wigig: Adding debug tools
Adding the debug tools package for 11ad
Change-Id: I171d7534614ec8941e0b48bb01d757ccd3be8960
Signed-off-by: Vadim Iosevich <vadimi@codeaurora.org>
diff --git a/Android.mk b/Android.mk
new file mode 100755
index 0000000..416702e
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,5 @@
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+include $(call all-makefiles-under, $(LOCAL_PATH))
+
diff --git a/debug-tools/Android.mk b/debug-tools/Android.mk
new file mode 100644
index 0000000..8e4e086
--- /dev/null
+++ b/debug-tools/Android.mk
@@ -0,0 +1,6 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+include $(call all-makefiles-under, $(LOCAL_PATH))
+
diff --git a/debug-tools/LogCollector/Android.mk b/debug-tools/LogCollector/Android.mk
new file mode 100644
index 0000000..001ac1c
--- /dev/null
+++ b/debug-tools/LogCollector/Android.mk
@@ -0,0 +1,35 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := wigig_logcollector
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_CPPFLAGS := -Wall -fexceptions
+
+LOCAL_C_INCLUDES += \
+ $(LOCAL_PATH)/../lib/WlctPciAcss \
+ $(LOCAL_PATH)/../lib/inc \
+ $(LOCAL_PATH)/../lib/utils \
+
+LOCAL_SHARED_LIBRARIES := \
+ libwigig_utils \
+ libwigig_pciaccess \
+
+LOCAL_SRC_FILES := \
+ LogCollector.cpp
+
+include $(BUILD_EXECUTABLE)
+
+# LogCollector configuration file
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := wigig_logcollector.ini
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)
+LOCAL_SRC_FILES := linux/wigig_logcollector.ini
+include $(BUILD_PREBUILT)
+
+
diff --git a/debug-tools/LogCollector/LogCollector.cpp b/debug-tools/LogCollector/LogCollector.cpp
new file mode 100644
index 0000000..b59737f
--- /dev/null
+++ b/debug-tools/LogCollector/LogCollector.cpp
@@ -0,0 +1,826 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <stdarg.h>
+#include <ctime>
+
+#ifndef _WINDOWS // Linux
+#include <unistd.h>
+#include <getopt.h>
+#include <err.h>
+#else // Windows
+#include <windows.h>
+#endif //#ifdef _WINDOWS
+
+
+
+#include "WlctPciAcss.h"
+
+using namespace std;
+
+////////// TYPE DEFINITIONS //////////
+enum TRACER_TYPE
+{
+ TRACER_TYPE_FW,
+ TRACER_TYPE_UCODE
+};
+
+enum MODULES
+{
+ SYSTEM,
+ DRIVERS,
+ MAC_MON,
+ HOST_CMD,
+ PHY_MON,
+ INFRA,
+ CALIBS,
+ TXRX,
+ RAD_MGR,
+ SCAN,
+ MLME,
+ L2_MGR,
+ DISC,
+ MGMT_SRV,
+ SECURITY,
+ PSM,
+ WBE_MNGR,
+ NUM_MODULES,
+};
+
+string module_names[NUM_MODULES] = {"SYSTEM", "DRIVERS", "MAC_MON", "HOST_CMD", "PHY_MON", "INFRA", "CALIBS", "TXRX", "RAD_MGR", "SCAN", "MLME", "L2_MGR", "DISC", "MGMT_SRV", "SECURITY", "PSM", "WBE_MNGR"};
+
+typedef uint32_t u32;
+typedef int32_t s32;
+typedef unsigned int uint;
+
+#ifdef _WINDOWS
+struct module_level_enable { /* Little Endian */
+ uint error_level_enable : 1;
+ uint warn_level_enable : 1;
+ uint info_level_enable : 1;
+ uint verbose_level_enable : 1;
+ uint reserved0 : 4;
+};
+struct log_trace_header { /* Little Endian */
+ uint strring_offset : 20;
+ uint module : 4; /* module that outputs the trace */
+ uint level : 2;
+ uint parameters_num : 2; /* [0..3] */
+ uint is_string : 1; /* indicate if the printf uses %s */
+ uint signature : 3; /* should be 5 (2'101) in valid header */
+};
+#else
+struct module_level_enable { /* Little Endian */
+ uint error_level_enable : 1;
+ uint warn_level_enable : 1;
+ uint info_level_enable : 1;
+ uint verbose_level_enable : 1;
+ uint reserved0 : 4;
+} __attribute__((packed));
+
+struct log_trace_header { /* Little Endian */
+ /* the offset of the trace string in the strings sections */
+ uint strring_offset : 20;
+ uint module : 4; /* module that outputs the trace */
+ /* 0 - Error
+ 1- WARN
+ 2 - INFO
+ 3 - VERBOSE */
+ uint level : 2;
+ uint parameters_num : 2; /* [0..3] */
+ uint is_string : 1; /* indicate if the printf uses %s */
+ uint signature : 3; /* should be 5 (2'101) in valid header */
+} __attribute__((packed));
+#endif
+
+union log_event {
+ struct log_trace_header hdr;
+ u32 param;
+};
+
+struct log_table_header {
+ u32 write_ptr; /* incremented by trace producer every write */
+ struct module_level_enable module_level_enable[NUM_MODULES];
+ union log_event evt[0];
+};
+
+enum {
+ str_mask = 0xFFFFF,
+};
+
+////////// END - TYPE DEFINITIONS ///////
+
+/////////// CONSTANTS ///////////////////
+
+const int SECOND_IN_MILLISECONDS = 1000;
+
+// 50 MB file size
+const int MAX_FILE_FRAGMENT_SIZE = 1024 * 1024 * 50;
+
+// RGFs containing log buffer addresses
+// FW log address
+const int REG_FW_USAGE_1 = 0x880004;
+// uCode log address
+const int REG_FW_USAGE_2 = 0x880008;
+
+// Firmware version RGFs
+const int FW_VERSION_MAJOR = 0x880a2c;
+const int FW_VERSION_MINOR = 0x880a30;
+const int FW_VERSION_SUB = 0x880a34;
+const int FW_VERSION_BUILD = 0x880a38;
+
+// Firmware Compilation Time RGFs
+const int FW_COMP_TIME_HOUR = 0x880a14;
+const int FW_COMP_TIME_MINUTE = 0x880a18;
+const int FW_COMP_TIME_SECOND = 0x880a1c;
+const int FW_COMP_TIME_DAY = 0x880a20;
+const int FW_COMP_TIME_MONTH = 0x880a24;
+const int FW_COMP_TIME_YEAR = 0x880a28;
+
+// Log buffer offsets
+// FW log address offset
+const int FW_LOG_ADDRESS_OFFSET = 0xc8000;
+// uCode log address offset
+//const int UCODE_LOG_ADDRESS_OFFSET = 0;
+
+// Entries in the fw log buf
+const size_t fw_log_buf_entries = 0x1000/4;
+
+// Config file filename
+#ifdef _WINDOWS
+const char* const DEFAULT_CONFIG_FILE_NAME = "wigig_logcollector.ini";
+#else
+const char* const DEFAULT_CONFIG_FILE_NAME = "/etc/wigig_logcollector.ini";
+#endif
+
+//////////// END - CONSTANTS ////////////
+
+//////////// Global Variables ///////////
+
+// Log addresses
+int fw_log_address = 0;
+int ucode_log_address = 0;
+
+/////// Config file parameters /////////
+int pollingInterval = 100;
+string resultPath = "";
+string deviceName = "";
+string deviceType = "";
+int fileFragmentSize = MAX_FILE_FRAGMENT_SIZE;
+bool debugPrint = false;
+DType_t devType = MST_NONE;
+
+log_table_header logHeader;
+
+//// END - Config file parameters /////
+
+void* handler = NULL;
+
+DWORD fwVersionMajor;
+DWORD fwVersionMinor;
+DWORD fwVersionSub;
+DWORD fwVersionBuild;
+
+DWORD fwCompTimeHour;
+DWORD fwCompTimeMinute;
+DWORD fwCompTimeSecond;
+DWORD fwCompTimeDay;
+DWORD fwCompTimeMonth;
+DWORD fwCompTimeYear;
+
+std::string configFilePath;
+const char *mod;
+int i;
+unsigned long x;
+char *endptr;
+int help; /* = 0; */
+
+void *log_bu; /* memory allocated for the log buf */
+
+ void *str_buf;
+ size_t str_sz;
+ u32 rptr; /* = 0; */
+ u32 last_wptr; /* = 0; */
+ const char *const levels[] = {
+ "E",
+ "W",
+ "I",
+ "V",
+};
+
+const char *modules[16];
+
+//////////// END - Global Variables //////
+
+static inline size_t log_size(size_t entry_num)
+{
+ return sizeof(struct log_table_header) + entry_num * 4;
+}
+
+// OS Agnostic system time
+struct tm OSGetSystemTime()
+{
+ time_t current_time;
+ time(¤t_time);
+
+ struct tm *pTimeStruct = localtime(¤t_time);
+ struct tm timeStruct = {};
+ if (pTimeStruct)
+ {
+ timeStruct = *pTimeStruct;
+ }
+
+ return timeStruct;
+}
+
+// OS agnostic debug print function
+void DebugPrint(const char* error_message, ...)
+{
+ if (debugPrint == false) return;
+
+ va_list argptr;
+ va_start(argptr, error_message);
+
+ vfprintf(stderr, error_message, argptr);
+
+ va_end(argptr);
+}
+
+void DisplayHelp()
+{
+ static char *help_str = (char*)("Usage: LogCollector [OPTION]...\n"
+ "Extract trace log from firmware\n"
+ "\n"
+ "Mandatory arguments to long options are mandatory for short options too.\n"
+ " The following switches are mandatory:\n"
+ " -m, --memdump=FILE File to read memory dump from\n"
+ " -l, --logsize=NUMBER Log buffer size, entries\n");
+ printf("%s", help_str);
+ exit(1);
+}
+
+// OS agnostic sleep function
+void OSSleep(int sleep_period)
+{
+#ifdef _WINDOWS
+ Sleep(sleep_period);
+#else
+ usleep(sleep_period * SECOND_IN_MILLISECONDS);
+#endif
+}
+
+// OS agnostic error print function
+void OSError(const char* error_message, ...)
+{
+ va_list argptr;
+ va_start(argptr, error_message);
+
+#ifdef _WINDOWS
+ vfprintf(stderr, error_message, argptr);
+
+ exit(0);
+#else
+ vfprintf(stderr, error_message, argptr);
+
+ exit(0);
+#endif
+
+ va_end(argptr);
+}
+
+void ParseModuelLevel(string moduleString)
+{
+ for (int i = 0; i < NUM_MODULES; i++)
+ {
+ if (moduleString.find(module_names[i]) == 0)
+ {
+ // + 1 for '='
+ string levels = moduleString.substr(module_names[i].size() + 1);
+
+ if (levels.find("V") != string::npos)
+ {
+ logHeader.module_level_enable[i].verbose_level_enable = 1;
+ }
+ if (levels.find("I") != string::npos)
+ {
+ logHeader.module_level_enable[i].info_level_enable = 1;
+ }
+ if (levels.find("E") != string::npos)
+ {
+ logHeader.module_level_enable[i].error_level_enable = 1;
+ }
+ if (levels.find("W") != string::npos)
+ {
+ logHeader.module_level_enable[i].warn_level_enable = 1;
+ }
+ }
+ }
+}
+
+// OS agnostic get arguments function
+void ParseConfigLine(string line)
+{
+ const char* device_name = "device_name=";
+ const char* device_type = "device_type=";
+ const char* polling_interval = "polling_interval=";
+ const char* result_path = "result_path=";
+ const char* module_level_prefix = "MODULE_LEVEL_";
+ const char* debug_print = "debug_print=";
+ const char* log_fragment_size = "log_fragment_size=";
+
+ DebugPrint("configuration line = %s\n", line.c_str());
+
+ // Skip comments
+ if (line.find("//") == 0)
+ {
+ return;
+ }
+
+ try
+ {
+ if (line.find(debug_print) == 0)
+ {
+ debugPrint = (line.substr(strlen(debug_print)).find("TRUE") == 0);
+ DebugPrint("Debug Prints Enabled\n");
+ }
+ else if (line.find(log_fragment_size) == 0)
+ {
+ fileFragmentSize = atoi(line.substr(strlen(log_fragment_size)).c_str()) * 1024 * 1024;
+ DebugPrint("File fragment size is %d MB\n", atoi(line.substr(strlen(log_fragment_size)).c_str()));
+ }
+ else if (line.find(device_name) == 0)
+ {
+ deviceName = line.substr(strlen(device_name));
+ DebugPrint("Device Name Requested: %s\n", deviceName.c_str());
+ }
+ else if (line.find(polling_interval) == 0)
+ {
+ pollingInterval = atoi(line.substr(strlen(polling_interval)).c_str());
+ DebugPrint("Polling Interval Is:%d\n", pollingInterval);
+ }
+ else if (line.find(result_path) == 0)
+ {
+ resultPath = line.substr(strlen(result_path));
+ DebugPrint("Result path = %s\n", resultPath.c_str());
+ }
+ else if (line.find(module_level_prefix) == 0)
+ {
+ ParseModuelLevel(line.substr(strlen(module_level_prefix)));
+ }
+ else if (line.find(device_type) == 0)
+ {
+ deviceType = line.substr(strlen(device_type));
+
+ DebugPrint("Device Type = %s\n", deviceType.c_str());
+
+ if (deviceType.find("MARLON") == 0)
+ {
+ DebugPrint("Device selected MARLON=%d\n", MST_MARLON);
+ devType = MST_MARLON;
+ }
+ else if (deviceType.find("SPARROW") == 0)
+ {
+ DebugPrint("Device selected SPARROW=%d\n", MST_SPARROW);
+ devType = MST_SPARROW;
+ }
+ else if (deviceType.find("TALYN") == 0)
+ {
+ DebugPrint("Device selected TALYN=%d\n", MST_LAST);
+ devType = MST_LAST;
+ }
+ else
+ {
+ DebugPrint("Device selected NONE=%d\n", MST_NONE);
+ devType = MST_NONE;
+ }
+
+ }
+ else
+ {
+ }
+ }
+ catch (int)
+ {
+ OSError("Error: Failed to parse Config File");
+ }
+}
+
+// Open device interface
+static void OpenDevice()
+{
+ INTERFACE_LIST interfaces;
+ int num_items;
+ int res;
+ res = GetInterfaces(&interfaces, &num_items);
+
+ if (res != 0 || num_items == 0)
+ {
+ OSError("Error: retrieving interfaces");
+ }
+
+ string currentDeviceName;
+
+ // No specific device was requested or only one device is available
+ // Select first device in device list
+ bool deviceFound = false;
+
+ if (deviceName.compare("") == 0 || num_items == 1)
+ {
+ cout << "Selecting device: " << interfaces.list[0].ifName << "\n";
+ currentDeviceName = interfaces.list[0].ifName;
+ }
+ else
+ {
+ // Iterate through all found devices to find the one in config file
+ for (int i = 0 ; i < MAX_INTERFACES; i ++)
+ {
+ currentDeviceName = interfaces.list[i].ifName;
+
+ if (deviceName.compare(currentDeviceName) == 0)
+ {
+ // We have found the device we are looking for
+ cout << "Found device: " << currentDeviceName.c_str() << "\n";
+ deviceFound = true;
+ break;
+ }
+ }
+
+ if (!deviceFound)
+ {
+ OSError("A device named: %s, was not found", deviceName.c_str());
+ }
+ }
+
+ DebugPrint ("Opening Device: %s\n", currentDeviceName.c_str());
+
+ // Create a handler to the device
+ DWORD err = CreateDeviceAccessHandler(currentDeviceName.c_str(), devType, &handler);
+ if (!(err == 0 && isInit(handler)))
+ {
+ OSError("Failed to open device: %s, Error code: %d\n", currentDeviceName.c_str(), err);
+ }
+}
+
+// Get log address
+static int GetLogAddress(TRACER_TYPE type)
+{
+ DWORD val;
+ DWORD addr = REG_FW_USAGE_1;
+
+ if (type == TRACER_TYPE_UCODE)
+ {
+ addr = REG_FW_USAGE_2;
+ }
+ else if (type == TRACER_TYPE_FW)
+ {
+ addr = REG_FW_USAGE_1;
+ }
+ else
+ {
+ OSError("Invalid log tracer type - using FW as default");
+ }
+
+
+ // Read log offset
+ WlctAccssRead(handler, addr, val);
+
+ if (val == 0)
+ {
+ OSError("Invalid log buffer pointer address");
+ }
+
+ return val;
+}
+
+// OS agnostic read log function
+static bool OSReadLog(void *buf, size_t size)
+{
+ // Check if the device is open
+ if ((NULL == handler) || (!isInit(handler)))
+ {
+ OSError("Device not opened when trying the read log");
+ }
+
+ // Update FW & uCode log addresses
+ if (!fw_log_address) fw_log_address = GetLogAddress(TRACER_TYPE_FW) + FW_LOG_ADDRESS_OFFSET;
+ //if (!ucode_log_address) ucode_log_address = GetLogAddress(TRACER_TYPE_UCODE);
+
+ // Read the actual log
+ if(0 != readBlock(handler, fw_log_address, size, (char*)buf))
+ {
+ return false;
+ // OSError("Failed to read log buffer");
+ }
+ return true;
+}
+
+// OS agnostic read configuration file function
+static void OSReadConfigFile()
+{
+ try
+ {
+ ifstream file(configFilePath.c_str());
+
+ if(!file || !file.good())
+ {
+ OSError("Error: failed to read config file: %s. %s \n", configFilePath.c_str(), strerror(errno));
+ }
+
+ string line;
+ while(std::getline(file, line))
+ {
+ ParseConfigLine(line);
+ }
+ }
+ catch (int i)
+ {
+ OSError("Exception while trying to open config file: %s\n", configFilePath.c_str());
+ }
+}
+
+ void AddTimestamp(ofstream& outputFile)
+{
+ struct tm now = OSGetSystemTime();
+
+ std::ostringstream timeStampBuilder;
+
+ timeStampBuilder << "<Log_Content>"
+ << "<Sample_Time>"
+ << "<Hour>" << now.tm_hour << "</Hour>"
+ << "<Minute>" << now.tm_min << "</Minute>"
+ << "<Second>" << now.tm_sec << "</Second>"
+ << "<Day>" << now.tm_mday << "</Day>"
+ << "<Month>" << now.tm_mon + 1 << "</Month>"
+ << "<Year>" << now.tm_year + 1900 << "</Year>"
+ << "</Sample_Time>";
+
+ outputFile << timeStampBuilder.str();
+}
+
+static int ParseLog(void* log_buf, size_t log_buf_entries, ofstream& outputFile)
+{
+// DebugPrint("Parsing log\n");
+
+ int sizeAdded = 0;
+
+ // Prepare a header pointing to log buffer top
+ struct log_table_header *h = (struct log_table_header*)log_buf;
+
+ u32 wptr = h->write_ptr;
+
+ if ((wptr - rptr) <= 0)
+ {
+ // Nothing to read.
+ return 0;
+ }
+
+ if ((wptr - rptr) >= log_buf_entries)
+ {
+ // overflow; try to parse last wrap
+ rptr = wptr - log_buf_entries;
+ }
+ DebugPrint(" wptr = %d rptr = %d\n", wptr, rptr);
+
+ AddTimestamp(outputFile);
+ outputFile << "<Content>";
+
+ for (; ((s32)(wptr - rptr) > 0) && (wptr != last_wptr); rptr++)
+ {
+ DebugPrint("wptr = %d, rptr = %d\n", wptr, rptr);
+
+ int i;
+ u32 p[3] = {0};
+ union log_event *evt = &h->evt[rptr % log_buf_entries];
+
+ if (evt->hdr.signature != 5)
+ {
+ continue;
+ }
+ if (evt->hdr.strring_offset > str_sz)
+ {
+// continue;
+ }
+ if (evt->hdr.parameters_num > 3)
+ {
+ DebugPrint("Parameter Num = %d", evt->hdr.parameters_num);
+ continue;
+ }
+ for (i = 0; i < evt->hdr.parameters_num; i++)
+ p[i] = h->evt[(rptr + i + 1) % log_buf_entries].param;
+ /*DebugPrint("%d,%s,%d:", evt->hdr.module,
+ levels[evt->hdr.level],
+ evt->hdr.strring_offset);
+
+ DebugPrint("%d,%d,%d\n",
+ (p[0]),
+ (p[1]),
+ (p[2]));*/
+
+ outputFile << evt->hdr.module << "," << levels[evt->hdr.level] << "," << evt->hdr.strring_offset << ":" << p[0] << "," << p[1] << "," << p[2] << "\n";
+
+ // (paramters) (verbosity type) (delimiters)
+ sizeAdded += (5 * sizeof(int)) + (1 * sizeof(char)) + (4 * sizeof(char));
+
+ rptr += evt->hdr.parameters_num;
+ }
+
+ last_wptr = wptr;
+
+ outputFile << "</Content></Log_Content>";
+
+ fflush(stdout);
+ return sizeAdded;
+}
+
+void SetModuleVerbosity()
+{
+ // Check if the device is open
+ if ((NULL == handler) || (!isInit(handler)))
+ {
+ OSError("Device not opened when trying to set module verbosity");
+ }
+
+ // Update FW & uCode log addresses
+ if (!fw_log_address) fw_log_address = GetLogAddress(TRACER_TYPE_FW) + FW_LOG_ADDRESS_OFFSET;
+ //if (!ucode_log_address) ucode_log_address = GetLogAddress(TRACER_TYPE_UCODE);
+
+ DebugPrint("fw log address = %d\n", fw_log_address);
+
+ // Write verbosity to the device
+ if(-1 == writeBlock(handler, fw_log_address + sizeof(logHeader.write_ptr), sizeof(logHeader.module_level_enable), (char*)logHeader.module_level_enable))
+ {
+ OSError("Failed to write module verbosity structure");
+ }
+}
+
+void ReadDeviceInfo()
+{
+ // Check if the device is open
+ if ((NULL == handler) || (!isInit(handler)))
+ {
+ OSError("Device not opened when trying to read device info");
+ }
+
+ // Read FW Version
+ WlctAccssRead(handler, FW_VERSION_MAJOR, fwVersionMajor);
+ WlctAccssRead(handler, FW_VERSION_MINOR, fwVersionMinor);
+ WlctAccssRead(handler, FW_VERSION_SUB, fwVersionSub);
+ WlctAccssRead(handler, FW_VERSION_BUILD, fwVersionBuild);
+
+ // Read compilation Time
+ WlctAccssRead(handler, FW_COMP_TIME_HOUR, fwCompTimeHour);
+ WlctAccssRead(handler, FW_COMP_TIME_MINUTE, fwCompTimeMinute);
+ WlctAccssRead(handler, FW_COMP_TIME_SECOND, fwCompTimeSecond);
+ WlctAccssRead(handler, FW_COMP_TIME_DAY, fwCompTimeDay);
+ WlctAccssRead(handler, FW_COMP_TIME_MONTH, fwCompTimeMonth);
+ WlctAccssRead(handler, FW_COMP_TIME_YEAR, fwCompTimeYear);
+}
+
+void* AllocateBuffer()
+{
+ void* log_buf = malloc(log_size(fw_log_buf_entries));
+ if (!log_buf)
+ {
+ OSError("Error: Unable to allocate log buffer %zd bytes", log_size(fw_log_buf_entries));
+ }
+
+ return log_buf;
+}
+
+bool CreateNewOutputFile(string path, ofstream& outputFile)
+{
+ std::ostringstream fileNameBuilder;
+ fileNameBuilder << path << "logFile_" << time(0);
+
+ DebugPrint("Path: %s\n", path.c_str());
+ DebugPrint("Creating output file: %s\n", fileNameBuilder.str().c_str());
+
+ outputFile.open(fileNameBuilder.str().c_str());
+
+ if (outputFile.fail())
+ {
+ printf("Error opening output file: %s\n", fileNameBuilder.str().c_str());
+ return false;
+ }
+
+ std::ostringstream headerBuilder;
+
+ headerBuilder << "<LogFile>"
+ << "<FW_Ver>"
+ << "<Major>" << fwVersionMajor << "</Major>"
+ << "<Minor>" << fwVersionMinor <<"</Minor>"
+ << "<Sub>" << fwVersionSub << "</Sub>"
+ << "<Build>" << fwVersionBuild << "</Build>"
+ << "</FW_Ver>"
+ << "<Compilation_Time>"
+ << "<Hour>" << fwCompTimeHour << "</Hour>"
+ << "<Minute>" << fwCompTimeMinute << "</Minute>"
+ << "<Second>" << fwCompTimeSecond << "</Second>"
+ << "<Day>" << fwCompTimeDay << "</Day>"
+ << "<Month>" << fwCompTimeMonth << "</Month>"
+ << "<Year>" << fwCompTimeYear << "</Year>"
+ << "</Compilation_Time>"
+ << "<Logs>";
+
+ outputFile << headerBuilder.str();
+ return true;
+}
+
+void CloseOutputFile(ofstream& outputFile)
+{
+ outputFile << "</Logs></LogFile>";
+ outputFile.close();
+ DebugPrint("Output file closed\n");
+}
+
+int main(int argc, char *argv[])
+{
+ configFilePath = DEFAULT_CONFIG_FILE_NAME;
+ if (argc == 2)
+ {
+ configFilePath = argv[1];
+ }
+
+ // Read configuration file
+ OSReadConfigFile();
+
+ if (false) // TODO decide when to show help
+ {
+ help = 1;
+ }
+
+ if (help)
+ {
+ DisplayHelp();
+ }
+
+ OpenDevice();
+
+ ReadDeviceInfo();
+
+ SetModuleVerbosity();
+
+ // Allocate log buffer
+ void* log_buf = AllocateBuffer();
+
+ long currentFileSize = 0;
+
+ ofstream outputFile;
+
+ bool status = CreateNewOutputFile(resultPath, outputFile);
+ if (!status) return 1;
+
+ while (true)
+ {
+ if (currentFileSize > fileFragmentSize)
+ {
+ currentFileSize = 0;
+ CloseOutputFile(outputFile);
+ status = CreateNewOutputFile(resultPath, outputFile);
+ if (!status) return 1;
+ }
+
+ // Read the log
+ if (!OSReadLog(log_buf, log_size(fw_log_buf_entries)))
+ {
+ OSSleep(pollingInterval);
+ continue;
+ }
+
+ currentFileSize += ParseLog(log_buf, fw_log_buf_entries, outputFile);
+ DebugPrint("Current File Size = %d\n", currentFileSize);
+
+ OSSleep(pollingInterval);
+ }
+
+ return 0;
+}
diff --git a/debug-tools/LogCollector/Makefile b/debug-tools/LogCollector/Makefile
new file mode 100644
index 0000000..88d91ed
--- /dev/null
+++ b/debug-tools/LogCollector/Makefile
@@ -0,0 +1,45 @@
+-include $(TOPDIR)/rules.mk
+
+CFLAGS := -fPIE -Wall -g -MMD
+LDFLAGS := -pie -fPIE -pthread -lwigig_pciaccess -lwigig_utils
+
+ifneq ($(CONFIG_TARGET_ipq)$(CONFIG_TARGET_ipq806x),)
+is_ipq806x = 1
+endif
+
+ifeq ($(is_ipq806x), 1)
+ifneq ($(strip $(TOOLPREFIX)),)
+CROSS:=$(TOOLPREFIX)
+endif
+endif
+
+CC = $(CROSS)gcc
+CXX = $(CROSS)g++
+
+.DEFAULT_GOAL = all
+PROG = wigig_logcollector
+
+INCLUDES = -I ../lib/WlctPciAcss \
+ -I ../lib/inc \
+ -I ../lib/utils \
+
+LIBS = -L../lib/WlctPciAcss \
+ -L../lib/utils \
+
+CPP_FILES = $(shell find . -type f -name '*.cpp')
+OBJ_FILES = $(CPP_FILES:.cpp=.o)
+
+all: $(PROG)
+
+$(PROG): $(OBJ_FILES)
+ $(CXX) -o $@ $^ $(LIBS) $(LDFLAGS)
+
+%.o : %.cpp
+ $(CXX) $(CFLAGS) $(INCLUDES) -o $@ -c $<
+
+
+clean:
+ rm -rf $(PROG)
+ find . -type f \( -name "*.d" -o -name "*.o" \) -delete
+
+-include $(OBJ_FILES:%.o=%.d)
diff --git a/debug-tools/LogCollector/linux/wigig_logcollector.ini b/debug-tools/LogCollector/linux/wigig_logcollector.ini
new file mode 100644
index 0000000..0ad18b4
--- /dev/null
+++ b/debug-tools/LogCollector/linux/wigig_logcollector.ini
@@ -0,0 +1,28 @@
+debug_print=FALSE
+device_name=
+device_type=SPARROW
+polling_interval=100
+log_fragment_size=10
+result_path=/tmp/
+
+// Log Module Levels
+// V - Verbose, I - Info, E - Error, W - Warning
+// For example: MODULE_LEVEL_SYSTEM=VIE
+// Or: MODULE_LEVEL_DRIVERS=WIV
+MODULE_LEVEL_SYSTEM=VIEW
+MODULE_LEVEL_DRIVERS=VIEW
+MODULE_LEVEL_MAC_MON=VIEW
+MODULE_LEVEL_HOST_CMD=VIEW
+MODULE_LEVEL_PHY_MON=VIEW
+MODULE_LEVEL_INFRA=VIEW
+MODULE_LEVEL_CALIBS=VIEW
+MODULE_LEVEL_TXRX=VIEW
+MODULE_LEVEL_RAD_MGR=VIEW
+MODULE_LEVEL_SCAN=VIEW
+MODULE_LEVEL_MLME=VIEW
+MODULE_LEVEL_L2_MGR=VIEW
+MODULE_LEVEL_DISC=VIEW
+MODULE_LEVEL_MGMT_SRV=VIEW
+MODULE_LEVEL_SECURITY=VIEW
+MODULE_LEVEL_PSM=VIEW
+MODULE_LEVEL_WBE_MNGR=VIEW
diff --git a/debug-tools/Makefile b/debug-tools/Makefile
new file mode 100644
index 0000000..e82e937
--- /dev/null
+++ b/debug-tools/Makefile
@@ -0,0 +1,37 @@
+.DEFAULT_GOAL = all
+
+.PHONY = all install uninstall clean
+
+all: make_host_manager_11ad make_remoteserver make_logcollector make_wiburn make_wlctutils make_wlctpciacss make_flashacss
+
+make_host_manager_11ad:
+ $(MAKE) -C host_manager_11ad CROSS=$(CROSS)
+
+make_remoteserver: make_wlctutils make_wlctpciacss
+ $(MAKE) -C remoteserver CROSS=$(CROSS)
+
+make_logcollector: make_wlctutils make_wlctpciacss
+ $(MAKE) -C LogCollector CROSS=$(CROSS)
+
+make_wiburn: make_wlctutils make_wlctpciacss make_flashacss
+ $(MAKE) -C wiburn CROSS=$(CROSS)
+
+make_wlctutils:
+ $(MAKE) -C lib/utils CROSS=$(CROSS)
+
+make_wlctpciacss:
+ $(MAKE) -C lib/WlctPciAcss CROSS=$(CROSS)
+
+make_flashacss:
+ $(MAKE) -C lib/FlashAcss CROSS=$(CROSS)
+
+clean:
+ echo "Cleaning up wigig debug tools"
+ $(MAKE) -C host_manager_11ad clean
+ $(MAKE) -C remoteserver clean
+ $(MAKE) -C LogCollector clean
+ $(MAKE) -C wiburn clean
+ $(MAKE) -C lib/utils clean
+ $(MAKE) -C lib/WlctPciAcss clean
+ $(MAKE) -C lib/FlashAcss clean
+
diff --git a/debug-tools/host_manager_11ad/Android.mk b/debug-tools/host_manager_11ad/Android.mk
new file mode 100644
index 0000000..8a96497
--- /dev/null
+++ b/debug-tools/host_manager_11ad/Android.mk
@@ -0,0 +1,17 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := host_manager_11ad
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_CPPFLAGS := -Wall -lpthread -fexceptions
+
+LOCAL_C_INCLUDES += \
+ $(LOCAL_PATH)/access_layer_11ad \
+ $(LOCAL_PATH)/access_layer_11ad/Unix \
+
+LOCAL_SRC_FILES := $(shell find $(LOCAL_PATH) -name '*.cpp' | sed s:^$(LOCAL_PATH)::g )
+
+include $(BUILD_EXECUTABLE)
diff --git a/debug-tools/host_manager_11ad/ArgumentsParser.cpp b/debug-tools/host_manager_11ad/ArgumentsParser.cpp
new file mode 100644
index 0000000..49e6fbf
--- /dev/null
+++ b/debug-tools/host_manager_11ad/ArgumentsParser.cpp
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include "ArgumentsParser.h"
+
+#include <cstdio>
+#include <vector>
+#include <string>
+#include <algorithm>
+
+#define HOST_MANAGER_VERSION 0x0100
+
+using namespace std;
+// *************************************************************************************************
+
+int ArgumentsParser::ParseAndHandleArguments(int argc, char * argv[], unsigned int &commandsTcpPort)
+{
+
+ //do something with params
+ (void)commandsTcpPort;
+
+ for (int i = 0; i < argc; i++)
+ {
+ m_arguments.push_back(string(argv[i]));
+ }
+ if (DoesArgumentExist("-v"))
+ { //Argument for the version of host_manager_11ad
+ printf("Host Manager 11ad v%d.%d\n", HOST_MANAGER_VERSION >> 8, HOST_MANAGER_VERSION & 0xff);
+ }
+ if (DoesArgumentExist("-p"))
+ { //Argument for setting the port of the commands TCP port
+
+ }
+
+ unsigned val;
+ if (GetArgumentValue("-d", val))
+ { //Argument for setting verbosity level
+ g_LogConfig.SetMaxSeverity(val);
+ }
+
+ return 0;
+}
+
+bool ArgumentsParser::DoesArgumentExist(string option)
+{
+ bool doesArgumentExist = find(m_arguments.begin(), m_arguments.end(), option) != m_arguments.end();
+ return doesArgumentExist;
+}
+
+bool ArgumentsParser::GetArgumentValue(string option, unsigned& val)
+{
+ auto argumentIter = find(m_arguments.begin(), m_arguments.end(), option);
+ if (argumentIter != m_arguments.end())
+ {
+ auto valueIter = ++argumentIter;
+ if (valueIter != m_arguments.end())
+ {
+ string valStr = *valueIter;
+ try
+ {
+ val = strtoul(valStr.c_str(), NULL, 10);
+ return true;
+ }
+ catch (...)
+ {
+ printf("Error in setting verbosity level\n");
+ }
+ }
+ }
+ return false;
+}
diff --git a/debug-tools/host_manager_11ad/ArgumentsParser.h b/debug-tools/host_manager_11ad/ArgumentsParser.h
new file mode 100644
index 0000000..a9caa0f
--- /dev/null
+++ b/debug-tools/host_manager_11ad/ArgumentsParser.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _ARGUMENTSPARSER_H_
+#define _ARGUMENTSPARSER_H_
+
+#include "DebugLogger.h"
+
+#include <string>
+#include <vector>
+
+using namespace std;
+
+// *************************************************************************************************
+/*
+ * Class for parsing the arguments given in the command line
+ */
+class ArgumentsParser
+{
+public:
+ int ParseAndHandleArguments(int argc, char* argv[], unsigned int &commandsTcpPort);
+
+private:
+ vector<string> m_arguments; //Vector that holds each one of the arguments that was given in the command line
+ bool DoesArgumentExist(string option);
+ bool GetArgumentValue(string option, unsigned& val); // returns true iff the argument exists in the srguments list and its value was extracted correctly
+};
+
+#endif // !_ARGUMENTSPARSER_H_
diff --git a/debug-tools/host_manager_11ad/CommandsHandler.cpp b/debug-tools/host_manager_11ad/CommandsHandler.cpp
new file mode 100644
index 0000000..e02617b
--- /dev/null
+++ b/debug-tools/host_manager_11ad/CommandsHandler.cpp
@@ -0,0 +1,742 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "CommandsHandler.h"
+#include "Host.h"
+#include <sstream>
+#include <string>
+#include "HostDefinitions.h"
+#include "pmc_file.h"
+#include "FileReader.h"
+
+string CommandsHandler::DecorateResponseMessage(bool successStatus, string message)
+{
+ string status = successStatus ? "Success" : "Fail";
+ string decoratedResponse = Utils::GetCurrentLocalTime() + m_reply_feilds_delimiter + status;
+ if (message != "")
+ {
+ decoratedResponse += m_reply_feilds_delimiter + message;
+ }
+ return decoratedResponse;
+}
+
+// **************************************TCP commands handlers*********************************************************** //
+ResponseMessage CommandsHandler::GetInterfaces(vector<string> arguments, unsigned int numberOfArguments)
+{
+ //do something with params
+ (void)arguments;
+
+ LOG_VERBOSE << __FUNCTION__ << endl;
+ ResponseMessage response;
+ if (ValidArgumentsNumber(__FUNCTION__, numberOfArguments, 0, response.message))
+ {
+ set<string> devices;
+ DeviceManagerOperationStatus status = m_host.GetDeviceManager().GetDevices(devices);
+
+ if (dmosSuccess != status)
+ {
+ LOG_ERROR << "Error while trying to get interfaces. Error: " + m_host.GetDeviceManager().GetDeviceManagerOperationStatusString(status);
+ response.message = (dmosNoSuchConnectedDevice == status)? DecorateResponseMessage(false, m_host.GetDeviceManager().GetDeviceManagerOperationStatusString(status)) :
+ DecorateResponseMessage(false, GetCommandsHandlerResponseStatusString(chrsOperationFailure));
+ }
+ else
+ {
+ // create one string that contains all connected devices
+ stringstream devicesSs;
+ bool firstTime = true;
+ for (auto device : devices)
+ {
+ if (firstTime)
+ {
+ devicesSs << device;
+ firstTime = false;
+ continue;
+ }
+ devicesSs << m_device_delimiter << device;
+ }
+ response.message = DecorateResponseMessage(true, devicesSs.str());
+ }
+ }
+ response.type = REPLY_TYPE_BUFFER;
+ response.length = response.message.size();
+ return response;
+}
+// *************************************************************************************************
+
+ResponseMessage CommandsHandler::OpenInterface(vector<string> arguments, unsigned int numberOfArguments)
+{
+ LOG_VERBOSE << __FUNCTION__ << endl;
+ ResponseMessage response;
+ if (ValidArgumentsNumber(__FUNCTION__, numberOfArguments, 1, response.message))
+ {
+ DeviceManagerOperationStatus status = m_host.GetDeviceManager().OpenInterface(arguments[0]);
+
+ if (dmosSuccess != status)
+ {
+ LOG_ERROR << "Error while trying to open interface " + arguments[0] + ". Error: " + m_host.GetDeviceManager().GetDeviceManagerOperationStatusString(status);
+ response.message = (dmosNoSuchConnectedDevice == status) ? DecorateResponseMessage(false, m_host.GetDeviceManager().GetDeviceManagerOperationStatusString(status)) :
+ DecorateResponseMessage(false, GetCommandsHandlerResponseStatusString(chrsOperationFailure));
+ }
+ else
+ {
+ response.message = DecorateResponseMessage(true, arguments[0]); // backward compatibility
+ }
+ }
+ response.type = REPLY_TYPE_BUFFER;
+ response.length = response.message.size();
+ return response;
+}
+// *************************************************************************************************
+
+ResponseMessage CommandsHandler::CloseInterface(vector<string> arguments, unsigned int numberOfArguments)
+{
+ LOG_VERBOSE << __FUNCTION__ << endl;
+ ResponseMessage response;
+ if (ValidArgumentsNumber(__FUNCTION__, numberOfArguments, 1, response.message))
+ {
+ DeviceManagerOperationStatus status = m_host.GetDeviceManager().CloseInterface(arguments[0]);
+
+ if (dmosSuccess != status)
+ {
+ LOG_ERROR << "Error while trying to close interface " + arguments[0] + ". Error: " + m_host.GetDeviceManager().GetDeviceManagerOperationStatusString(status);
+ response.message = (dmosNoSuchConnectedDevice == status) ? DecorateResponseMessage(false, m_host.GetDeviceManager().GetDeviceManagerOperationStatusString(status)) :
+ DecorateResponseMessage(false, GetCommandsHandlerResponseStatusString(chrsOperationFailure));
+ }
+ else
+ {
+ response.message = DecorateResponseMessage(true); // backward compatibility
+ }
+ }
+ response.type = REPLY_TYPE_BUFFER;
+ response.length = response.message.size();
+ return response;
+}
+// *************************************************************************************************
+
+ResponseMessage CommandsHandler::Read(vector<string> arguments, unsigned int numberOfArguments)
+{
+ LOG_VERBOSE << __FUNCTION__ << endl;
+ ResponseMessage response;
+ if (ValidArgumentsNumber(__FUNCTION__, numberOfArguments, 2, response.message))
+ {
+ DWORD address;
+ if (!Utils::ConvertHexStringToDword(arguments[1], address))
+ {
+ LOG_WARNING << "Error in Read arguments: given address isn't starting with 0x" << endl;
+ response.message = DecorateResponseMessage(false, GetCommandsHandlerResponseStatusString(chrsInvalidArgument));
+ }
+ else
+ {
+ DWORD value;
+ DeviceManagerOperationStatus status = m_host.GetDeviceManager().Read(arguments[0], address, value);
+ if (dmosSuccess != status)
+ {
+ LOG_ERROR << "Error while trying to read address " + arguments[1] + " from " + arguments[0] + ". Error: " + m_host.GetDeviceManager().GetDeviceManagerOperationStatusString(status);
+ response.message = (dmosNoSuchConnectedDevice == status) ? DecorateResponseMessage(false, m_host.GetDeviceManager().GetDeviceManagerOperationStatusString(status)) :
+ DecorateResponseMessage(false, GetCommandsHandlerResponseStatusString(chrsOperationFailure));
+ }
+ else
+ {
+ stringstream message;
+ message << "0x" << hex << value;
+ response.message = DecorateResponseMessage(true, message.str());
+ }
+ }
+ }
+ response.type = REPLY_TYPE_BUFFER;
+ response.length = response.message.size();
+ return response;
+}
+// *************************************************************************************************
+
+ResponseMessage CommandsHandler::Write(vector<string> arguments, unsigned int numberOfArguments)
+{
+ LOG_VERBOSE << __FUNCTION__ << endl;
+ ResponseMessage response;
+ if (ValidArgumentsNumber(__FUNCTION__, numberOfArguments, 3, response.message))
+ {
+ DWORD address, value;
+ if (!Utils::ConvertHexStringToDword(arguments[1], address) || !Utils::ConvertHexStringToDword(arguments[2], value))
+ {
+ response.message = DecorateResponseMessage(false, GetCommandsHandlerResponseStatusString(chrsInvalidArgument));
+ }
+ else
+ {
+ DeviceManagerOperationStatus status = m_host.GetDeviceManager().Write(arguments[0], address, value);
+ if (dmosSuccess != status)
+ {
+ LOG_ERROR << "Error while trying to write value " + arguments[2] +" to " + arguments[1] + " on " + arguments[0] + ". Error: " + m_host.GetDeviceManager().GetDeviceManagerOperationStatusString(status);
+ response.message = (dmosNoSuchConnectedDevice == status) ? DecorateResponseMessage(false, m_host.GetDeviceManager().GetDeviceManagerOperationStatusString(status)) :
+ DecorateResponseMessage(false, GetCommandsHandlerResponseStatusString(chrsOperationFailure));
+ }
+ else
+ {
+ response.message = DecorateResponseMessage(true);
+ }
+ }
+ }
+ response.type = REPLY_TYPE_BUFFER;
+ response.length = response.message.size();
+ return response;
+}
+// *************************************************************************************************
+
+ResponseMessage CommandsHandler::ReadBlock(vector<string> arguments, unsigned int numberOfArguments)
+{
+ LOG_VERBOSE << __FUNCTION__ << endl;
+ ResponseMessage response;
+ if (ValidArgumentsNumber(__FUNCTION__, numberOfArguments, 3, response.message))
+ {
+ DWORD address, blockSize;
+ if (!Utils::ConvertHexStringToDword(arguments[1], address) || !Utils::ConvertHexStringToDword(arguments[2], blockSize))
+ {
+ response.message = DecorateResponseMessage(false, GetCommandsHandlerResponseStatusString(chrsInvalidArgument));
+ }
+ else
+ {
+ vector<DWORD> values;
+ DeviceManagerOperationStatus status = m_host.GetDeviceManager().ReadBlock(arguments[0], address, blockSize, values);
+ if (dmosSuccess != status)
+ {
+ LOG_ERROR << "Error while trying to read " + arguments[2] + " addresses starting at address " + arguments[1] + " from " + arguments[0] + ". Error: " + m_host.GetDeviceManager().GetDeviceManagerOperationStatusString(status);
+ response.message = (dmosNoSuchConnectedDevice == status) ? DecorateResponseMessage(false, m_host.GetDeviceManager().GetDeviceManagerOperationStatusString(status)) :
+ DecorateResponseMessage(false, GetCommandsHandlerResponseStatusString(chrsOperationFailure));
+ }
+ else
+ {
+ stringstream responseSs;
+ auto it = values.begin();
+ if (it != values.end())
+ {
+ responseSs << "0x" << hex << *it;
+ ++it;
+ }
+ for (; it != values.end(); ++it)
+ {
+ responseSs << m_array_delimiter << "0x" << hex << *it;
+ }
+ response.message = DecorateResponseMessage(true, responseSs.str());
+ }
+ }
+ }
+ response.type = REPLY_TYPE_BUFFER;
+ response.length = response.message.size();
+ return response;
+}
+// *************************************************************************************************
+
+ResponseMessage CommandsHandler::WriteBlock(vector<string> arguments, unsigned int numberOfArguments)
+{
+ LOG_VERBOSE << __FUNCTION__ << endl;
+ ResponseMessage response;
+
+ if (ValidArgumentsNumber(__FUNCTION__, numberOfArguments, 3, response.message))
+ {
+ DWORD address;
+ vector<DWORD> values;
+ if (!Utils::ConvertHexStringToDword(arguments[1], address) || !Utils::ConvertHexStringToDwordVector(arguments[2], m_array_delimiter, values))
+ {
+ response.message = DecorateResponseMessage(false, GetCommandsHandlerResponseStatusString(chrsInvalidArgument));
+ }
+ else
+ {
+ // perform write block
+ DeviceManagerOperationStatus status = m_host.GetDeviceManager().WriteBlock(arguments[0], address, values);
+ if (dmosSuccess != status)
+ {
+ LOG_ERROR << "Error in write blocks. arguments are:\nDevice name - " + arguments[0] + "\nStart address - " + arguments[1] +
+ "\nValues - " + arguments[2];
+ response.message = (dmosNoSuchConnectedDevice == status) ? DecorateResponseMessage(false, m_host.GetDeviceManager().GetDeviceManagerOperationStatusString(status)) :
+ DecorateResponseMessage(false, GetCommandsHandlerResponseStatusString(chrsOperationFailure));
+ }
+ else
+ {
+ response.message = DecorateResponseMessage(true);
+ }
+ }
+ }
+ response.type = REPLY_TYPE_BUFFER;
+ response.length = response.message.size();
+ return response;
+}
+// *************************************************************************************************
+
+ResponseMessage CommandsHandler::InterfaceReset(vector<string> arguments, unsigned int numberOfArguments)
+{
+ LOG_VERBOSE << __FUNCTION__ << endl;
+ ResponseMessage response;
+ if (ValidArgumentsNumber(__FUNCTION__, numberOfArguments, 1, response.message))
+ {
+ DeviceManagerOperationStatus status = m_host.GetDeviceManager().InterfaceReset(arguments[0]);
+ if (dmosSuccess != status)
+ {
+ LOG_ERROR << "Failed to perform interface reset on " + arguments[0] + ". Error: " + m_host.GetDeviceManager().GetDeviceManagerOperationStatusString(status);
+ response.message = (dmosNoSuchConnectedDevice == status) ? DecorateResponseMessage(false, m_host.GetDeviceManager().GetDeviceManagerOperationStatusString(status)) :
+ DecorateResponseMessage(false, GetCommandsHandlerResponseStatusString(chrsOperationFailure));
+ }
+ else
+ {
+ response.message = DecorateResponseMessage(true);
+ }
+ }
+ response.type = REPLY_TYPE_BUFFER;
+ response.length = response.message.size();
+ return response;
+}
+// *************************************************************************************************
+
+ResponseMessage CommandsHandler::SwReset(vector<string> arguments, unsigned int numberOfArguments)
+{
+ LOG_VERBOSE << __FUNCTION__ << endl;
+ ResponseMessage response;
+ if (ValidArgumentsNumber(__FUNCTION__, numberOfArguments, 1, response.message))
+ {
+ DeviceManagerOperationStatus status = m_host.GetDeviceManager().SwReset(arguments[0]);
+ if (dmosSuccess != status)
+ {
+ LOG_ERROR << "Failed to perform sw reset on " + arguments[0] + ". Error: " + m_host.GetDeviceManager().GetDeviceManagerOperationStatusString(status);
+ response.message = (dmosNoSuchConnectedDevice == status) ? DecorateResponseMessage(false, m_host.GetDeviceManager().GetDeviceManagerOperationStatusString(status)) :
+ DecorateResponseMessage(false, GetCommandsHandlerResponseStatusString(chrsOperationFailure));
+ }
+ else
+ {
+ response.message = DecorateResponseMessage(true);
+ }
+ }
+ response.type = REPLY_TYPE_BUFFER;
+ response.length = response.message.size();
+ return response;
+}
+// *************************************************************************************************
+
+ResponseMessage CommandsHandler::AllocPmc(vector<string> arguments, unsigned int numberOfArguments)
+{
+ //do something with params
+ (void)numberOfArguments;
+ LOG_VERBOSE << __FUNCTION__;
+ for (auto& s : arguments)
+ {
+ LOG_VERBOSE << "," << s;
+ }
+ LOG_VERBOSE << endl;
+
+ ResponseMessage response;
+ if (ValidArgumentsNumber(__FUNCTION__, arguments.size(), 3, response.message))
+ {
+ unsigned descSize;
+ unsigned descNum;
+ if (!Utils::ConvertDecimalStringToUnsignedInt(arguments[1], descSize) || !Utils::ConvertDecimalStringToUnsignedInt(arguments[2], descNum))
+ {
+ stringstream error;
+ response.message = DecorateResponseMessage(false, GetCommandsHandlerResponseStatusString(chrsInvalidArgument));
+ }
+ else
+ {
+ DeviceManagerOperationStatus status = m_host.GetDeviceManager().AllocPmc(arguments[0], descSize, descNum);
+ if (dmosSuccess != status)
+ {
+ stringstream error;
+ LOG_ERROR << __FUNCTION__ << ":" << m_host.GetDeviceManager().GetDeviceManagerOperationStatusString(status);
+ response.message = (dmosNoSuchConnectedDevice == status) ? DecorateResponseMessage(false, m_host.GetDeviceManager().GetDeviceManagerOperationStatusString(status)) :
+ DecorateResponseMessage(false, GetCommandsHandlerResponseStatusString(chrsOperationFailure));
+ }
+ else
+ {
+ response.message = DecorateResponseMessage(true);
+ }
+ }
+ }
+ response.type = REPLY_TYPE_BUFFER;
+ response.length = response.message.size();
+ return response;
+}
+// *************************************************************************************************
+
+ResponseMessage CommandsHandler::DeallocPmc(vector<string> arguments, unsigned int numberOfArguments)
+{
+ //do something with params
+ (void)numberOfArguments;
+ LOG_VERBOSE << __FUNCTION__;
+ for (auto& s : arguments)
+ {
+ LOG_VERBOSE << "," << s;
+ }
+ LOG_VERBOSE << endl;
+
+ ResponseMessage response;
+ if (ValidArgumentsNumber(__FUNCTION__, arguments.size(), 1, response.message))
+ {
+ DeviceManagerOperationStatus status = m_host.GetDeviceManager().DeallocPmc(arguments[0]);
+ if (dmosSuccess != status)
+ {
+ stringstream error;
+ LOG_ERROR << __FUNCTION__ << ":" << m_host.GetDeviceManager().GetDeviceManagerOperationStatusString(status);
+ response.message = (dmosNoSuchConnectedDevice == status) ? DecorateResponseMessage(false, m_host.GetDeviceManager().GetDeviceManagerOperationStatusString(status)) :
+ DecorateResponseMessage(false, GetCommandsHandlerResponseStatusString(chrsOperationFailure));
+ }
+ else
+ {
+ response.message = DecorateResponseMessage(true);
+ }
+ }
+ response.type = REPLY_TYPE_BUFFER;
+ response.length = response.message.size();
+ return response;
+}
+// *************************************************************************************************
+
+ResponseMessage CommandsHandler::CreatePmcFile(vector<string> arguments, unsigned int numberOfArguments)
+{
+ //do something with params
+ (void)numberOfArguments;
+ LOG_VERBOSE << __FUNCTION__;
+ for (auto& s : arguments)
+ {
+ LOG_VERBOSE << "," << s;
+ }
+ LOG_VERBOSE << endl;
+
+ ResponseMessage response;
+ if (ValidArgumentsNumber(__FUNCTION__, arguments.size(), 2, response.message))
+ {
+ unsigned refNumber;
+ if (!Utils::ConvertDecimalStringToUnsignedInt(arguments[1], refNumber))
+ {
+ response.message = DecorateResponseMessage(false, GetCommandsHandlerResponseStatusString(chrsInvalidArgument));
+ }
+ else
+ {
+ DeviceManagerOperationStatus status = m_host.GetDeviceManager().CreatePmcFile(arguments[0], refNumber);
+ if (dmosSuccess != status)
+ {
+ stringstream error;
+ LOG_ERROR << __FUNCTION__ << ":" << m_host.GetDeviceManager().GetDeviceManagerOperationStatusString(status);
+ response.message = (dmosNoSuchConnectedDevice == status) ? DecorateResponseMessage(false, m_host.GetDeviceManager().GetDeviceManagerOperationStatusString(status)) :
+ DecorateResponseMessage(false, GetCommandsHandlerResponseStatusString(chrsOperationFailure));
+ }
+ else
+ {
+ response.message = DecorateResponseMessage(true);
+ }
+ }
+ }
+ response.type = REPLY_TYPE_BUFFER;
+ response.length = response.message.size();
+ return response;
+}
+// *************************************************************************************************
+
+ResponseMessage CommandsHandler::ReadPmcFile(vector<string> arguments, unsigned int numberOfArguments)
+{
+ //do something with params
+ (void)numberOfArguments;
+ LOG_VERBOSE << __FUNCTION__;
+ for (auto& s : arguments)
+ {
+ LOG_VERBOSE << "," << s;
+ }
+ LOG_VERBOSE << endl;
+
+ ResponseMessage response;
+ response.type = REPLY_TYPE_BUFFER;
+
+#ifdef _WINDOWS
+ response.message = DecorateResponseMessage(false, GetCommandsHandlerResponseStatusString(chrsLinuxSupportOnly));
+#else
+ if (ValidArgumentsNumber(__FUNCTION__, arguments.size(), 1, response.message))
+ {
+ unsigned refNumber;
+ if (!Utils::ConvertDecimalStringToUnsignedInt(arguments[0], refNumber))
+ {
+ response.message = DecorateResponseMessage(false, GetCommandsHandlerResponseStatusString(chrsInvalidArgument));
+ }
+ else
+ {
+ LOG_DEBUG << "Reading PMC File #" << refNumber << endl;
+ PmcFile pmcFile(refNumber);
+
+ if (NULL == pmcFile.GetFileName())
+ {
+ response.message = DecorateResponseMessage(false, GetCommandsHandlerResponseStatusString(chrsOperationFailure));
+ }
+ else
+ {
+ // Note: Nthe file name won't be sent to a clientls
+ response.message = pmcFile.GetFileName();
+ response.type = REPLY_TYPE_FILE;
+ }
+ }
+ }
+#endif // _WINDOWS
+ response.length = response.message.size();
+ return response;
+}
+// *************************************************************************************************
+
+ResponseMessage CommandsHandler::SendWmi(vector<string> arguments, unsigned int numberOfArguments)
+{
+ //do something with params
+ (void)numberOfArguments;
+ LOG_VERBOSE << __FUNCTION__;
+ for (auto& s : arguments)
+ {
+ LOG_VERBOSE << "," << s;
+ }
+ LOG_VERBOSE << endl;
+
+ ResponseMessage response;
+ if (ValidArgumentsNumber(__FUNCTION__, arguments.size(), 3, response.message))
+ {
+ DWORD command;
+ vector<DWORD> payload;
+ if (!Utils::ConvertHexStringToDword(arguments[1], command) || !Utils::ConvertHexStringToDwordVector(arguments[2], m_array_delimiter, payload))
+ {
+ response.message = DecorateResponseMessage(false, GetCommandsHandlerResponseStatusString(chrsInvalidArgument));
+ }
+ DeviceManagerOperationStatus status = m_host.GetDeviceManager().SendWmi(arguments[0], command, payload);
+ if (dmosSuccess != status)
+ {
+ LOG_ERROR << __FUNCTION__ << ":" << m_host.GetDeviceManager().GetDeviceManagerOperationStatusString(status);
+ response.message = (dmosNoSuchConnectedDevice == status) ? DecorateResponseMessage(false, m_host.GetDeviceManager().GetDeviceManagerOperationStatusString(status)) :
+ DecorateResponseMessage(false, GetCommandsHandlerResponseStatusString(chrsOperationFailure));
+ }
+ else
+ {
+ response.message = DecorateResponseMessage(true);
+ }
+ }
+ response.type = REPLY_TYPE_BUFFER;
+ response.length = response.message.size();
+ return response;
+}
+// *************************************************************************************************
+
+ResponseMessage CommandsHandler::SetHostAlias(vector<string> arguments, unsigned int numberOfArguments)
+{
+ LOG_VERBOSE << __FUNCTION__ << endl;
+ ResponseMessage response;
+
+ if (ValidArgumentsNumber(__FUNCTION__, numberOfArguments, 1, response.message))
+ {
+ if (m_host.GetHostInfo().SaveAliasToFile(arguments[0]))
+ {
+ response.message = DecorateResponseMessage(true);
+ }
+ else
+ {
+ response.message = DecorateResponseMessage(false, GetCommandsHandlerResponseStatusString(chrsOperationFailure));
+ }
+ }
+ response.type = REPLY_TYPE_BUFFER;
+ response.length = response.message.size();
+ return response;
+}
+// *************************************************************************************************
+
+ResponseMessage CommandsHandler::GetTime(vector<string> arguments, unsigned int numberOfArguments)
+{
+ //do something with params
+ (void)arguments;
+ LOG_VERBOSE << __FUNCTION__ << endl;
+ ResponseMessage response;
+
+ if (ValidArgumentsNumber(__FUNCTION__, numberOfArguments, 0, response.message))
+ {
+ response.message = DecorateResponseMessage(true);
+ }
+ response.type = REPLY_TYPE_BUFFER;
+ response.length = response.message.size();
+ return response;
+}
+// *************************************************************************************************
+
+// *************************************************************************************************
+ResponseMessage CommandsHandler::SetDriverMode(vector<string> arguments, unsigned int numberOfArguments)
+{
+ LOG_VERBOSE << __FUNCTION__ << endl;
+ ResponseMessage response;
+ if (ValidArgumentsNumber(__FUNCTION__, numberOfArguments, 2, response.message))
+ {
+ int newMode;
+ int oldMode;
+
+ if ("WBE_MODE" == arguments[1])
+ {
+ newMode = IOCTL_WBE_MODE;
+ }
+ else if ("WIFI_STA_MODE" == arguments[1])
+ {
+ newMode = IOCTL_WIFI_STA_MODE;
+ }
+ else if ("WIFI_SOFTAP_MODE" == arguments[1])
+ {
+ newMode = IOCTL_WIFI_SOFTAP_MODE;
+ }
+ else if ("CONCURRENT_MODE" == arguments[1])
+ {
+ newMode = IOCTL_CONCURRENT_MODE;
+ }
+ else if ("SAFE_MODE" == arguments[1])
+ {
+ newMode = IOCTL_SAFE_MODE;
+ }
+ else
+ {
+ // TODO
+ response.message = dmosFail;
+ response.type = REPLY_TYPE_BUFFER;
+ response.length = response.message.size();
+ return response;
+ }
+
+ DeviceManagerOperationStatus status = m_host.GetDeviceManager().SetDriverMode(arguments[0], newMode, oldMode);
+ if (dmosSuccess != status)
+ {
+ LOG_ERROR << "Failed to set driver mode on " + arguments[0] + ". Error: " + m_host.GetDeviceManager().GetDeviceManagerOperationStatusString(status);
+ response.message = (dmosNoSuchConnectedDevice == status) ? DecorateResponseMessage(false, m_host.GetDeviceManager().GetDeviceManagerOperationStatusString(status)) :
+ DecorateResponseMessage(false, GetCommandsHandlerResponseStatusString(chrsOperationFailure));
+ }
+ else
+ {
+ string message;
+
+ switch (oldMode)
+ {
+ case IOCTL_WBE_MODE:
+ message = "WBE_MODE";
+ break;
+ case IOCTL_WIFI_STA_MODE:
+ message = "WIFI_STA_MODE";
+ break;
+ case IOCTL_WIFI_SOFTAP_MODE:
+ message = "WIFI_SOFTAP_MODE";
+ break;
+ case IOCTL_CONCURRENT_MODE:
+ message = "CONCURRENT_MODE";
+ break;
+ case IOCTL_SAFE_MODE:
+ message = "SAFE_MODE";
+ break;
+ default:
+ break;
+ }
+
+ response.message = DecorateResponseMessage(true, message);
+ }
+ }
+ response.type = REPLY_TYPE_BUFFER;
+ response.length = response.message.size();
+ return response;
+}
+// *************************************************************************************************
+
+// **************************************UDP commands handlers*********************************************************** //
+ResponseMessage CommandsHandler::GetHostNetworkInfo(vector<string> arguments, unsigned int numberOfArguments)
+{
+ //do something with params
+ (void)numberOfArguments;
+ LOG_VERBOSE << __FUNCTION__ << endl;
+ ResponseMessage response;
+
+ if (arguments.size() != 0)
+ {
+ response.message = DecorateResponseMessage(false, "Failed to get host's info: expected zero argument");
+ }
+ else
+ {
+ response.message = "GetHostIdentity;" + m_host.GetHostInfo().GetIps().m_ip + ";" + m_host.GetHostInfo().GetAlias();
+ }
+
+ response.type = REPLY_TYPE_BUFFER;
+ response.length = response.message.size();
+ return response;
+}
+// *************************************************************************************************
+
+CommandsHandler::CommandsHandler(ServerType type, Host& host) :
+ m_host(host)
+{
+ if (stTcp == type) // TCP server
+ {
+ m_functionHandler.insert(make_pair("get_interfaces", &CommandsHandler::GetInterfaces));
+ m_functionHandler.insert(make_pair("open_interface", &CommandsHandler::OpenInterface));
+ m_functionHandler.insert(make_pair("close_interface", &CommandsHandler::CloseInterface));
+ m_functionHandler.insert(make_pair("r", &CommandsHandler::Read));
+ m_functionHandler.insert(make_pair("rb", &CommandsHandler::ReadBlock));
+ m_functionHandler.insert(make_pair("w", &CommandsHandler::Write));
+ m_functionHandler.insert(make_pair("wb", &CommandsHandler::WriteBlock));
+ m_functionHandler.insert(make_pair("interface_reset", &CommandsHandler::InterfaceReset));
+ m_functionHandler.insert(make_pair("sw_reset", &CommandsHandler::SwReset));
+ m_functionHandler.insert(make_pair("alloc_pmc", &CommandsHandler::AllocPmc));
+ m_functionHandler.insert(make_pair("dealloc_pmc", &CommandsHandler::DeallocPmc));
+ m_functionHandler.insert(make_pair("create_pmc_file", &CommandsHandler::CreatePmcFile));
+ m_functionHandler.insert(make_pair("read_pmc_file", &CommandsHandler::ReadPmcFile));
+ m_functionHandler.insert(make_pair("send_wmi", &CommandsHandler::SendWmi));
+ m_functionHandler.insert(make_pair("set_host_alias", &CommandsHandler::SetHostAlias));
+ m_functionHandler.insert(make_pair("get_time", &CommandsHandler::GetTime));
+ m_functionHandler.insert(make_pair("set_local_driver_mode", &CommandsHandler::SetDriverMode));
+ }
+ else // UDP server
+ {
+ m_functionHandler.insert(make_pair(/*"get_host_network_info"*/"GetHostIdentity", &CommandsHandler::GetHostNetworkInfo));
+ }
+}
+
+// *************************************************************************************************
+
+ConnectionStatus CommandsHandler::ExecuteCommand(string message, ResponseMessage &referencedResponse)
+{
+ m_pMessageParser.reset(new MessageParser(message));
+
+ string commandName = m_pMessageParser->GetCommandFromMessage();
+
+ LOG_DEBUG << "command name: " << commandName << endl; //TODO - remove after test
+
+ if (m_functionHandler.find(commandName) == m_functionHandler.end())
+ { //There's no such a command, the return value from the map would be null
+ LOG_WARNING << "Unknown command from client: " << commandName << endl;
+ referencedResponse.message = "Unknown command: " + commandName;
+ referencedResponse.length = referencedResponse.message.size();
+ referencedResponse.type = REPLY_TYPE_BUFFER;
+ return KEEP_CONNECTION_ALIVE;
+ }
+ referencedResponse = (this->*m_functionHandler[commandName])(m_pMessageParser->GetArgsFromMessage(), m_pMessageParser->GetNumberOfArgs()); //call the function that fits commandName
+
+
+
+ /* For testing while developing: */
+ vector<string> vec = m_pMessageParser->GetArgsFromMessage(); //TODO - remove after test
+ for (auto i: vec) //TODO - remove after test - print the given arguments
+ {
+ LOG_DEBUG << "argument is: " << i << endl;
+ }
+ /* End of testing for developing */
+
+ return KEEP_CONNECTION_ALIVE;
+}
diff --git a/debug-tools/host_manager_11ad/CommandsHandler.h b/debug-tools/host_manager_11ad/CommandsHandler.h
new file mode 100644
index 0000000..b2ae6c8
--- /dev/null
+++ b/debug-tools/host_manager_11ad/CommandsHandler.h
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _COMMANDSHANDLER_H_
+#define _COMMANDSHANDLER_H_
+
+#include <iostream>
+#include <memory>
+#include <map>
+#include "MessageParser.h"
+#include "HostDefinitions.h"
+#include <sstream>
+
+class Host;
+
+using namespace std;
+
+
+// *************************************************************************************************
+
+class CommandsHandler
+{
+public:
+ /*
+ * pCommandFunction is used for the functions map - each function gets two arguments:
+ * vector of strings which holds the arguments and the number of arguments in that vector
+ */
+ typedef ResponseMessage(CommandsHandler::*pCommandFunction)(vector<string>, unsigned int);
+
+ /*
+ * The constructor inserts each one of the available functions into the map - m_functionHandler - according to server type (TCP/UDP)
+ */
+ CommandsHandler(ServerType type, Host& host);
+
+ ConnectionStatus ExecuteCommand(string message, ResponseMessage &referencedResponse);
+
+
+private:
+ shared_ptr<MessageParser> m_pMessageParser;
+ //m_functionHandler is a map that maps a string = command name, to a function
+ map<string, pCommandFunction> m_functionHandler;
+ Host& m_host; // a refernce to the host (enables access to deviceManager and hostInfo)
+
+ enum CommandsHandlerResponseStatus
+ {
+ chrsInvalidNumberOfArguments,
+ chrsInvalidArgument,
+ chrsOperationFailure,
+ chrsLinuxSupportOnly,
+ chrsSuccess
+ };
+
+ string GetCommandsHandlerResponseStatusString(CommandsHandlerResponseStatus status)
+ {
+ switch (status)
+ {
+ case chrsInvalidNumberOfArguments:
+ return "Invalid arguments number";
+ case chrsInvalidArgument:
+ return "Invaild argument type";
+ case chrsOperationFailure:
+ return "Operation failure";
+ case chrsLinuxSupportOnly:
+ return "Linux support only";
+ case chrsSuccess:
+ return "Success";
+ default:
+ return "CommandsHandlerResponseStatus is unknown";
+ }
+ }
+
+ /*
+ FormatResponseMessage
+ Decorate the response message with time stamp and a success status
+ @param: successStatus - true for a successful operation, false otherwise
+ @param: message - the content of the response
+ @return: the decorated response
+ */
+ string DecorateResponseMessage(bool successStatus, string message = "");
+
+ // **********************************Commands Functions:****************************************
+ ResponseMessage GetInterfaces(vector<string> arguments, unsigned int numberOfArguments);
+
+ ResponseMessage OpenInterface(vector<string> arguments, unsigned int numberOfArguments);
+
+ ResponseMessage CloseInterface(vector<string> arguments, unsigned int numberOfArguments);
+
+ ResponseMessage Read(vector<string> arguments, unsigned int numberOfArguments);
+
+ ResponseMessage Write(vector<string> arguments, unsigned int numberOfArguments);
+
+ ResponseMessage ReadBlock(vector<string> arguments, unsigned int numberOfArguments);
+
+ ResponseMessage WriteBlock(vector<string> arguments, unsigned int numberOfArguments);
+
+ ResponseMessage InterfaceReset(vector<string> arguments, unsigned int numberOfArguments);
+
+ ResponseMessage SwReset(vector<string> arguments, unsigned int numberOfArguments);
+
+ ResponseMessage AllocPmc(vector<string> arguments, unsigned int numberOfArguments);
+
+ ResponseMessage DeallocPmc(vector<string> arguments, unsigned int numberOfArguments);
+
+ ResponseMessage CreatePmcFile(vector<string> arguments, unsigned int numberOfArguments);
+
+ ResponseMessage ReadPmcFile(vector<string> arguments, unsigned int numberOfArguments);
+
+ ResponseMessage SendWmi(vector<string> arguments, unsigned int numberOfArguments);
+
+ ResponseMessage GetTime(vector<string> arguments, unsigned int numberOfArguments);
+
+ ResponseMessage SetDriverMode(vector<string> arguments, unsigned int numberOfArguments);
+
+
+ bool ValidArgumentsNumber(string functionName, size_t numberOfArguments, size_t expectedNumOfArguments, string& responseMessage)
+ {
+ if (expectedNumOfArguments != numberOfArguments)
+ {
+ stringstream error;
+ LOG_WARNING << "Mismatching number of arguments in " << functionName << ": expected " << expectedNumOfArguments << " but got "<< numberOfArguments << endl;
+ responseMessage = DecorateResponseMessage(false, GetCommandsHandlerResponseStatusString(chrsInvalidNumberOfArguments));
+ return false;
+ }
+ return true;
+ }
+
+ /*
+ GetHostNetworkInfo
+ Return host's IP and host's alias as the Response
+ @param: an empty vector
+ @return: a response with a string that contains both host's IP and host's alias
+ */
+ ResponseMessage GetHostNetworkInfo(vector<string> arguments, unsigned int numberOfArguments);
+
+ /*
+ SetHostAlias
+ Get a new alias and define it as the new host's alias
+ @param: a vector with one string representing the new alias
+ @return: a response with feedback about the operation status (success/failure)
+ */
+ ResponseMessage SetHostAlias(vector<string> arguments, unsigned int numberOfArguments);
+
+ const char m_device_delimiter = ' ';
+
+ const char m_array_delimiter = ' ';
+
+ const char m_reply_feilds_delimiter = '|';
+};
+
+
+#endif // !_COMMANDSHANDLER_H_
diff --git a/debug-tools/host_manager_11ad/CommandsTcpServer.cpp b/debug-tools/host_manager_11ad/CommandsTcpServer.cpp
new file mode 100644
index 0000000..cdfe62f
--- /dev/null
+++ b/debug-tools/host_manager_11ad/CommandsTcpServer.cpp
@@ -0,0 +1,245 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "CommandsTcpServer.h"
+#include <thread>
+#include "NetworkInterface.h"
+#include "FileReader.h"
+#include "Host.h"
+
+using namespace std;
+
+// *************************************************************************************************
+
+CommandsTcpServer::CommandsTcpServer(unsigned int commandsTcpPort, Host& host)
+ :m_port(commandsTcpPort),m_pSocket(new NetworkInterfaces::NetworkInterface()), m_host(host)
+{
+}
+
+// *************************************************************************************************
+
+void CommandsTcpServer::Start()
+{
+ LOG_INFO << "Starting commands TCP server on port " << m_port << endl;
+ m_pSocket->Bind(m_port);
+ m_pSocket->Listen();
+
+ //Infinite loop that waits for clients to connect to the commands TCP server - there's no reason to stop this loop,
+ //should run forever unless there is a problem
+ while (true)
+ {
+ try
+ {
+ //thread serverThread = thread(&ServerThread, m_pServer->accept());
+ thread serverThread(&CommandsTcpServer::ServerThread, this, m_pSocket->Accept()); //open a new thread for each client
+ serverThread.detach();
+ }
+ catch (exception e)
+ {
+ LOG_ERROR << "Couldn't make a new connection or starting a new thread in Commands TCP server for a new client " << e.what() << endl;
+ }
+
+ }
+}
+
+void CommandsTcpServer::Stop()
+{
+ LOG_INFO << "Stopping the commands TCP server" << endl;
+ m_pSocket->Shutdown(2); //type 2 -> Acts like the close(), shutting down both input and output
+}
+
+// *************************************************************************************************
+//A thread function to handle each client that connects to the server
+void CommandsTcpServer::ServerThread(NetworkInterfaces::NetworkInterface client)
+{
+ unique_ptr<CommandsHandler> pCommandsHandler(new CommandsHandler(stTcp, m_host));
+ ConnectionStatus keepConnectionAliveFromCommand = KEEP_CONNECTION_ALIVE; //A flag for the content of the command - says if the client wants to close connection
+ ConnectionStatus keepConnectionAliveFromReply = KEEP_CONNECTION_ALIVE; //A flag for the reply status, for problems in sending reply etc..
+ m_host.GetHostInfo().AddNewConnectedUser(client.GetPeerName()); // add the user's to the host's connected users
+
+ do
+ {
+ string messages;
+ messages.empty();
+
+ try
+ {
+ messages = client.Receive();
+ vector<string> splitMessages = Utils::Split(messages, '\r');
+
+ for (auto& message : splitMessages)
+ {
+ ResponseMessage referencedResponse = { "", REPLY_TYPE_NONE, 0 };
+ if (message.empty())
+ { //message back from the client is "", means the connection is closed
+ break;
+ }
+
+ //Try to execute the command from the client, get back from function if to keep the connection with the client alive or not
+ keepConnectionAliveFromCommand = pCommandsHandler->ExecuteCommand(message, referencedResponse);
+
+ //Reply back to the client an answer for his command. If it wasn't successful - close the connection
+ keepConnectionAliveFromReply = CommandsTcpServer::Reply(client, referencedResponse);
+ }
+ //LOG_INFO << "Message from Client to commands TCP server: " << message << endl;
+ }
+ catch (exception e)
+ {
+ LOG_ERROR << "Couldn't get the message from the client" << e.what() << endl;
+ break;
+ }
+
+ } while (keepConnectionAliveFromCommand != CLOSE_CONNECTION && keepConnectionAliveFromReply != CLOSE_CONNECTION);
+
+ //client.shutdown(0); //TODO - check how to do it correctly (without exception)
+ //client.shutdown(1); //TODO - check how to do it correctly (without exception)
+ //client.close(); //TODO - check how to do it correctly (without exception)
+ LOG_INFO << "Closed connection with the client: " << client.GetPeerName() << endl;
+ m_host.GetHostInfo().RemoveNewConnectedUser(client.GetPeerName());
+}
+
+// *************************************************************************************************
+
+ConnectionStatus CommandsTcpServer::Reply(NetworkInterfaces::NetworkInterface &client, ResponseMessage &responseMessage)
+{
+ LOG_DEBUG << "Reply is: " << responseMessage.message << endl;
+
+ switch (responseMessage.type)
+ {
+ case REPLY_TYPE_BUFFER:
+ return ReplyBuffer(client, responseMessage);
+ case REPLY_TYPE_FILE:
+ return ReplyFile(client, responseMessage);
+ default:
+ //LOG_ERROR << "Unknown reply type" << endl;
+ break;
+ }
+ return CLOSE_CONNECTION;
+}
+
+
+// *************************************************************************************************
+
+ConnectionStatus CommandsTcpServer::ReplyBuffer(NetworkInterfaces::NetworkInterface &client, ResponseMessage &responseMessage)
+{
+ LOG_DEBUG << "Replying from a buffer (" << responseMessage.length << "B) Content: " << responseMessage.message << endl;
+
+ if (0 == responseMessage.length)
+ {
+ LOG_ERROR << "No reply generated by a command handler - connection will be closed" << endl;
+ return CLOSE_CONNECTION;
+ }
+
+ try
+ {
+ client.Send((responseMessage.message + "\r").c_str()); //TODO - maybe the sending format is ending with "\n\r"
+ }
+ catch (const exception& e)
+ {
+ LOG_ERROR << "couldn't send the message to the client, closing connection: " << e.what() << endl;
+ return CLOSE_CONNECTION;
+ }
+ catch (int e) // TODO: check if we can remove the previous catch
+ {
+ LOG_ERROR << "couldn't send the message to the client, closing connection: " << e << endl;
+ return CLOSE_CONNECTION;
+ }
+
+
+ return KEEP_CONNECTION_ALIVE;
+}
+
+
+//TODO - reply file had been copied from old "wilserver" almost without touching it.
+//It has to be checked and also modified to fit the new "host_server_11ad"
+//The same applies to "FileReader.h" and "FileReader.cpp"
+ConnectionStatus CommandsTcpServer::ReplyFile(NetworkInterfaces::NetworkInterface & client, ResponseMessage & fileName)
+{
+ LOG_DEBUG << "Replying from a file: " << fileName.message << std::endl;
+ FileReader fileReader(fileName.message.c_str());
+ size_t fileSize = fileReader.GetFileSize();
+
+ if (0 == fileSize)
+ {
+ LOG_ERROR << "No file content is available for reply" << std::endl;
+ return CLOSE_CONNECTION;
+ }
+
+ static const size_t BUF_LEN = 64 * 1024;
+
+ char* pBuf = new char[BUF_LEN];
+ size_t chunkSize = 0;
+ bool isError = false;
+
+ do
+ {
+ LOG_VERBOSE << "Requesting for a file chunk" << std::endl;
+
+ chunkSize = fileReader.ReadChunk(pBuf, BUF_LEN);
+ if (chunkSize > 0)
+ {
+ //if (false == send_buffer(sock, pBuf, chunkSize)) //TODO - was in the old "wilserver" changed to the next line (with client.send(pBuf))
+ if (0 == client.Send(pBuf))
+ {
+ LOG_ERROR << "Send error detected" << std::endl;
+ isError = true;
+ break;
+ }
+ }
+
+ // Error/Completion may occur with non-zero chunk as well
+ if (fileReader.IsError())
+ {
+ LOG_ERROR << "File read error detected" << std::endl;
+ isError = true;
+ break;
+ }
+
+ if (fileReader.IsCompleted())
+ {
+ LOG_DEBUG << "File completion detected" << std::endl;
+ break;
+ }
+
+ LOG_DEBUG << "File Chunk Delivered: " << chunkSize << "B" << std::endl;
+ } while (chunkSize > 0);
+
+ delete[] pBuf;
+
+ if (isError)
+ {
+ LOG_ERROR << "Error occurred while replying file content" << std::endl;
+ return CLOSE_CONNECTION;
+ }
+ else
+ {
+ LOG_DEBUG << "File Content successfully delivered" << std::endl;
+ return KEEP_CONNECTION_ALIVE;
+ }
+}
diff --git a/debug-tools/host_manager_11ad/CommandsTcpServer.h b/debug-tools/host_manager_11ad/CommandsTcpServer.h
new file mode 100644
index 0000000..fa6d8dc
--- /dev/null
+++ b/debug-tools/host_manager_11ad/CommandsTcpServer.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _COMMANDSTCPSERVER_H_
+#define _COMMANDSTCPSERVER_H_
+
+#include "NetworkInterface.h"
+#include <memory>
+#include "HostDefinitions.h"
+#include "CommandsHandler.h"
+
+using namespace std;
+
+class Host;
+
+/*
+* Commands TCP Server is a synchronous server that handles each client separately.
+* When a client sends a new command to the Commands TCP Server, the host processes it and sends back to the client an answer.
+*/
+class CommandsTcpServer
+{
+public:
+
+ /*
+ * Commands TCP server constructor gets the port to start in. It also initializes new Socket object.
+ */
+ CommandsTcpServer(unsigned int commandsTcpPort, Host& host);
+
+ /*
+ * Start the commands TCP server at the given port (given in the constructor).
+ * For each new client that is connecting to the server it opens a new thread and
+ * continue to listen on the port for more clients.
+ */
+ void Start();
+
+ /*
+ * Stop the commands TCP server by doing some clean ups for the sockets.
+ */
+ void Stop();
+
+private:
+
+ unsigned int m_port; //The port in which the commands TCP server is working on
+ shared_ptr<NetworkInterfaces::NetworkInterface> m_pSocket; //an object that holds the connection with each client
+ Host& m_host; // refernce to the host object (that is passed to commandsHandler each time a new TCP connection is created)
+
+ void ServerThread(NetworkInterfaces::NetworkInterface client);
+ ConnectionStatus Reply(NetworkInterfaces::NetworkInterface &client, ResponseMessage &responseMessage);
+ ConnectionStatus ReplyBuffer(NetworkInterfaces::NetworkInterface &client, ResponseMessage &responseMessage);
+ ConnectionStatus ReplyFile(NetworkInterfaces::NetworkInterface &client, ResponseMessage &fileName);
+};
+
+
+#endif // !_COMMANDSTCPSERVER_H_
+
diff --git a/debug-tools/host_manager_11ad/DebugLogger.cpp b/debug-tools/host_manager_11ad/DebugLogger.cpp
new file mode 100644
index 0000000..cf3ae90
--- /dev/null
+++ b/debug-tools/host_manager_11ad/DebugLogger.cpp
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "DebugLogger.h"
+#include <stdio.h>
+
+// *************************************************************************************************
+
+LogConfig g_LogConfig(LOG_SEV_INFO, false);
+
+// *************************************************************************************************
+
+LogConfig::LogConfig(LogSeverity maxSeverity, bool bPrintLocation)
+ : m_MaxSeverity(maxSeverity), m_PrintLocation(bPrintLocation)
+{
+}
+
+void LogConfig::SetMaxSeverity(int traceLevel)
+{
+ if (traceLevel > LOG_SEV_VERBOSE)
+ {
+ fprintf(stderr, "Invalid trace level, setting %d\n", LOG_SEV_VERBOSE);
+ m_MaxSeverity = LOG_SEV_VERBOSE;
+ }
+ else
+ {
+ m_MaxSeverity = static_cast<LogSeverity>(traceLevel);
+ fprintf(stdout, "Setting trace level to %d\n", m_MaxSeverity);
+ }
+}
+
+// *************************************************************************************************
+
+const char* LogMsgPrefix::SeverityToString(LogSeverity sev)
+{
+ static const char* const pSeverityToString[] = { "ERR", "WRN", "INF", "DBG", "VRB" };
+
+ size_t index = static_cast<size_t>(sev);
+ if (index >= sizeof(pSeverityToString) / sizeof(pSeverityToString[0]))
+ {
+ return "---";
+ }
+
+ return pSeverityToString[index];
+}
+
+std::ostream& operator<<(std::ostream& os, const LogMsgPrefix& prefix)
+{
+ os << '[' << LogMsgPrefix::SeverityToString(prefix.Severity) << "] ";
+ if (!g_LogConfig.ShouldPrintLocation()) return os;
+ return os << "(" << prefix.File << ':' << prefix.Line << ") ";
+}
diff --git a/debug-tools/host_manager_11ad/DebugLogger.h b/debug-tools/host_manager_11ad/DebugLogger.h
new file mode 100644
index 0000000..20160e6
--- /dev/null
+++ b/debug-tools/host_manager_11ad/DebugLogger.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _DEBUGLOGGER_H_
+#define _DEBUGLOGGER_H_
+
+#include <iostream>
+
+// Severity values are expected to raise from zero
+enum LogSeverity
+{
+ LOG_SEV_ERROR = 0, // Unexpected input/events that may cause server misbehavior
+ LOG_SEV_WARNING = 1, // Suspicious events
+ LOG_SEV_INFO = 2, // Events like command/response
+ LOG_SEV_DEBUG = 3, // Detailed functionality
+ LOG_SEV_VERBOSE = 4 // Excessive debug
+};
+
+#define TRACE_WITH_PREFIX(SEV) \
+ g_LogConfig.ShouldPrint(SEV) && std::cout << LogMsgPrefix(SEV, __FILE__, __LINE__)
+
+#define LOG_ERROR TRACE_WITH_PREFIX(LOG_SEV_ERROR)
+#define LOG_WARNING TRACE_WITH_PREFIX(LOG_SEV_WARNING)
+#define LOG_INFO TRACE_WITH_PREFIX(LOG_SEV_INFO)
+#define LOG_DEBUG TRACE_WITH_PREFIX(LOG_SEV_DEBUG)
+#define LOG_VERBOSE TRACE_WITH_PREFIX(LOG_SEV_VERBOSE)
+
+// *************************************************************************************************
+
+struct LogConfig
+{
+public:
+ LogConfig(LogSeverity maxSeverity, bool bPrintLocation);
+ void SetMaxSeverity(int traceLevel);
+
+ bool ShouldPrint(LogSeverity sev) const { return sev <= m_MaxSeverity; }
+ bool ShouldPrintLocation() const { return m_PrintLocation; }
+
+private:
+
+ LogSeverity m_MaxSeverity;
+ const bool m_PrintLocation;
+
+};
+
+// *************************************************************************************************
+
+extern LogConfig g_LogConfig;
+
+// *************************************************************************************************
+
+class LogMsgPrefix
+{
+ friend std::ostream& operator<<(std::ostream& os, const LogMsgPrefix& prefix);
+
+public:
+
+ LogMsgPrefix(LogSeverity severity, const char* pFile, int line)
+ : Severity(severity), File(pFile), Line(line) {}
+
+private:
+
+ static const char* SeverityToString(LogSeverity sev);
+
+ const LogSeverity Severity;
+ const char* const File;
+ const int Line;
+};
+
+
+// *************************************************************************************************
+// Stream Formatters
+// *************************************************************************************************
+
+// Print a boolean value as a string
+struct BoolStr
+{
+ explicit BoolStr(bool value): Value(value) {}
+ const bool Value;
+};
+
+inline std::ostream& operator<<(std::ostream& os, const BoolStr& boolStr)
+{
+ return os << std::boolalpha << boolStr.Value << std::noboolalpha;
+}
+
+// *************************************************************************************************
+
+// Print a string while displaying newline characters
+struct PlainStr
+{
+ explicit PlainStr(const std::string& value): Value(value) {}
+ const std::string& Value;
+};
+
+inline std::ostream& operator<<(std::ostream& os, const PlainStr& plainStr)
+{
+ for (std::string::const_iterator it = plainStr.Value.begin(); it != plainStr.Value.end(); ++it)
+ {
+ switch (*it)
+ {
+ case '\r': os << "\\r"; break;
+ case '\n': os << "\\n"; break;
+ case '\t': os << "\\t"; break;
+ default: os << *it; break;
+ }
+ }
+
+ return os;
+}
+
+
+#endif // ! _DEBUGLOGGER_H_
diff --git a/debug-tools/host_manager_11ad/DeviceManager.cpp b/debug-tools/host_manager_11ad/DeviceManager.cpp
new file mode 100644
index 0000000..debba4b
--- /dev/null
+++ b/debug-tools/host_manager_11ad/DeviceManager.cpp
@@ -0,0 +1,490 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <chrono>
+#include <thread>
+#include <future>
+
+#include "DeviceManager.h"
+#include "Utils.h"
+#include "AccessLayerAPI.h"
+
+DeviceManager::DeviceManager() :
+ m_deviceManagerRestDurationMs(500),
+ m_terminate(false)
+{
+ m_deviceManager = thread(&DeviceManager::PeriodicTasks, this);
+}
+
+DeviceManager::~DeviceManager()
+{
+ m_terminate = true;
+ m_deviceManager.join();
+}
+
+string DeviceManager::GetDeviceManagerOperationStatusString(DeviceManagerOperationStatus status)
+{
+ switch (status)
+ {
+ case dmosSuccess:
+ return "Successful operation";
+ case dmosNoSuchConnectedDevice:
+ return "Unknown device";
+ case dmosFailedToReadFromDevice:
+ return "Read failure";
+ case dmosFailedToWriteToDevice:
+ return "Write failure";
+ case dmosFailedToResetInterface:
+ return "Reset interface failure";
+ case dmosFailedToResetSw:
+ return "SW reset failure";
+ case dmosFailedToAllocatePmc:
+ return "Allocate PMC failure";
+ case dmosFailedToDeallocatePmc:
+ return "Deallocate PMC failure";
+ case dmosFailedToCreatePmcFile:
+ return "Create PMC file failure";
+ case dmosFailedToSendWmi:
+ return "Send WMI failure";
+ case dmosFail:
+ return "Operation failure";
+ default:
+ return "DeviceManagerOperationStatus is unknown ";
+ }
+}
+
+DeviceManagerOperationStatus DeviceManager::GetDevices(set<string>& devicesNames)
+{
+ devicesNames.clear();
+ for (auto& device : m_connectedDevices)
+ {
+ devicesNames.insert(device.first);
+ }
+ return dmosSuccess;
+}
+
+DeviceManagerOperationStatus DeviceManager::OpenInterface(string deviceName)
+{
+ if (m_connectedDevices.count(deviceName) > 0)
+ {
+ return dmosSuccess;
+ }
+ return dmosNoSuchConnectedDevice;
+}
+
+DeviceManagerOperationStatus DeviceManager::CloseInterface(string deviceName)
+{
+ if (m_connectedDevices.count(deviceName) > 0)
+ {
+ return dmosSuccess;
+ }
+ return dmosNoSuchConnectedDevice;
+}
+
+DeviceManagerOperationStatus DeviceManager::Read(string deviceName, DWORD address, DWORD& value)
+{
+ if ((0 == address) || (0 != address % 4) || (0xFFFFFFFF == address))
+ {
+ return dmosInvalidAddress;
+ }
+
+ DeviceManagerOperationStatus status;
+ m_connectedDevicesMutex.lock();
+ if (m_connectedDevices.count(deviceName) > 0)
+ {
+ m_connectedDevices[deviceName]->m_mutex.lock();
+ m_connectedDevicesMutex.unlock();
+ bool success = m_connectedDevices[deviceName]->m_device->Read(address, value);
+ if (success)
+ {
+ status = dmosSuccess;
+ }
+ else
+ {
+ value = Device::GetRegisterDefaultValue();
+ status = dmosFailedToReadFromDevice;
+ }
+ m_connectedDevices[deviceName]->m_mutex.unlock();
+ return status;
+ }
+ else
+ {
+ m_connectedDevicesMutex.unlock();
+ value = Device::GetRegisterDefaultValue();
+ return dmosNoSuchConnectedDevice;
+ }
+}
+
+DeviceManagerOperationStatus DeviceManager::Write(string deviceName, DWORD address, DWORD value)
+{
+ if ((0 == address) || (0 != address % 4) || (0xFFFFFFFF == address))
+ {
+ return dmosInvalidAddress;
+ }
+
+ DeviceManagerOperationStatus status;
+ m_connectedDevicesMutex.lock();
+ if (m_connectedDevices.count(deviceName) > 0)
+ {
+ m_connectedDevices[deviceName]->m_mutex.lock();
+ m_connectedDevicesMutex.unlock();
+ bool success = m_connectedDevices[deviceName]->m_device->Write(address, value);
+ if (success)
+ {
+ status = dmosSuccess;
+ }
+ else
+ {
+ status = dmosFailedToWriteToDevice;
+ }
+ m_connectedDevices[deviceName]->m_mutex.unlock();
+ return status;
+ }
+ else
+ {
+ m_connectedDevicesMutex.unlock();
+ return dmosNoSuchConnectedDevice;
+ }
+}
+
+DeviceManagerOperationStatus DeviceManager::ReadBlock(string deviceName, DWORD address, DWORD blockSize, vector<DWORD>& values)
+{
+ if ((0 == address) || (0 != address % 4) || (0xFFFFFFFF == address))
+ {
+ return dmosInvalidAddress;
+ }
+
+ DeviceManagerOperationStatus status;
+ m_connectedDevicesMutex.lock();
+ if (m_connectedDevices.count(deviceName) > 0)
+ {
+ m_connectedDevices[deviceName]->m_mutex.lock();
+ m_connectedDevicesMutex.unlock();
+ bool success = m_connectedDevices[deviceName]->m_device->ReadBlock(address, blockSize, values);
+ if (success)
+ {
+ status = dmosSuccess;
+ }
+ else
+ {
+ vector<DWORD> defaultValues(blockSize, Device::GetRegisterDefaultValue());
+ status = dmosFailedToReadFromDevice;
+ }
+ m_connectedDevices[deviceName]->m_mutex.unlock();
+ return status;
+ }
+ else
+ {
+ m_connectedDevicesMutex.unlock();
+ vector<DWORD> defaultValues(blockSize, Device::GetRegisterDefaultValue());
+ return dmosNoSuchConnectedDevice;
+ }
+}
+
+DeviceManagerOperationStatus DeviceManager::WriteBlock(string deviceName, DWORD address, const vector<DWORD>& values)
+{
+ if ((0 == address) || (0 != address % 4) || (0xFFFFFFFF == address))
+ {
+ return dmosInvalidAddress;
+ }
+
+ DeviceManagerOperationStatus status;
+ m_connectedDevicesMutex.lock();
+ if (m_connectedDevices.count(deviceName) > 0)
+ {
+ m_connectedDevices[deviceName]->m_mutex.lock();
+ m_connectedDevicesMutex.unlock();
+ bool success = m_connectedDevices[deviceName]->m_device->WriteBlock(address, values);
+ if (success)
+ {
+ status = dmosSuccess;
+ }
+ else
+ {
+ status = dmosFailedToWriteToDevice;
+ }
+ m_connectedDevices[deviceName]->m_mutex.unlock();
+ return status;
+ }
+ else
+ {
+ m_connectedDevicesMutex.unlock();
+ return dmosNoSuchConnectedDevice;
+ }
+}
+
+DeviceManagerOperationStatus DeviceManager::InterfaceReset(string deviceName)
+{
+ DeviceManagerOperationStatus status;
+ m_connectedDevicesMutex.lock();
+ if (m_connectedDevices.count(deviceName) > 0)
+ {
+ m_connectedDevices[deviceName]->m_mutex.lock();
+ m_connectedDevicesMutex.unlock();
+ m_connectedDevices[deviceName]->m_device->InterfaceReset();
+ status = dmosSuccess;
+ m_connectedDevices[deviceName]->m_mutex.unlock();
+ return status;
+ }
+ else
+ {
+ m_connectedDevicesMutex.unlock();
+ return dmosNoSuchConnectedDevice;
+ }
+}
+
+DeviceManagerOperationStatus DeviceManager::SwReset(string deviceName)
+{
+ DeviceManagerOperationStatus status;
+ m_connectedDevicesMutex.lock();
+ if (m_connectedDevices.count(deviceName) > 0)
+ {
+ m_connectedDevices[deviceName]->m_mutex.lock();
+ m_connectedDevicesMutex.unlock();
+ bool success = m_connectedDevices[deviceName]->m_device->SwReset();
+ if (success)
+ {
+ status = dmosSuccess;
+ }
+ else
+ {
+ status = dmosFailedToResetSw;
+ }
+ m_connectedDevices[deviceName]->m_mutex.unlock();
+ return status;
+ }
+ else
+ {
+ m_connectedDevicesMutex.unlock();
+ return dmosNoSuchConnectedDevice;
+ }
+}
+
+DeviceManagerOperationStatus DeviceManager::SetDriverMode(string deviceName, int newMode, int& oldMode)
+{
+ DeviceManagerOperationStatus status;
+ m_connectedDevicesMutex.lock();
+ if (m_connectedDevices.count(deviceName) > 0)
+ {
+ m_connectedDevices[deviceName]->m_mutex.lock();
+ m_connectedDevicesMutex.unlock();
+ bool success = m_connectedDevices[deviceName]->m_device->SetDriverMode(newMode, oldMode);
+ if (success)
+ {
+ status = dmosSuccess;
+ }
+ else
+ {
+ status = dmosFailedToResetSw;
+ }
+ m_connectedDevices[deviceName]->m_mutex.unlock();
+ return status;
+ }
+ else
+ {
+ m_connectedDevicesMutex.unlock();
+ return dmosNoSuchConnectedDevice;
+ }
+}
+
+DeviceManagerOperationStatus DeviceManager::AllocPmc(string deviceName, unsigned descSize, unsigned descNum)
+{
+ DeviceManagerOperationStatus status;
+ m_connectedDevicesMutex.lock();
+ if (m_connectedDevices.count(deviceName) > 0)
+ {
+ m_connectedDevices[deviceName]->m_mutex.lock();
+ m_connectedDevicesMutex.unlock();
+ bool success = m_connectedDevices[deviceName]->m_device->AllocPmc(descSize, descNum);
+ if (success)
+ {
+ status = dmosSuccess;
+ }
+ else
+ {
+ status = dmosFailedToAllocatePmc;
+ }
+ m_connectedDevices[deviceName]->m_mutex.unlock();
+ return status;
+ }
+ else
+ {
+ m_connectedDevicesMutex.unlock();
+ return dmosNoSuchConnectedDevice;
+ }
+}
+
+DeviceManagerOperationStatus DeviceManager::DeallocPmc(string deviceName)
+{
+ DeviceManagerOperationStatus status;
+ m_connectedDevicesMutex.lock();
+ if (m_connectedDevices.count(deviceName) > 0)
+ {
+ m_connectedDevices[deviceName]->m_mutex.lock();
+ m_connectedDevicesMutex.unlock();
+ bool success = m_connectedDevices[deviceName]->m_device->DeallocPmc();
+ if (success)
+ {
+ status = dmosSuccess;
+ }
+ else
+ {
+ status = dmosFailedToDeallocatePmc;
+ }
+ m_connectedDevices[deviceName]->m_mutex.unlock();
+ return status;
+ }
+ else
+ {
+ m_connectedDevicesMutex.unlock();
+ return dmosNoSuchConnectedDevice;
+ }
+}
+
+DeviceManagerOperationStatus DeviceManager::CreatePmcFile(string deviceName, unsigned refNumber)
+{
+ DeviceManagerOperationStatus status;
+ m_connectedDevicesMutex.lock();
+ if (m_connectedDevices.count(deviceName) > 0)
+ {
+ m_connectedDevices[deviceName]->m_mutex.lock();
+ m_connectedDevicesMutex.unlock();
+ bool success = m_connectedDevices[deviceName]->m_device->CreatePmcFile(refNumber);
+ if (success)
+ {
+ status = dmosSuccess;
+ }
+ else
+ {
+ status = dmosFailedToCreatePmcFile;
+ }
+ m_connectedDevices[deviceName]->m_mutex.unlock();
+ return status;
+ }
+ else
+ {
+ m_connectedDevicesMutex.unlock();
+ return dmosNoSuchConnectedDevice;
+ }
+}
+
+DeviceManagerOperationStatus DeviceManager::SendWmi(string deviceName, DWORD command, const vector<DWORD>& payload)
+{
+ DeviceManagerOperationStatus status;
+ m_connectedDevicesMutex.lock();
+ if (m_connectedDevices.count(deviceName) > 0)
+ {
+ m_connectedDevices[deviceName]->m_mutex.lock();
+ m_connectedDevicesMutex.unlock();
+ bool success = m_connectedDevices[deviceName]->m_device->SendWmi(command, payload);
+ if (success)
+ {
+ status = dmosSuccess;
+ }
+ else
+ {
+ status = dmosFailedToSendWmi;
+ }
+ m_connectedDevices[deviceName]->m_mutex.unlock();
+ return status;
+ }
+ else
+ {
+ m_connectedDevicesMutex.unlock();
+ return dmosNoSuchConnectedDevice;
+ }
+}
+
+void DeviceManager::CreateDevice(string deviceName)
+{
+ m_connectedDevicesMutex.lock();
+ shared_ptr<ConnectedDevice> connectedDevice(new ConnectedDevice(AccessLayer::OpenDevice(deviceName)));
+ m_connectedDevices.insert(make_pair(deviceName, connectedDevice));
+ m_connectedDevicesMutex.unlock();
+}
+
+void DeviceManager::DeleteDevice(string deviceName)
+{
+ m_connectedDevicesMutex.lock();
+ // make sure that no client is using this object
+ m_connectedDevices[deviceName]->m_mutex.lock();
+ // no need that the mutex will be still locked since new clients have to get m_connectedDevicesMutex before they try to get m_mutex
+ m_connectedDevices[deviceName]->m_mutex.unlock();
+ AccessLayer::CloseDevice(deviceName);
+ m_connectedDevices.erase(deviceName);
+ m_connectedDevicesMutex.unlock();
+}
+
+void DeviceManager::UpdateConnectedDevices()
+{
+ set<string> currentlyConnectedDevices = AccessLayer::GetDevices();
+
+ // delete devices that arn't connected anymore
+ vector<string> devicesForRemove;
+ for (auto& connectedDevice : m_connectedDevices)
+ {
+ if (0 == currentlyConnectedDevices.count(connectedDevice.first))
+ {
+ devicesForRemove.push_back(connectedDevice.first);
+ }
+ }
+ for (auto& device : devicesForRemove)
+ {
+ DeleteDevice(device);
+ }
+
+ // add new connected devices
+ vector<string> newDevices;
+ for (auto& currentlyConnectedDevice : currentlyConnectedDevices)
+ {
+ if (0 == m_connectedDevices.count(currentlyConnectedDevice))
+ {
+ newDevices.push_back(currentlyConnectedDevice);
+ }
+ }
+ for (auto& device : newDevices)
+ {
+ CreateDevice(device);
+ }
+}
+
+void DeviceManager::PeriodicTasks()
+{
+ while (!m_terminate)
+ {
+ UpdateConnectedDevices();
+ for (auto& connectedDevice : m_connectedDevices)
+ {
+ connectedDevice.second->m_mutex.lock();
+ connectedDevice.second->m_device->Poll();
+ connectedDevice.second->m_mutex.unlock();
+ }
+ this_thread::sleep_for(std::chrono::milliseconds(m_deviceManagerRestDurationMs));
+ }
+}
\ No newline at end of file
diff --git a/debug-tools/host_manager_11ad/DeviceManager.h b/debug-tools/host_manager_11ad/DeviceManager.h
new file mode 100644
index 0000000..6cd8596
--- /dev/null
+++ b/debug-tools/host_manager_11ad/DeviceManager.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _DEVICEMANAGER_H_
+#define _DEVICEMANAGER_H_
+
+#include <string>
+#include <set>
+#include <unordered_map>
+#include <unordered_set>
+#include <thread>
+#include <mutex>
+#include <atomic>
+
+#include "HostDefinitions.h"
+#include "Device.h"
+
+using namespace std;
+
+struct ConnectedDevice
+{
+ ConnectedDevice(unique_ptr<Device> device) :
+ m_device(move(device))
+ { }
+
+ shared_ptr<Device> m_device;
+ mutex m_mutex;
+};
+
+enum DeviceManagerOperationStatus
+{
+ dmosSuccess,
+ dmosNoSuchConnectedDevice, // the given device name is not part of m_conncectedDevices
+ dmosFailedToReadFromDevice,
+ dmosFailedToWriteToDevice,
+ dmosFailedToResetInterface,
+ dmosFailedToResetSw,
+ dmosFailedToAllocatePmc,
+ dmosFailedToDeallocatePmc,
+ dmosFailedToCreatePmcFile,
+ dmosFailedToSendWmi,
+ dmosInvalidAddress,
+ dmosFail // general failure. try to avoid using it
+};
+
+class DeviceManager
+{
+public:
+ DeviceManager();
+ ~DeviceManager();
+ string GetDeviceManagerOperationStatusString(DeviceManagerOperationStatus status);
+
+ DeviceManagerOperationStatus GetDevices(set<string>&);
+ DeviceManagerOperationStatus Read(string deviceName, DWORD address, DWORD& value);
+ DeviceManagerOperationStatus Write(string deviceName, DWORD address, DWORD value);
+ DeviceManagerOperationStatus ReadBlock(string deviceName, DWORD address, DWORD blockSize, vector<DWORD>& values);
+ DeviceManagerOperationStatus WriteBlock(string deviceName, DWORD address, const vector<DWORD>& values);
+ DeviceManagerOperationStatus InterfaceReset(string deviceName);
+ DeviceManagerOperationStatus SwReset(string deviceName);
+ DeviceManagerOperationStatus AllocPmc(string deviceName, unsigned descSize, unsigned descNum);
+ DeviceManagerOperationStatus DeallocPmc(string deviceName);
+ DeviceManagerOperationStatus CreatePmcFile(string deviceName, unsigned refNumber);
+ DeviceManagerOperationStatus SendWmi(string deviceName, DWORD command, const vector<DWORD>& payload);
+ DeviceManagerOperationStatus OpenInterface(string deviceName); // for backward compatibility
+ DeviceManagerOperationStatus CloseInterface(string deviceName);
+ DeviceManagerOperationStatus SetDriverMode(string deviceName, int newMode, int& oldMode);
+
+private:
+ void PeriodicTasks();
+ void UpdateConnectedDevices();
+ void CreateDevice(string deviceName);
+ void DeleteDevice(string deviceName);
+
+ unordered_map<string, shared_ptr<ConnectedDevice>> m_connectedDevices; // map from unique string (unique inside a host) to a connected device
+ unsigned const m_deviceManagerRestDurationMs;
+ thread m_deviceManager;
+ mutex m_connectedDevicesMutex;
+ atomic<bool> m_terminate;
+};
+
+#endif // !_DEVICEMANAGER_H_
diff --git a/debug-tools/host_manager_11ad/EventsTcpServer.cpp b/debug-tools/host_manager_11ad/EventsTcpServer.cpp
new file mode 100644
index 0000000..6bed5ce
--- /dev/null
+++ b/debug-tools/host_manager_11ad/EventsTcpServer.cpp
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "EventsTcpServer.h"
+
+EventsTcpServer::EventsTcpServer(unsigned int eventsTcpPort)
+ :m_port(eventsTcpPort), m_pSocket(new NetworkInterfaces::NetworkInterface())
+{
+}
+
+void EventsTcpServer::Start()
+{
+ LOG_INFO << "Starting events TCP server on port " << m_port << endl;
+ m_pSocket->Bind(m_port);
+ m_pSocket->Listen();
+
+ //Infinite loop because it has to wait for clients to connect to it forever, there's no reason to stop it
+ //unless there is a problem.
+ while (true)
+ {
+ try
+ {
+ NetworkInterfaces::NetworkInterface newClient = m_pSocket->Accept();
+ //LOG_INFO << "Adding a new client to the Events TCP Server: " << newClient.getPeerName() << endl;
+ //using unique_lock promises that in case of exception the mutex is unlocked:
+ unique_lock<mutex> clientsVectorLock(clientsVectorMutex);
+ clientsVector.push_back(newClient);
+ clientsVectorLock.unlock();
+ }
+ catch (exception e)
+ {
+ LOG_ERROR << "Couldn't start a new connection with a new client on events TCP server" << e.what() << endl;
+ }
+ }
+}
+
+bool EventsTcpServer::SendToAllConnectedClients(string message)
+{
+ try
+ {
+ //using unique_lock promises that in case of exception the mutex is unlocked:
+ unique_lock<mutex> clientsVectorLock(clientsVectorMutex); //locks the mutex in for loop because it iterates on clientsVector
+ for (auto client = clientsVector.begin(); client != clientsVector.end(); )
+ {
+ try
+ {
+ int bytesSent = (*client).Send(message);
+ if (bytesSent == 0)
+ { //it means the client had disconnected, remove the client from the clients list
+ LOG_WARNING << "Client: " << (*client).GetPeerName() << " has disconnected, removing from the clients list" << endl;
+ client = clientsVector.erase(client);
+ }
+ else
+ {
+ ++client;
+ }
+ }
+ catch (exception e)
+ {
+ string peerName = "Unknown client";
+ if (client != clientsVector.end())
+ {
+ peerName = (*client).GetPeerName();
+ }
+ LOG_WARNING << "Couldn't send the event to the client: " << peerName << " " << e.what() << endl;
+
+ }
+ }
+ clientsVectorLock.unlock(); //unlock the mutex on the for loop
+ }
+ catch (exception e)
+ {
+ LOG_WARNING << "Couldn't send the event to all the clients" << e.what() << endl;
+ return false;
+ }
+
+ return true;
+}
+
+void EventsTcpServer::Stop()
+{
+ LOG_INFO << "Stopping the events TCP server" << endl;
+ m_pSocket->Shutdown(2); //type 2 -> Acts like the close(), shutting down both input and output
+}
diff --git a/debug-tools/host_manager_11ad/EventsTcpServer.h b/debug-tools/host_manager_11ad/EventsTcpServer.h
new file mode 100644
index 0000000..9527cee
--- /dev/null
+++ b/debug-tools/host_manager_11ad/EventsTcpServer.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _EVENTSTCPSERVER_H_
+#define _EVENTSTCPSERVER_H_
+
+#include "NetworkInterface.h"
+#include <memory>
+#include <mutex>
+#include "HostDefinitions.h"
+#include "CommandsHandler.h"
+
+/*
+ *TODO - add a function to the events TCP server: when some client connects to the host server, the host server informs every client
+ *(include the one that just connected) that another client had connected to the host
+ */
+
+/*
+* Events TCP server is a asynchronous server that broadcasts events that come from the device or the host to all connected clients.
+* If a client wants to get events he has to connect this server (separately from the Commands TCP server).
+* This server doesn't get any messages from clients.
+*/
+class EventsTcpServer
+{
+public:
+ /*
+ * Events TCP server constructor gets the port to start in. It also initializes new Socket object.
+ */
+ EventsTcpServer(unsigned int eventsTcpPort);
+
+ /*
+ * Start the events TCP server at the given port (given in the constructor).
+ * For each new client that is connecting to the server, it adds it to a clients list.
+ */
+ void Start();
+
+ /*
+ * Send an event to all registered clients (clients that exist in the list).
+ * If the connection is lost, remove the client from the list (it is the client's responsibility
+ * to renew the connection with this server).
+ */
+ bool SendToAllConnectedClients(string message);
+
+ /*
+ * Stop the events TCP server by doing some clean ups for the sockets.
+ */
+ void Stop();
+
+private:
+ unsigned int m_port; //The port in which the events TCP server is working on
+ shared_ptr<NetworkInterfaces::NetworkInterface> m_pSocket;
+ // clientsVector is a vector that keeps all the clients that are connected to the server and want to get events from the device or the host
+ vector<NetworkInterfaces::NetworkInterface> clientsVector;
+ mutex clientsVectorMutex; //Two different (or more) threads can access the clients vector - a mutex is needed
+
+};
+
+
+
+#endif // !_EVENTSTCPSERVER_H_
diff --git a/debug-tools/host_manager_11ad/FileReader.cpp b/debug-tools/host_manager_11ad/FileReader.cpp
new file mode 100644
index 0000000..a5cc951
--- /dev/null
+++ b/debug-tools/host_manager_11ad/FileReader.cpp
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "FileReader.h"
+//#include "DebugLogger.h"
+
+#include <cstring>
+#include <cerrno>
+#include <stdio.h>
+
+// *************************************************************************************************
+
+FileReader::FileReader(const char* pFileName)
+ : m_FileName(pFileName)
+ , m_pFile(NULL)
+ , m_FileSize(0)
+ , m_ReadTillNow(0)
+ , m_IsCompleted(false)
+ , m_IsError(false)
+{
+ if (NULL == pFileName)
+ {
+ //LOG_ERROR << "No file name provided" << std::endl;
+ return;
+ }
+
+ //LOG_DEBUG << "Opening file reader for: " << m_FileName << std::endl;
+ m_pFile = fopen(pFileName, "rb");
+
+ if (NULL == m_pFile)
+ {
+ //int lastErrno = errno;
+ //LOG_ERROR << "Error opening file."
+ //<< " Name: " << pFileName
+ //<< " Error: " << lastErrno
+ //<< " Message: " << strerror(lastErrno)
+ //<< std::endl;
+ return;
+ }
+
+ fseek(m_pFile, 0, SEEK_END);
+ m_FileSize = ftell(m_pFile);
+ rewind(m_pFile);
+
+ //LOG_DEBUG << "Get file size for " << pFileName << ": " << m_FileSize << "B" << std::endl;
+}
+
+// *************************************************************************************************
+
+FileReader::~FileReader()
+{
+ if (m_pFile)
+ {
+ //LOG_DEBUG << "Closing the file: " << m_FileName << std::endl;
+ fclose(m_pFile);
+ m_pFile = NULL;
+ }
+}
+
+// *************************************************************************************************
+
+bool FileReader::CanReadFromFile(char* pBuf, size_t availableSpace)
+{
+ if (!pBuf)
+ {
+ //LOG_ERROR << "Cannot read from file " << m_FileName << ": "
+ //<< "No buffer is provided" << std::endl;
+ return false;
+ }
+
+ if (0 == availableSpace)
+ {
+ //LOG_ERROR << "Cannot read from file " << m_FileName << ": "
+ //<< "No buffer space is provided" << std::endl;
+ return false;
+ }
+
+ if (NULL == m_pFile)
+ {
+ //LOG_ERROR << "Cannot read from file " << m_FileName << ": "
+ //<< "No file handle is available" << std::endl;
+ return false;
+ }
+
+ if (m_IsCompleted)
+ {
+ //LOG_ERROR << "Unexpected read from file " << m_FileName << ": "
+ //<< "EoF is reached" << std::endl;
+ return false;
+ }
+
+ if (m_IsError)
+ {
+ //LOG_ERROR << "Unexpected read from file " << m_FileName << ": "
+ //<< "Error occured" << std::endl;
+ return false;
+ }
+
+ return true;
+
+}
+
+// *************************************************************************************************
+
+size_t FileReader::ReadChunk(char* pBuf, size_t availableSpace)
+{
+ //LOG_DEBUG << "Reading a chunk."
+ //<< " File Name: " << m_FileName
+ //<< " File Size: " << m_FileSize << "B"
+ //<< " Read till now: " << m_ReadTillNow << "B"
+ //<< " Buffer: " << availableSpace << "B"
+ //<< " Completed: " << BoolStr(m_IsCompleted)
+ //<< " Error: " << BoolStr(m_IsError)
+ //<< std::endl;
+
+ if (false == CanReadFromFile(pBuf, availableSpace))
+ {
+ //LOG_ERROR << "Cannot read from file: " << m_FileName
+ //<< " Check previous errors/status" << std::endl;
+ m_IsError = true;
+ return 0;
+ }
+
+ // Read up to availableSpace. Reading less means either EoF is reached or read error occured
+ size_t readBytes = fread(pBuf, 1, availableSpace, m_pFile);
+ m_ReadTillNow += readBytes;
+
+ if (feof(m_pFile))
+ {
+ //LOG_DEBUG << "EOF reached" << std::endl;
+ m_IsCompleted = true;
+ }
+
+ if (ferror(m_pFile))
+ {
+ //int lastErrno = errno;
+ m_IsError = true;
+ //LOG_ERROR << "Cannot read file"
+ //<< " Name: " << m_FileName
+ //<< " Error: " << lastErrno
+ //<< " Message:" << strerror(lastErrno)
+ //<< std::endl;
+ }
+
+ //LOG_VERBOSE << "Got a chunk."
+ //<< " File Name: " << m_FileName
+ //<< " File Size: " << m_FileSize << "B"
+ //<< " Read till now: " << m_ReadTillNow << "B"
+ //<< " Buffer: " << availableSpace << "B"
+ //<< " Completed: " << BoolStr(m_IsCompleted)
+ //<< " Error: " << BoolStr(m_IsError)
+ //<< std::endl;
+
+ return readBytes;
+
+}
diff --git a/debug-tools/host_manager_11ad/FileReader.h b/debug-tools/host_manager_11ad/FileReader.h
new file mode 100644
index 0000000..2b7b12f
--- /dev/null
+++ b/debug-tools/host_manager_11ad/FileReader.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _FILE_READER_H_
+#define _FILE_READER_H_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string>
+
+// *************************************************************************************************
+
+// Reads a file from the file system and exports its content to a buffer provided by the caller.
+// If the file is larger than a provide bugffer, it is delivered by chunks of the buffer size.
+// The last chunk may occupy less than the whole buffer. It's a caller's responsibility to allocate
+// the buffer and call the FileReader API untill the file is fully exported.
+
+class FileReader
+{
+public:
+
+ explicit FileReader(const char* pFileName);
+ ~FileReader();
+
+ size_t ReadChunk(char* pBuf, size_t availableSpace);
+
+ bool IsCompleted() const { return m_ReadTillNow == m_FileSize; }
+ bool IsError() const { return m_IsError; }
+
+ size_t ReadTillNow() const { return m_ReadTillNow; }
+ size_t GetFileSize() const { return m_FileSize; }
+
+private:
+
+ bool CanReadFromFile(char* pBuf, size_t availableSpace);
+
+ const std::string m_FileName; // File name - cached for tracing
+ FILE* m_pFile; // File Handler - open for read
+ size_t m_FileSize; // File Size
+ size_t m_ReadTillNow; // Bytes read till now
+ bool m_IsCompleted; // Set to true when OEF is reached
+ bool m_IsError; // Error flag
+
+};
+
+
+#endif // _FILE_READER_H_
diff --git a/debug-tools/host_manager_11ad/Host.cpp b/debug-tools/host_manager_11ad/Host.cpp
new file mode 100644
index 0000000..46a9450
--- /dev/null
+++ b/debug-tools/host_manager_11ad/Host.cpp
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "Host.h"
+#include "DebugLogger.h"
+#include <iostream>
+#include <thread>
+#include <functional> //Included for the "ref" in events TCP server thread
+#include "Utils.h"
+
+using namespace std;
+
+void Host::StartHost(unsigned int commandsTcpPort, unsigned int eventsTcpPort, unsigned int udpPortIn, unsigned int udpPortOut)
+{
+ m_pCommandsTcpServer.reset(new CommandsTcpServer(commandsTcpPort, *this));
+
+ if (!m_pCommandsTcpServer)
+ { //m_pCommandsTcpServer is NULL, couldn't set Socket
+ LOG_ERROR << "Couldn't set new socket for the commands TCP server" << endl;
+ throw "Couldn't set new socket for the commands TCP server";
+ }
+ thread threadCommandsTcpServer;
+ try
+ {
+ //threadCommandsTcpServer = thread(&CommandsTcpServer::Start, m_pCommandsTcpServer);
+ threadCommandsTcpServer = thread(&CommandsTcpServer::Start, m_pCommandsTcpServer.get());
+ }
+ catch (exception e)
+ {
+ LOG_ERROR << "Couldn't start commands TCP server" << endl;
+ throw "Couldn't start commands TCP server";
+ }
+
+ m_pEventsTcpServer.reset(new EventsTcpServer(eventsTcpPort));
+
+ if (!m_pEventsTcpServer)
+ { //m_pEventsTcpServer is NULL, couldn't set Socket
+ LOG_ERROR << "Couldn't set new socket for the events TCP server" << endl;
+ throw "Couldn't set new socket for the events TCP server";
+ }
+
+ thread threadEventsTcpServer;
+ try
+ {
+ //threadEventsTcpServer = thread(&EventsTcpServer::Start, m_pEventsTcpServer);
+ threadEventsTcpServer = thread(&EventsTcpServer::Start, m_pEventsTcpServer.get());
+ }
+ catch (exception e)
+ {
+ LOG_ERROR << "Couldn't start events TCP server" << endl;
+ throw "Couldn't start commands TCP server";
+ }
+
+ LOG_INFO << "Starting UDP server at port in: " << udpPortIn << ", and port out: " << udpPortOut << endl;
+
+ m_pUdpServer.reset(new UdpServer(udpPortIn, udpPortOut, *this));
+ if (!m_pUdpServer)
+ { //m_pUdpServer is NULL, couldn't set Socket
+ LOG_ERROR << "Couldn't set new socket for the UDP server" << endl;
+ throw "Couldn't set new socket for the UDP server";
+ }
+
+ thread threadUdpServer;
+ try
+ {
+ threadUdpServer = thread(&UdpServer::StartServer, m_pUdpServer);
+ }
+ catch (exception e)
+ {
+ LOG_ERROR << "Couldn't start UDP server thread" << e.what() << endl;
+ throw "Couldn't start UDP server thread";
+ }
+
+ threadCommandsTcpServer.join();
+ threadEventsTcpServer.join();
+ threadUdpServer.join();
+
+}
+
+void Host::StopHost()
+{
+ m_pCommandsTcpServer->Stop();
+ m_pEventsTcpServer->Stop();
+ m_pUdpServer->Stop();
+}
diff --git a/debug-tools/host_manager_11ad/Host.h b/debug-tools/host_manager_11ad/Host.h
new file mode 100644
index 0000000..e899259
--- /dev/null
+++ b/debug-tools/host_manager_11ad/Host.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _HOST_H_
+#define _HOST_H_
+
+//#include "Server.h"
+#include "CommandsTcpServer.h"
+#include "EventsTcpServer.h"
+#include "CommandsHandler.h"
+#include "UdpServer.h"
+#include "HostInfo.h"
+#include "DeviceManager.h"
+
+/*
+ * Host is a class that holds the TCP and UDP server.
+ * It also holds the Device Manager.
+ */
+class Host
+{
+public:
+
+ /*
+ * Host is s singletone due to HandleOsSignals - signal is a global function that can't get a pointer to the host as an argument
+ */
+ static Host& GetHost()
+ {
+ static Host host;
+ return host;
+ }
+
+
+ /*
+ * StratHost starts each one of the servers it holds
+ */
+ void StartHost(unsigned int commandsTcpPort, unsigned int eventsTcpPort, unsigned int udpPortIn, unsigned int udpPortOut);
+
+ /*
+ * StopHost stops each one of the servers it holds
+ */
+ void StopHost();
+
+ HostInfo& GetHostInfo() { return m_hostInfo; }
+
+ DeviceManager& GetDeviceManager() { return m_deviceManager; }
+
+
+private:
+ shared_ptr<CommandsTcpServer> m_pCommandsTcpServer;
+ shared_ptr<EventsTcpServer> m_pEventsTcpServer;
+ shared_ptr<UdpServer> m_pUdpServer;
+ HostInfo m_hostInfo;
+ DeviceManager m_deviceManager;
+};
+
+
+#endif // ! _HOST_H_
diff --git a/debug-tools/host_manager_11ad/HostDefinitions.h b/debug-tools/host_manager_11ad/HostDefinitions.h
new file mode 100644
index 0000000..1db346a
--- /dev/null
+++ b/debug-tools/host_manager_11ad/HostDefinitions.h
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _DEFINITIONS_H_
+#define _DEFINITIONS_H_
+
+#include <string>
+#include <cstdint>
+#include "Utils.h"
+
+
+// *************************************************************************************************
+/*
+ * The reply data may be generated in several ways, the data is expected to be obtained according to this type
+ */
+enum REPLY_TYPE
+{
+ REPLY_TYPE_NONE,
+ REPLY_TYPE_BUFFER,
+ REPLY_TYPE_FILE
+};
+
+// *************************************************************************************************
+/*
+ * A response to the client, through the servers
+ */
+typedef struct
+{
+ std::string message;
+ REPLY_TYPE type;
+ unsigned int length;
+} ResponseMessage;
+
+// *************************************************************************************************
+/*
+ * ConnectionStatus indicates whether to close a connection with a client or not.
+ */
+enum ConnectionStatus
+{
+ CLOSE_CONNECTION,
+ KEEP_CONNECTION_ALIVE
+};
+
+// **************************** Events Structures and Enum Types **************************************
+/*
+ * Define an event struct which would be sent as bytes in packed mode.
+ * The concept is to send the smallest message we can as it being sent many times and to multiple clients.
+ * NOTE that the __exactly__ same struct is defined in the side that gets this struct.
+ * The structures sent in packed mode (by using "#pragma pack(push, 1)")
+ */
+
+#pragma pack(push, 1) //following structures would be in packed mode
+
+enum HOST_EVENT_TYPE : uint8_t
+{
+ VERSION_CHANGED,
+ CONNECTED_USERS_CHANGED,
+ DEVICES_LIST_CHANGED,
+ DEVICE_EVENT
+};
+
+struct HostEvent
+{
+ HostEvent(HOST_EVENT_TYPE hostEventType) :
+ m_marker("TheUtopicHostManager11ad"),
+ m_currentTime(Utils::GetCurrentLocalTime()),
+ m_eventType(hostEventType)
+ { }
+
+ const string m_marker; // for stream synchronization in DmTools
+ string m_currentTime; // event's genaration time, in YYYY-MM-DD HH:mm:ss.<ms><ms><ms> format
+ HOST_EVENT_TYPE m_eventType; //Value size is uint8_t
+ uint32_t m_payloadSize;
+ uint8_t *payLoad; //The size of the payload (which is the raw data from the device) is given in "payloadSize"
+};
+
+//The type of the event coming from the device - as the device aware of it
+enum DEVICE_EVENT_TYPE : uint8_t
+{
+ WMI_EVENT,
+ LOG_EVENT,
+ POLLER_EVENT
+};
+
+typedef enum _DRIVER_MODE {
+ IOCTL_WBE_MODE,
+ IOCTL_WIFI_STA_MODE,
+ IOCTL_WIFI_SOFTAP_MODE,
+ IOCTL_CONCURRENT_MODE, // This mode is for a full concurrent implementation (not required mode switch between WBE/WIFI/SOFTAP)
+ IOCTL_SAFE_MODE, // A safe mode required for driver for protected flows like upgrade and crash dump...
+} DRIVER_MODE;
+
+struct DeviceEvent : public HostEvent
+{
+ DeviceEvent(DEVICE_EVENT_TYPE deviceEventType) :
+ HostEvent(DEVICE_EVENT),
+ m_deviceEventType(deviceEventType)
+ {}
+
+ DEVICE_EVENT_TYPE m_deviceEventType; //This value size is uint8_t
+ uint16_t m_deviceNameSize; //This value would be sent with the package
+ uint8_t* m_deviceName; //The size of the device name is in "deviceNameSize"
+ uint32_t m_payloadSize;
+ uint8_t* m_payLoad; //The size of the payload (which is the raw data from the device) is given in "payloadSize"
+};
+
+
+//Example for another host event
+//typedef struct _DevicesChangedEvent : HostEvent
+//{
+//
+//} DevicesChangedEvent;
+
+#pragma pack(pop) //stop using packed mode
+
+// *************************************************************************************************
+
+#define MAX_REGS_LEN (256* 1024) // Max registers to read/write at once //TODO - is it needed? maybe read until line terminator?
+
+// Max buffer size for a command and a reply. We should consider the longest command/data sequence to fit in a buffer.
+// rb reading 1024 (MAX_REGS_LEN) registers: rb HHHHHHHH HHHH 1024*(0xHHHHHHHH) = 17 + 1024*10 = 10257 bytes
+// wb writing 1024 (MAX_REGS_LEN) hex values: wb HHHHHHHH "1024*HH" = 14+1024*2 = 2062 bytes
+#define MAX_INPUT_BUF (11*MAX_REGS_LEN) //TODO - is it needed? maybe read until line terminator?
+
+// *************************************************************************************************
+
+struct HostIps
+{
+ HostIps() :
+ m_ip(""),
+ m_broadcastIp("")
+ {}
+
+ std::string m_ip; // host's IP address
+ std::string m_broadcastIp; // host's broadcast IP address (derivated by subnet mask)
+};
+
+// *************************************************************************************************
+
+enum ServerType
+{
+ stTcp,
+ stUdp
+};
+
+#endif // !_DEFINITIONS_H_
diff --git a/debug-tools/host_manager_11ad/HostInfo.cpp b/debug-tools/host_manager_11ad/HostInfo.cpp
new file mode 100644
index 0000000..735ce31
--- /dev/null
+++ b/debug-tools/host_manager_11ad/HostInfo.cpp
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "HostInfo.h"
+#include "DebugLogger.h"
+#include "UdpTempOsAbstruction.h"
+#include <iostream>
+
+HostInfo::HostInfo() :
+ m_alias(""),
+ m_persistencyPath(UdpTempOsAbstruction::GetPersistencyLocation() + "host_manager_11ad"),
+ m_aliasFileName(UdpTempOsAbstruction::GetDirectoriesDilimeter() + "host_alias"),
+ m_oldHostAliasFile(UdpTempOsAbstruction::GetPersistencyLocation() + "wigig_remoteserver_details"),
+ m_isAliasFileChanged(false)
+{
+ LoadHostInfo();
+}
+
+const HostIps& HostInfo::GetIps()
+{
+ return m_ips;
+}
+
+string HostInfo::GetAlias()
+{
+ if (m_isAliasFileChanged)
+ {
+ UpdateAliasFromFile();
+ }
+ return m_alias;
+}
+
+bool HostInfo::SaveAliasToFile(string newAlias)
+{
+ m_persistencyLock.lock();
+ if (!UdpTempOsAbstruction::WriteFile(m_persistencyPath + m_aliasFileName, newAlias))
+ {
+ LOG_WARNING << "Failed to write new alias to configuration file " << m_persistencyPath << m_aliasFileName << endl;
+ return false;
+ }
+ m_isAliasFileChanged = true;
+ m_persistencyLock.unlock();
+ return true;
+}
+
+bool HostInfo::UpdateAliasFromFile()
+{
+ m_persistencyLock.lock();
+ if (!UdpTempOsAbstruction::ReadFile(m_persistencyPath + m_aliasFileName, m_alias))
+ {
+ LOG_WARNING << "Failed to write new alias to configuration file " << m_persistencyPath << m_aliasFileName << endl;
+ return false;
+ }
+ m_isAliasFileChanged = false;
+ m_persistencyLock.unlock();
+ return true;
+}
+
+
+//void HostInfo::LoadHostInfo()
+//{
+// m_ips = UdpTempOsAbstruction::GetHostIps();
+//
+// bool res = UdpTempOsAbstruction::ReadFile(m_persistencyPath, m_alias);
+// if (!res) // file doesn't exist
+// {
+// /*
+// res = UdpTempOsAbstruction::CreateFile(m_persistencyPath)
+// if (!res)
+// {
+// cout << "Failed to create persistency file" << endl;
+// m_alias = "";
+// return;
+// }
+// */
+// res = UdpTempOsAbstruction::ReadHostOsAlias(m_alias);
+// if (!res)
+// {
+// cout << "Failed to read OS host name" << endl;
+// m_alias = "";
+// }
+// res = UdpTempOsAbstruction::WriteFile(m_persistencyPath, m_alias);
+// if (!res)
+// {
+// cout << "Failed to write host alias to persistency" << endl;
+// }
+// }
+//}
+
+void HostInfo::LoadHostInfo()
+{
+ m_ips = UdpTempOsAbstruction::GetHostIps();
+
+ // create host manager directory if doesn't exist
+ bool res = UdpTempOsAbstruction::IsFolderExists(m_persistencyPath);
+ if (!res)
+ {
+ res = UdpTempOsAbstruction::CreateFolder(m_persistencyPath);
+ if (!res)
+ {
+ LOG_WARNING << "Failed to create " << m_persistencyPath << " directory" << endl;
+ return;
+ }
+ // backward compatibility - copy the alias that the user already given to its new place
+ if (UdpTempOsAbstruction::IsFileExists(m_oldHostAliasFile))
+ {
+ UdpTempOsAbstruction::MoveFileToNewLocation(m_oldHostAliasFile, m_persistencyPath + m_aliasFileName);
+ }
+ }
+
+ res = UdpTempOsAbstruction::ReadFile(m_persistencyPath + m_aliasFileName, m_alias);
+ if (!res) // file doesn't exist
+ {
+ res = UdpTempOsAbstruction::ReadHostOsAlias(m_alias);
+ if (!res)
+ {
+ LOG_WARNING << "Failed to read OS host name" << endl;
+ m_alias = "";
+ }
+ res = UdpTempOsAbstruction::WriteFile(m_persistencyPath + m_aliasFileName, m_alias);
+ if (!res)
+ {
+ LOG_WARNING << "Failed to write host alias to persistency" << endl;
+ }
+ }
+}
diff --git a/debug-tools/host_manager_11ad/HostInfo.h b/debug-tools/host_manager_11ad/HostInfo.h
new file mode 100644
index 0000000..98acbe5
--- /dev/null
+++ b/debug-tools/host_manager_11ad/HostInfo.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _HOSTINFO_H_
+#define _HOSTINFO_H_
+
+#include <string>
+#include <memory>
+#include <atomic>
+#include <mutex>
+#include <set>
+
+#include "HostDefinitions.h"
+
+using namespace std;
+
+class HostInfo
+{
+
+public:
+
+ /*
+ HostInfo
+ Initializes all hostInfo members (ips and alias)
+ */
+ HostInfo();
+
+ /*
+ GetIps
+ Returns host's Ips (private and broadcast)
+ @param: none
+ @return: host's ips
+ */
+ const HostIps& GetIps();
+
+ /*
+ GetHostAlias
+ Returns host's alias (if one was given by the user)
+ @param: none
+ @return: host's alias if exists, otherwise empty string
+ */
+ string GetAlias();
+
+ /*
+ SaveAliasToFile
+ Gets a new alias for the host and saves it to a configuration file.
+ This function is called from CommandsTcpServer only. It turns on a flag so that the UDP server (that is on a different thread) will check for the new alias
+ @param: string - the new alias
+ @return: bool - operation status - true for success, false otherwise
+ */
+ bool SaveAliasToFile(string newAlias);
+
+ /*
+ UpdateAliasFromFile
+ Updates the m_alias member with the host's alias from 11ad's persistency
+ @param: none
+ @return: bool - operation status - true for success, false otherwise
+ */
+ bool UpdateAliasFromFile();
+
+ /*
+ GetConnectedUsers
+ Returns a set of all the users that are connected to this host
+ @param: none
+ @return: set<string> of all connected users
+ */
+ const set<string>& GetConnectedUsers() { return m_connectedUsers; }
+
+ /*
+ AddNewConnectedUser
+ Adds a user to the connected user's list
+ @param: string - a new user (currently the user's DmTools's IP. TODO: change to the user's personal host's name or user's DmTools username)
+ @return: none
+ */
+ void AddNewConnectedUser(string user) { m_connectedUsers.insert(user); }
+
+ /*
+ RemoveConnectedUser
+ Removes a user from the connected user's list
+ @param: string - a user (currently the user's DmTools's IP. TODO: change to the user's personal host's name or user's DmTools username)
+ @return: none
+ */
+ void RemoveNewConnectedUser(string user) { m_connectedUsers.erase(user); }
+
+ string GetVersion() { return m_version; }
+
+
+private:
+ HostIps m_ips; // host's network details // assumption: each host has only one IP address for ethernet interfaces
+ string m_alias; // host's alias (given by user)
+ const string m_persistencyPath; // host server's files location
+ const string m_aliasFileName; // host's alias file
+ const string m_oldHostAliasFile; // old location of the host alias
+ set<string> m_connectedUsers; // list of users IPs that have a connection to the commandsTcpServer // TODO: change to the user's personal host's name or user's DmTools username
+ string m_version; // host_manager_11ad version // TODO: update m_version
+ atomic<bool> m_isAliasFileChanged; // when turned on indicates that m_alias contains stale information, so we need to update it from persistency
+ mutex m_persistencyLock; // only one thread is allowed to change persistency at a time
+
+ // load host's info from persistency and ioctls
+ void LoadHostInfo();
+};
+
+
+#endif
\ No newline at end of file
diff --git a/debug-tools/host_manager_11ad/Makefile b/debug-tools/host_manager_11ad/Makefile
new file mode 100644
index 0000000..3c39b3c
--- /dev/null
+++ b/debug-tools/host_manager_11ad/Makefile
@@ -0,0 +1,39 @@
+-include $(TOPDIR)/rules.mk
+
+CPPFLAGS := -Wall -g -MMD -std=c++0x -fPIE
+LDFLAGS := -pthread -fPIE -pie
+
+ifneq ($(CONFIG_TARGET_ipq)$(CONFIG_TARGET_ipq806x),)
+is_ipq806x = 1
+endif
+
+ifeq ($(is_ipq806x), 1)
+ifneq ($(strip $(TOOLPREFIX)),)
+CROSS:=$(TOOLPREFIX)
+endif
+endif
+
+CXX := $(CROSS)g++
+
+.DEFAULT_GOAL = all
+PROG = host_manager_11ad
+
+INCLUDE_CFLAGS += -I access_layer_11ad \
+ -I access_layer_11ad/Unix \
+
+all: $(PROG)
+
+CPP_FILES = $(shell find . -type f -name '*.cpp')
+OBJ_FILES= $(CPP_FILES:.cpp=.o)
+
+$(PROG): $(OBJ_FILES) $(LIBS)
+ $(CXX) -o $@ $^ $(LDFLAGS) $(LIBS)
+
+%.o : %.cpp
+ $(CXX) $(CPPFLAGS) $(INCLUDE_CFLAGS) -o $@ -c $<
+
+clean:
+ rm -rf $(PROG)
+ find . -type f \( -name "*.d" -o -name "*.o" \) -delete
+
+-include $(OBJ_FILES:%.o=%.d)
diff --git a/debug-tools/host_manager_11ad/MessageParser.cpp b/debug-tools/host_manager_11ad/MessageParser.cpp
new file mode 100644
index 0000000..ede3ba1
--- /dev/null
+++ b/debug-tools/host_manager_11ad/MessageParser.cpp
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "MessageParser.h"
+//#include <regex>
+#include <sstream>
+
+// *************************************************************************************************
+
+MessageParser::MessageParser(string message)
+ :m_message(message)
+{
+ char delimeter = '|'; //The new separator in a message is: "|", the old one is " ", keep the old one for backward compatibility
+ if (message.find_first_of(delimeter) == string::npos)
+ { //The new separator is *not* in the message, that means that the message is in the old format
+ delimeter = ' ';
+ }
+ m_splitMessage = m_SplitMessageByDelim(m_message, delimeter);
+}
+
+// *************************************************************************************************
+vector<string> MessageParser::m_SplitMessageByDelim(const string &message, char delim)
+{
+ vector<string> splitMessage;
+ stringstream sstream(message);
+ string word;
+ while (getline(sstream, word, delim))
+ {
+ if (word.empty())
+ { //don't push whitespace
+ continue;
+ }
+ splitMessage.push_back(word);
+ }
+ return splitMessage;
+}
+
+// *************************************************************************************************
+
+string MessageParser::GetCommandFromMessage()
+{
+ return string(m_splitMessage.front());
+
+}
+
+
+// *************************************************************************************************
+
+vector<string> MessageParser::GetArgsFromMessage()
+{
+ vector<string> temp = m_splitMessage;
+ temp.erase(temp.begin());
+ return temp;
+}
+
+// *************************************************************************************************
+
+unsigned int MessageParser::GetNumberOfArgs()
+{
+ return (m_splitMessage.size()-1); //(-1) because the function name is in also in the message
+}
diff --git a/debug-tools/host_manager_11ad/MessageParser.h b/debug-tools/host_manager_11ad/MessageParser.h
new file mode 100644
index 0000000..07c31b2
--- /dev/null
+++ b/debug-tools/host_manager_11ad/MessageParser.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MESSAGEPARSER_H
+#define _MESSAGEPARSER_H
+
+#include <iostream>
+#include "DebugLogger.h"
+#include <vector>
+
+using namespace std;
+
+// *************************************************************************************************
+
+class MessageParser
+{
+public:
+
+ MessageParser(string message);
+
+ /*
+ * Returns the command name from the message. Command name should be the first parameter in the message.
+ */
+ string GetCommandFromMessage();
+
+ vector<string> GetArgsFromMessage();
+
+ unsigned int GetNumberOfArgs();
+
+private:
+ string m_message; //holds the initial message - before was being parsed
+ vector<string> m_splitMessage;
+
+ vector<string> m_SplitMessageByDelim(const string &message, char delim);
+
+};
+
+#endif // !_MESSAGEPARSER_H
diff --git a/debug-tools/host_manager_11ad/NetworkInterface.cpp b/debug-tools/host_manager_11ad/NetworkInterface.cpp
new file mode 100644
index 0000000..ac9884b
--- /dev/null
+++ b/debug-tools/host_manager_11ad/NetworkInterface.cpp
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "NetworkInterface.h"
+#include "DebugLogger.h"
+
+#include <cerrno>
+
+using namespace NetworkInterfaces;
+
+NetworkInterface::NetworkInterface()
+{
+#ifdef _WINDOWS
+ WSADATA wsa;
+
+ if (-1 == WSAStartup(MAKEWORD(2, 0), &wsa))
+ {
+ LOG_ERROR << "Cannot initialize network library" << std::endl;
+ exit(1);
+ }
+#endif
+
+ m_fileDescriptor = socket(AF_INET, SOCK_STREAM, 0);
+ if (m_fileDescriptor < 0)
+ {
+ LOG_ERROR << "Cannot create socket file descriptor: " << strerror(errno) << std::endl;
+ exit(1);
+ }
+
+ char optval = 1;
+ setsockopt(m_fileDescriptor, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
+
+ m_localAddress.sin_family = AF_INET;
+ m_bufferSize = 0;
+ m_buffer = NULL;
+}
+
+NetworkInterface::NetworkInterface(int fileDescriptor)
+ : m_fileDescriptor(fileDescriptor)
+ , m_buffer(NULL)
+ , m_bufferSize(0)
+{
+}
+
+// Establish Connections
+void NetworkInterface::Bind(int port)
+{
+ m_localAddress.sin_port = htons(port);
+ m_localAddress.sin_addr.s_addr = INADDR_ANY;
+ memset(m_localAddress.sin_zero, '\0', sizeof m_localAddress.sin_zero);
+
+ if (-1 == bind(m_fileDescriptor, (struct sockaddr*)&m_localAddress, sizeof(m_localAddress)))
+ {
+ LOG_ERROR << "Cannot bind listener to port " << port << ": " << strerror(errno) << std::endl;
+ LOG_ERROR << "Please verify if another application instance is running" << std::endl;
+ exit(1);
+ }
+}
+
+void NetworkInterface::Listen(int backlog)
+{
+ if (-1 == listen(m_fileDescriptor, backlog))
+ {
+ LOG_ERROR << "Cannot listen to the socket: " << strerror(errno) << std::endl;
+ LOG_ERROR << "Please verify if another application instance is running" << std::endl;
+ exit(1);
+ }
+}
+
+NetworkInterface NetworkInterface::Accept()
+{
+ struct sockaddr_in remoteAddress;
+ socklen_t size = sizeof(remoteAddress);
+
+ int fileDescriptor = accept(m_fileDescriptor, (struct sockaddr*)&remoteAddress, &size);
+ if (fileDescriptor <= 0)
+ {
+ LOG_ERROR << "Cannot accept incoming connection: " << strerror(errno) << std::endl;
+ exit(1);
+ }
+
+ return NetworkInterface(fileDescriptor);
+}
+
+// Send and Receive
+int NetworkInterface::Send(const std::string& data)
+{
+ return send(m_fileDescriptor, data.c_str(), data.size(), 0);
+}
+
+int NetworkInterface::Send(const char* data)
+{
+ return send(m_fileDescriptor, data, strlen(data), 0);
+}
+
+const char* NetworkInterface::Receive(int size, int flags)
+{
+ if (m_bufferSize <= size + 1)
+ {
+ m_buffer = (char*)(realloc(m_buffer, sizeof(char) * (size + 1)));
+ m_bufferSize = size;
+ }
+
+ int bytesReceived = recv(m_fileDescriptor, m_buffer, size, flags);
+ m_buffer[bytesReceived] = '\0';
+
+ return m_buffer;
+}
+
+// Socket Closing Functions
+void NetworkInterface::Close()
+{
+#ifdef _WINDOWS
+ WSACleanup();
+ closesocket(m_fileDescriptor);
+#else
+ close(m_fileDescriptor);
+#endif
+}
+
+void NetworkInterface::Shutdown(int type)
+{
+#ifdef _WINDOWS
+ WSACleanup();
+#endif
+
+ shutdown(m_fileDescriptor, type);
+}
+
+const char* NetworkInterface::GetPeerName() const
+{
+ struct sockaddr_in remoteAddress;
+ socklen_t size = sizeof(remoteAddress);
+
+ if (-1 == getpeername(m_fileDescriptor, (struct sockaddr*)&remoteAddress, &size))
+ {
+ LOG_ERROR << "Failure in getpeername" << std::endl;
+ exit(1);
+ }
+
+ return inet_ntoa(remoteAddress.sin_addr);
+}
diff --git a/debug-tools/host_manager_11ad/NetworkInterface.h b/debug-tools/host_manager_11ad/NetworkInterface.h
new file mode 100644
index 0000000..7f1c40e
--- /dev/null
+++ b/debug-tools/host_manager_11ad/NetworkInterface.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SOCKET_H_
+#define _SOCKET_H_
+
+#ifdef _WINDOWS
+#pragma comment(lib, "Ws2_32.lib")
+#endif
+
+#include <cstdlib>
+#include <cstdio>
+#include <cerrno>
+#include <cstring>
+#include <string>
+
+#ifdef _WINDOWS
+#include <winsock.h>
+#elif __linux
+#include <unistd.h>
+#include <netdb.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/wait.h>
+#else
+
+#endif
+
+#ifdef _WINDOWS
+typedef int socklen_t;
+#endif
+
+
+namespace NetworkInterfaces
+{
+ class NetworkInterface
+ {
+ private:
+
+ int m_fileDescriptor;
+ struct sockaddr_in m_localAddress;
+ char* m_buffer;
+ int m_bufferSize;
+
+ public:
+
+ NetworkInterface();
+ explicit NetworkInterface(int sockfd);
+
+ // Establish Connection
+ void Bind(int portNumber);
+ void Listen(int backlog = 5);
+ NetworkInterface Accept();
+
+ // Send and Receive
+ int Send(const char* data);
+ int Send(const std::string& data);
+ const char* Receive(int size = 1024, int flags = 0);
+
+ // Terminate Connection
+ void Close();
+ void Shutdown(int type);
+
+ // Addresses
+ const char* GetPeerName() const;
+ };
+
+}
+
+#endif // !_NETWORK_INTERFACE_H_
diff --git a/debug-tools/host_manager_11ad/OsHandler.cpp b/debug-tools/host_manager_11ad/OsHandler.cpp
new file mode 100644
index 0000000..324d8c5
--- /dev/null
+++ b/debug-tools/host_manager_11ad/OsHandler.cpp
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "OsHandler.h"
+#include <memory>
+#include <iostream> //TODO - maybe to remove
+#include "Host.h"
+using namespace std; //TODO - maybe to remove
+
+#ifdef __linux
+void sig_quit_handler(int signum)
+{
+ if (signum == SIGQUIT)
+ {
+ printf("Exiting host_manager_11ad as per user request\n");
+ Host::GetHost().StopHost();
+ exit(signum);
+ }
+ else if (signum == SIGPIPE)
+ {
+ //printf("Connection lost\n");
+ }
+}
+#endif // __linux
+
+
+// *************************************************************************************************
+
+void OsHandler::HandleOsSignals()
+{
+#ifdef __linux
+ //LOG_INFO << "Handle linux SIQQUIT signal" << endl;
+ signal(SIGQUIT, sig_quit_handler);
+ signal(SIGPIPE, sig_quit_handler);
+#endif // __linux
+
+}
diff --git a/debug-tools/host_manager_11ad/OsHandler.h b/debug-tools/host_manager_11ad/OsHandler.h
new file mode 100644
index 0000000..8c4eb90
--- /dev/null
+++ b/debug-tools/host_manager_11ad/OsHandler.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _OSHANDLER_H_
+#define _OSHANDLER_H_
+
+
+
+// *************************************************************************************************
+
+/*
+* Class handling specific OS implementations
+*/
+class OsHandler
+{
+public:
+
+ /*
+ * Function to handle os signals - mostly relevant for linux os.
+ */
+ void HandleOsSignals();
+};
+
+#endif // _OSHANDLER_H_
+
diff --git a/debug-tools/host_manager_11ad/UdpServer.cpp b/debug-tools/host_manager_11ad/UdpServer.cpp
new file mode 100644
index 0000000..af08c25
--- /dev/null
+++ b/debug-tools/host_manager_11ad/UdpServer.cpp
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "UdpServer.h"
+#include "UdpTempOsAbstruction.h"
+#include "CommandsHandler.h"
+#include "Host.h"
+
+const int UdpServer::m_maxMessageLength = 1024;
+
+UdpServer::UdpServer(unsigned int udpPortIn, unsigned int udpPortOut, Host& host) :
+ m_udpPortIn(udpPortIn),
+ m_udpPortOut(udpPortOut),
+ m_broadcastIp(host.GetHostInfo().GetIps().m_broadcastIp),
+ m_CommandHandler(stUdp, host)
+{
+ try
+ {
+ m_pSocket.reset(new UdpSocket(m_broadcastIp, udpPortIn, udpPortOut));
+ }
+ catch (string error)
+ {
+ LOG_WARNING << "Failed to open UDP socket: " << error << endl;
+ m_pSocket.reset();
+ }
+}
+
+void UdpServer::StartServer()
+{
+ if (UdpTempOsAbstruction::LOCAL_HOST_IP == m_broadcastIp)
+ {
+ LOG_WARNING << "Can't start UDP server due to invalid host's IP/ broadcast IP";
+ return;
+ }
+
+ if (m_pSocket)
+ {
+ LOG_DEBUG << "Start UDP server on local port " << m_udpPortIn << std::endl;
+ LOG_DEBUG << "Broadcast messages are sent to port " << m_udpPortOut << std::endl;
+ BlockingReceive();
+ }
+}
+
+void UdpServer::Stop()
+{
+ m_pSocket.reset();
+}
+
+void UdpServer::BlockingReceive()
+{
+ do
+ {
+ const char* incomingMessage = m_pSocket->Receive(m_maxMessageLength);
+ LOG_VERBOSE << "Got Udp message: " << incomingMessage << endl;
+ ResponseMessage referencedResponse = { "", REPLY_TYPE_NONE, 0 };
+ m_CommandHandler.ExecuteCommand(incomingMessage, referencedResponse);
+ if (referencedResponse.length > 0)
+ {
+ LOG_VERBOSE << "Send broadcast message" << endl;
+ SendBroadcastMessage(referencedResponse);
+ }
+
+ } while (true);
+}
+
+void UdpServer::SendBroadcastMessage(ResponseMessage responseMessage)
+{
+ m_pSocket->Send(responseMessage.message);
+}
\ No newline at end of file
diff --git a/debug-tools/host_manager_11ad/UdpServer.h b/debug-tools/host_manager_11ad/UdpServer.h
new file mode 100644
index 0000000..f9324f7
--- /dev/null
+++ b/debug-tools/host_manager_11ad/UdpServer.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _UDPSERVER_H_
+#define _UDPSERVER_H_
+
+#include <string>
+#include <thread>
+#include "HostDefinitions.h"
+#include "CommandsHandler.h"
+#include "UdpTempOsAbstruction.h"
+
+class Host;
+
+class UdpServer
+{
+public:
+ /*
+ UdpServer
+ Creates a UDP socket which receives messages from the network and can response using a broadcast option
+ */
+ UdpServer(unsigned int udpPortIn, unsigned int udpPortOut, Host& host);
+
+ /*
+ StartServer
+ Starts to receive messages, Handles the message and continue to the receive
+ @param: none
+ @return: none
+ */
+ void StartServer();
+
+ /*
+ StopServer
+ Stops receiving messages
+ @param: none
+ @return: none
+ */
+ void Stop();
+
+private:
+ /*
+ BlockingReceive
+ Waits for a UDP message and handles it
+ Assumption: m_pSocket is valid
+ @param: none
+ @return: none
+ */
+ void BlockingReceive();
+
+ /*
+ SendBroadcastMessage
+ Sends a message to all hosts in the subnet
+ Assumption: m_pSocket is valid
+ @param: responseMessage - the message to send
+ @return: none
+ */
+ void SendBroadcastMessage(ResponseMessage responseMessage);
+
+ unsigned int m_udpPortIn; // the local host port
+ unsigned int m_udpPortOut; // the remote host port
+ string m_broadcastIp;
+ unique_ptr<UdpSocket> m_pSocket;
+ CommandsHandler m_CommandHandler;
+ static const int m_maxMessageLength;
+};
+
+
+#endif // !_UDPSERVER_H_
\ No newline at end of file
diff --git a/debug-tools/host_manager_11ad/UdpTempOsAbstruction.cpp b/debug-tools/host_manager_11ad/UdpTempOsAbstruction.cpp
new file mode 100644
index 0000000..dc951f0
--- /dev/null
+++ b/debug-tools/host_manager_11ad/UdpTempOsAbstruction.cpp
@@ -0,0 +1,342 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef __linux
+#include <sys/ioctl.h> // for struct ifreq
+#include <net/if.h> // for struct ifreq
+
+#include <stdlib.h>
+#include <string.h>
+#include <cerrno>
+#include <unistd.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <stdio.h>
+
+#else
+#include <windows.h>
+#endif
+
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include "DebugLogger.h"
+#include "UdpTempOsAbstruction.h"
+
+const std::string UdpTempOsAbstruction::LOCAL_HOST_IP = "127.0.0.1";
+
+bool UdpTempOsAbstruction::FindEthernetInterface(struct ifreq& ifr, int& fd)
+{
+#ifdef __linux
+ fd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (fd < 0)
+ {
+ LOG_WARNING << "Failed to get host's IP address and broadcast IP address" << std::endl;
+ return false;
+ }
+
+ for (int i = 0; i < 100; i++)
+ {
+ snprintf(ifr.ifr_name, IFNAMSIZ - 1, "eth%d", i);
+
+ if (ioctl(fd, SIOCGIFADDR, &ifr) >= 0)
+ {
+ return true;
+ }
+ }
+#endif
+ return false;
+}
+
+HostIps UdpTempOsAbstruction::GetHostIps()
+{
+#ifdef __linux
+ HostIps hostIps;
+ int fd;
+ struct ifreq ifr;
+
+ ifr.ifr_addr.sa_family = AF_INET; // IP4V
+
+ // Get IP address according to OS
+ if (FindEthernetInterface(ifr, fd))
+ {
+ LOG_INFO << "Linux OS" << std::endl;
+ }
+ else
+ {
+ strncpy(ifr.ifr_name, "br-lan", IFNAMSIZ - 1);
+ if (ioctl(fd, SIOCGIFADDR, &ifr) >= 0)
+ {
+ LOG_INFO << "OpenWRT OS" << std::endl;
+ }
+ else
+ {
+ // Probably Android OS
+ LOG_INFO << "Android OS (no external IP Adress)" << std::endl;
+ hostIps.m_ip = UdpTempOsAbstruction::LOCAL_HOST_IP;
+ hostIps.m_broadcastIp = UdpTempOsAbstruction::LOCAL_HOST_IP;
+ return hostIps;
+ }
+ }
+
+ hostIps.m_ip = inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr);
+
+ if (ioctl(fd, SIOCGIFBRDADDR, &ifr) < 0)
+ {
+ LOG_WARNING << "Failed to get broadcast IP" << std::endl;
+ return hostIps;
+ }
+ hostIps.m_broadcastIp = inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr);
+ LOG_DEBUG << "Host's IP address is " << hostIps.m_ip << std::endl;
+ LOG_DEBUG << "Broadcast IP address is " << hostIps.m_broadcastIp << std::endl;
+
+ close(fd);
+ return hostIps;
+#else
+ HostIps empty;
+ empty.m_broadcastIp = "10.18.172.155";
+ return empty;
+#endif
+}
+
+bool UdpTempOsAbstruction::ReadFile(string fileName, string& data)
+{
+ ifstream fd(fileName.c_str());
+ if (!fd.good()) // file doesn't exist
+ {
+ data = "";
+ return false;
+ }
+
+ fd.open(fileName.c_str());
+ stringstream content;
+ content << fd.rdbuf();
+ fd.close();
+ data = content.str();
+ return true;
+}
+
+bool UdpTempOsAbstruction::WriteFile(string fileName, string content)
+{
+ std::ofstream fd(fileName.c_str());
+ if (!fd.is_open())
+ {
+ LOG_WARNING << "Failed to open file: " << fileName << std::endl;
+ return false;
+ }
+ fd << content;
+ if (fd.bad())
+ {
+ LOG_WARNING << "Failed to write to file: " << fileName << std::endl;
+ fd.close();
+ return false;
+ }
+ fd.close();
+ return true;
+}
+
+string UdpTempOsAbstruction::GetPersistencyLocation()
+{
+#ifdef __linux
+ return "/etc/";
+#else
+ return "C:\\Temp\\"; // TODO: change
+#endif // __linux
+}
+
+string UdpTempOsAbstruction::GetDirectoriesDilimeter()
+{
+#ifdef __linux
+ return "/";
+#else
+ return "\\";
+#endif
+}
+
+bool UdpTempOsAbstruction::ReadHostOsAlias(string& alias)
+{
+#ifdef __linux
+ if (!ReadFile("/etc/hostname", alias))
+ {
+ alias = "";
+ return false;
+ }
+ return true;
+#else
+ alias = "";
+ return false;
+#endif // __linux
+}
+
+bool UdpTempOsAbstruction::IsFolderExists(string path)
+{
+#ifdef __linux
+ DIR* pDir = opendir(path.c_str());
+ if (pDir != NULL)
+ {
+ (void)closedir(pDir);
+ return true;
+ }
+ return false;
+#else
+ DWORD fileAttributes = GetFileAttributesA(path.c_str());
+ if (INVALID_FILE_ATTRIBUTES == fileAttributes) // no such path
+ {
+ return false;
+ }
+ if (fileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ {
+ return true; // given path is a directory
+ }
+ return false; // given path isn't a directory
+#endif
+}
+
+bool UdpTempOsAbstruction::IsFileExists(string path)
+{
+ ifstream f(path.c_str());
+ return f.good();
+}
+
+bool UdpTempOsAbstruction::CreateFolder(string path)
+{
+#ifdef __linux
+ system(("mkdir " + path).c_str());
+ return true;
+#else
+ // not Implemented yet
+ return false;
+#endif
+}
+
+void UdpTempOsAbstruction::MoveFileToNewLocation(string oldFileLocation, string newFileLocation)
+{
+#ifdef __linux
+ system(("mv " + oldFileLocation + " " + newFileLocation).c_str());
+#else
+ // not Implemented yet
+#endif
+}
+
+UdpSocket::UdpSocket(string broadcastIp, int portIn, int portOut)
+{
+ m_portIn = portIn;
+ m_portOut = portOut;
+ m_broadcastIp = broadcastIp;
+#ifdef __linux
+
+ // create UDP socket
+ m_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (m_socket < 0)
+ {
+ string error = "Can't open UDP socket";
+ LOG_WARNING << error << endl;
+ throw error;
+ }
+
+ // set broadcast flag on
+ int enabled = 1;
+ if (setsockopt(m_socket, SOL_SOCKET, SO_BROADCAST, (char*)&enabled, sizeof(enabled)) < 0)
+ {
+ string error = "Can't set broadcast option for udp socket, error: ";
+ error += strerror(errno);
+
+ LOG_WARNING << error << endl;
+ shutdown(m_socket, SHUT_RDWR);
+ throw error;
+ }
+
+ // bind socket to portIn
+ struct sockaddr_in address;
+ address.sin_family = AF_INET;
+ address.sin_addr.s_addr = INADDR_ANY;
+ address.sin_port = htons(m_portIn);
+ if (::bind(m_socket, (struct sockaddr *)&address, sizeof(struct sockaddr_in)) < 0)
+ {
+ string error = "Can't bind socket to port, error: ";
+ error += strerror(errno);
+
+ LOG_WARNING << error << std::endl;
+ throw error;
+ }
+#else
+ string error = "UDP socket is supported on linux OS only";
+ throw error;
+#endif
+}
+
+int UdpSocket::Send(string message)
+{
+#ifdef __linux
+ struct sockaddr_in dstAddress;
+ dstAddress.sin_family = AF_INET;
+ inet_pton(AF_INET, m_broadcastIp.c_str(), &dstAddress.sin_addr.s_addr);
+ dstAddress.sin_port = htons(m_portOut);
+ int messageSize = message.length() * sizeof(char);
+ int result = sendto(m_socket, message.c_str(), messageSize, 0, (sockaddr*)&dstAddress, sizeof(dstAddress));
+ LOG_VERBOSE << "INFO : sendto with sock_out=" << m_socket << ", message=" << message << " messageSize=" << messageSize << " returned with " << result << std::endl;
+ if (result < 0)
+ {
+ LOG_WARNING << "ERROR : Cannot send udp broadcast message, error " << ": " << strerror(errno) << std::endl;
+ return 0;
+ }
+ return messageSize;
+#else
+ return 0;
+#endif
+}
+
+const char* UdpSocket::Receive(int len)
+{
+#ifdef __linux
+ char* buf = new char[len];
+ if (recvfrom(m_socket, buf, len, 0, NULL, 0) < 0)
+ {
+ LOG_WARNING << "Can't receive from port " << m_portIn << std::endl;
+ return "";
+ }
+ return buf;
+#else
+ return "";
+#endif
+}
+
+void UdpSocket::Close()
+{
+#ifdef __linux
+ shutdown(m_socket, SHUT_RDWR);
+#else
+#endif
+}
diff --git a/debug-tools/host_manager_11ad/UdpTempOsAbstruction.h b/debug-tools/host_manager_11ad/UdpTempOsAbstruction.h
new file mode 100644
index 0000000..836bd1f
--- /dev/null
+++ b/debug-tools/host_manager_11ad/UdpTempOsAbstruction.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _UDPTEMPOSABSTRUCTION_H_
+#define _UDPTEMPOSABSTRUCTION_H_
+
+#include <string>
+#include <memory>
+#include "HostDefinitions.h"
+
+using namespace std;
+
+class UdpTempOsAbstruction
+{
+public:
+
+ /*
+ GetHostIps
+ Returns host's personal IP and broadcat IP
+ @param: none
+ @return: HostIps - host's personal IP and broadcat IP
+ */
+ static HostIps GetHostIps();
+
+ /*
+ ReadFile
+ Gets a file name and reads its context.
+ @param: fileName - full file name
+ @return: file's content
+ */
+ static bool ReadFile(string fileName, string& data);
+
+ /*
+ WriteFile
+ Gets a file name and the required content, and write the content to the file (overrides the old content if exists)
+ @param: fileName - full file name
+ @param: content - the new file's content
+ @return: true for successful write operation, false otherwise
+ */
+ static bool WriteFile(string fileName, string content);
+
+ /*
+ GetPersistencyLocation
+ Returns the host persistency location prefix accurding to the OS
+ @param: none
+ @return: host persistency location prefix accurding to the OS
+ */
+ static string GetPersistencyLocation();
+
+ /*
+ ReadHostOsAlias
+ Returns the host's alias as defined in persistency
+ @param: a reference to a string that will be updated with the host's alias
+ @return: bool - status - true for successful operation, false otherwise
+ */
+ static bool ReadHostOsAlias(string& alias);
+
+ static bool IsFolderExists(string path);
+
+ static bool CreateFolder(string path);
+
+ static void MoveFileToNewLocation(string oldFileLocation, string newFileLocation);
+
+ static string GetDirectoriesDilimeter();
+
+ static bool IsFileExists(string path);
+
+ static const string LOCAL_HOST_IP; // default IP address
+
+private:
+ static bool FindEthernetInterface(struct ifreq& ifr, int& fd);
+
+};
+
+class UdpSocket
+{
+public:
+
+ UdpSocket(string broadcastIp, int portIn, int portOut);
+
+ ~UdpSocket() { Close(); }
+
+ int Send(string message);
+
+ const char* Receive(int len);
+
+ void Close();
+
+private:
+
+ int m_portIn;
+ int m_portOut;
+ int m_socket;
+ string m_broadcastIp;
+};
+
+#endif
\ No newline at end of file
diff --git a/debug-tools/host_manager_11ad/Utils.cpp b/debug-tools/host_manager_11ad/Utils.cpp
new file mode 100644
index 0000000..9047d89
--- /dev/null
+++ b/debug-tools/host_manager_11ad/Utils.cpp
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "Utils.h"
+#include <sstream>
+#include <iomanip>
+#include <stdexcept>
+#include <cstdlib>
+
+#ifdef __linux
+#else
+#define localtime_r(_Time, _Tm) localtime_s(_Tm, _Time)
+#endif
+
+using namespace std;
+
+// *************************************************************************************************
+vector<string> Utils::Split(string str, char delimiter)
+{
+ vector<string> splitStr;
+ size_t nextSpacePosition = str.find_first_of(delimiter);
+ while (string::npos != nextSpacePosition)
+ {
+ splitStr.push_back(str.substr(0, nextSpacePosition));
+ str = str.substr(nextSpacePosition + 1);
+ nextSpacePosition = str.find_first_of(delimiter);
+ }
+
+ if ("" != str)
+ {
+ splitStr.push_back(str);
+ }
+ return splitStr;
+ /*
+ vector<string> splitMessage;
+ stringstream sstream(message);
+ string word;
+ while (getline(sstream, word, delim))
+ {
+ if (word.empty())
+ { //don't push whitespace
+ continue;
+ }
+ splitMessage.push_back(word);
+ }
+ return splitMessage;
+ */
+}
+
+// *************************************************************************************************
+string Utils::GetCurrentLocalTime()
+{
+ chrono::system_clock::time_point nowTimePoint = chrono::system_clock::now(); // get current time
+
+ // convert epoch time to struct with year, month, day, hour, minute, second fields
+ time_t now = chrono::system_clock::to_time_t(nowTimePoint);
+ tm localTime;
+ localtime_r(&now, &localTime);
+
+ // get milliseconds field
+ const chrono::duration<double> tse = nowTimePoint.time_since_epoch();
+ chrono::seconds::rep milliseconds = chrono::duration_cast<std::chrono::milliseconds>(tse).count() % 1000;
+
+
+ ostringstream currentTime;
+ currentTime << (1900 + localTime.tm_year) << '-'
+ << std::setfill('0') << std::setw(2) << (localTime.tm_mon + 1) << '-'
+ << std::setfill('0') << std::setw(2) << localTime.tm_mday << ' '
+ << std::setfill('0') << std::setw(2) << localTime.tm_hour << ':'
+ << std::setfill('0') << std::setw(2) << localTime.tm_min << ':'
+ << std::setfill('0') << std::setw(2) << localTime.tm_sec << '.'
+ << std::setfill('0') << std::setw(3) << milliseconds;
+
+ string currentTimeStr(currentTime.str());
+ return currentTimeStr;
+}
+
+// *************************************************************************************************
+bool Utils::ConvertHexStringToDword(string str, DWORD& word)
+{
+ if (str.find_first_of("0x") != 0) //The parameter is a hex string (assuming that a string starting with 0x must be hex)
+ {
+ return false;
+ }
+ istringstream s(str);
+ s >> hex >> word;
+ return true;
+}
+
+// *************************************************************************************************
+bool Utils::ConvertHexStringToDwordVector(string str, char delimiter, vector<DWORD>& values)
+{
+ vector<string> strValues = Utils::Split(str, delimiter);
+ values.reserve(strValues.size());
+ for (auto& strValue : strValues)
+ {
+ DWORD word;
+ if (Utils::ConvertHexStringToDword(strValue, word))
+ {
+ values.push_back(word);
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+// *************************************************************************************************
+bool Utils::ConvertDecimalStringToUnsignedInt(string str, unsigned int& ui)
+{
+ unsigned long l;
+ try
+ {
+ l = strtoul(str.c_str(), nullptr, 10); // 10 for decimal base
+ }
+ catch (...)
+ {
+ return false;
+ }
+
+ ui = l;
+ return true;
+}
diff --git a/debug-tools/host_manager_11ad/Utils.h b/debug-tools/host_manager_11ad/Utils.h
new file mode 100644
index 0000000..716e6fb
--- /dev/null
+++ b/debug-tools/host_manager_11ad/Utils.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _UTILS_H_
+#define _UTILS_H_
+
+#include <vector>
+#include <string>
+#include <chrono>
+
+#ifdef _WINDOWS
+typedef unsigned long DWORD;
+#else
+typedef uint32_t DWORD;
+#endif
+
+using namespace std;
+
+class Utils
+{
+public:
+
+ static vector<string> Split(string str, char delimiter);
+
+ static string GetCurrentLocalTime();
+
+ static bool ConvertHexStringToDword(string str, DWORD& word);
+
+ static bool ConvertHexStringToDwordVector(string str, char delimiter, vector<DWORD>& values);
+
+ static bool ConvertDecimalStringToUnsignedInt(string str, unsigned int& ui);
+};
+
+#endif // !_UTILS_H_
+
diff --git a/debug-tools/host_manager_11ad/access_layer_11ad/AccessLayerAPI.cpp b/debug-tools/host_manager_11ad/access_layer_11ad/AccessLayerAPI.cpp
new file mode 100644
index 0000000..9c55094
--- /dev/null
+++ b/debug-tools/host_manager_11ad/access_layer_11ad/AccessLayerAPI.cpp
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sstream>
+
+#include "AccessLayerAPI.h"
+
+#ifdef _WINDOWS
+//#include "JTagDevice.h"
+#include "SerialDevice.h"
+#endif
+#include "TestDevice.h"
+
+#include "PciDevice.h"
+#include "../Utils.h"
+
+using namespace std;
+
+set<string> AccessLayer::GetDevices()
+{
+ set<string> enumeratedDevices;
+
+ // Enumerate
+ set<string> pciDevices = PciDevice::Enumerate();
+
+#ifdef _WINDOWS
+ //set<string> jtagDevices = JTagDevice::Enumerate();
+ //set<string> serialDevices = SerialDevice::Enumerate();
+ //enumeratedDevices.insert(serialDevices.begin(), serialDevices.end());
+#endif
+
+ enumeratedDevices.insert(pciDevices.begin(), pciDevices.end());
+#ifdef _UseTestDevice
+ set<string> testDevices = TestDevice::Enumerate();
+ enumeratedDevices.insert(testDevices.begin(), testDevices.end());
+#endif // _UseTestDevice
+
+ return enumeratedDevices;
+}
+
+unique_ptr<Device> AccessLayer::OpenDevice(string deviceName)
+{
+ vector<string> tokens = Utils::Split(deviceName, DEVICE_NAME_DELIMITER);
+
+ // Device name consists of exactly 3 elements:
+ // 1. Baseband Type (SPARROW, TALYN...)
+ // 2. Transport Type (PCI, JTAG, Serial...)
+ // 3. Interface name (wMp, wPci, wlan0, wigig0...)
+ if (tokens.size() != 2)
+ {
+ // LOG_MESSAGE_ERROR
+ return NULL;
+ }
+
+ // Transport type
+ unique_ptr<Device> pDevice;
+
+ if ("PCI" == tokens[0])
+ {
+ pDevice.reset(new PciDevice(deviceName, tokens[1]));
+ }
+
+#ifdef _WINDOWS
+ if ("SERIAL" == tokens[0])
+ {
+ pDevice.reset(new SerialDevice(deviceName, tokens[1]));
+ }
+#endif
+
+#ifdef _UseTestDevice
+ if ("TEST" == tokens[0])
+ {
+ pDevice.reset(new TestDevice(deviceName, tokens[1]));
+ }
+#endif // _UseOnlyTestDevice
+
+
+ return pDevice;
+}
+
+void AccessLayer::CloseDevice(string deviceName)
+{
+ //do something with params
+ (void)deviceName;
+}
diff --git a/debug-tools/host_manager_11ad/access_layer_11ad/AccessLayerAPI.h b/debug-tools/host_manager_11ad/access_layer_11ad/AccessLayerAPI.h
new file mode 100644
index 0000000..3461b4c
--- /dev/null
+++ b/debug-tools/host_manager_11ad/access_layer_11ad/AccessLayerAPI.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <memory>
+#include <set>
+#include "Device.h"
+
+class AccessLayer
+{
+public:
+ //static void GetVersion(WLCT_DLL_VERSION *pVer);
+ static set<string> GetDevices();
+ static unique_ptr<Device> OpenDevice(string deviceName);
+ static void CloseDevice(string deviceName);
+
+ static set<string> GetTestDevices();
+
+private:
+ static vector<string> Split(const string &message, char delim);
+};
\ No newline at end of file
diff --git a/debug-tools/host_manager_11ad/access_layer_11ad/Definitions.h b/debug-tools/host_manager_11ad/access_layer_11ad/Definitions.h
new file mode 100644
index 0000000..e127218
--- /dev/null
+++ b/debug-tools/host_manager_11ad/access_layer_11ad/Definitions.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _11AD_ACCESS_LAYER_DEFINITIONS_H_
+#define _11AD_ACCESS_LAYER_DEFINITIONS_H_
+
+#define BAUD_RATE_REGISTER 0x880050
+
+typedef enum BasebandTypeEnum
+{
+ BASEBAND_TYPE_NONE,
+ BASEBAND_TYPE_SPARROW, // added here to keep backward compatibility. some tools assume MARLON == 2, we don't brake this assumption
+ BASEBAND_TYPE_MARLON,
+ BASEBAND_TYPE_TALYN,
+ BASEBAND_TYPE_LAST
+} BasebandType;
+
+#define EMPTY_ARRAY_SIZE
+
+#define DEVICE_NAME_DELIMITER '!'
+
+#endif //_11AD_ACCESS_LAYER_DEFINITIONS_H_
\ No newline at end of file
diff --git a/debug-tools/host_manager_11ad/access_layer_11ad/Device.h b/debug-tools/host_manager_11ad/access_layer_11ad/Device.h
new file mode 100644
index 0000000..9d166c5
--- /dev/null
+++ b/debug-tools/host_manager_11ad/access_layer_11ad/Device.h
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _11AD_DEVICE_H_
+#define _11AD_DEVICE_H_
+
+#include <string>
+#include <vector>
+#include <set>
+#include <iostream>
+#include "OperatingSystemConstants.h"
+#include "Definitions.h"
+#include "../DebugLogger.h"
+
+using namespace std;
+
+class Device
+{
+public:
+ Device(string deviceName, string interfaceName)
+ {
+ m_deviceName = deviceName;
+ m_interfaceName = interfaceName;
+ m_initialized = false;
+
+ m_basebandType = BASEBAND_TYPE_NONE;
+ }
+
+ // ************************** Device API ****************************//
+ // Device Management
+ virtual bool Open() { return false; };
+ virtual void Close() {};
+
+ // Base access functions (to be implemented by specific device)
+ virtual bool Read(DWORD address, DWORD& value)
+ {
+ //do something with params
+ (void)address;
+ (void)value;
+ return false;
+ };
+ virtual bool ReadBlock(DWORD address, DWORD blockSize, vector<DWORD>& values)
+ {
+ //do something with params
+ (void)address;
+ (void)blockSize;
+ (void)values;
+ return false;
+ };
+
+ virtual bool Write(DWORD address, DWORD value)
+ {
+ //do something with params
+ (void)address;
+ (void)value;
+ return false; };
+ virtual bool WriteBlock(DWORD address, vector<DWORD> values)
+ {
+ //do something with params
+ (void)address;
+ (void)values;
+ return false; };
+
+ // Polling function
+ //vector<DeviceEvent> DoPoll();
+
+ // Functionality common to all devices
+ bool SwReset() { return false; }
+
+ virtual bool AllocPmc(unsigned descSize, unsigned descNum)
+ {
+ //do something with params
+ (void)descSize;
+ (void)descNum;
+ return false;
+ } // TODO: implement
+
+ virtual bool DeallocPmc() { return false; } // TODO: implement
+
+ virtual bool CreatePmcFile(unsigned refNumber)
+ {
+ //do something with params
+ (void)refNumber;
+ return false;
+ } // TODO: implement
+
+ virtual void InterfaceReset() {};
+
+ virtual bool SetDriverMode(int newMode, int& oldMode)
+ {
+ //do something with params
+ (void)newMode;
+ (void)oldMode;
+ return false;
+ }
+
+ bool SendWmi(DWORD command, vector<DWORD> payload)
+ {
+ //do something with params
+ (void)command;
+ (void)payload;
+ return false;
+
+ }
+ vector<DWORD> GetWmiEvent()
+ {
+
+ vector<DWORD> ret;
+ return ret;
+ }
+
+ bool IsOpen()
+ {
+ return m_initialized;
+ }
+
+ void Poll()
+ {
+ // TODO: implement polling: MB, logs, rgf
+ }
+
+ static unsigned int GetRegisterDefaultValue()
+ {
+ return 0xDEADDEAD;
+ }
+ // ************************** [END] Device API **********************//
+
+ string GetDeviceName()
+ {
+ return m_deviceName;
+ }
+
+ string GetInterfaceName()
+ {
+ return m_interfaceName;
+ }
+
+ BasebandType GetBasebandType()
+ {
+ if (m_basebandType == BASEBAND_TYPE_NONE)
+ {
+ m_basebandType = ReadBasebandType();
+ }
+
+ return m_basebandType;
+ }
+ virtual ~Device(){};
+protected:
+ DWORD m_deviceHandle;
+ bool m_initialized;
+private:
+ string m_deviceName;
+ string m_interfaceName;
+ BasebandType m_basebandType;
+
+ BasebandType ReadBasebandType()
+ {
+ DWORD jtagVersion;
+ const int rev_id_address = 0x880B34; //USER.JTAG.USER_USER_JTAG_1.dft_idcode_dev_id
+ const int device_id_mask = 0x0fffffff; //take the first 28 bits from the Jtag Id
+ BasebandType res = BASEBAND_TYPE_NONE;
+
+ if (!Read(rev_id_address, jtagVersion))
+ {
+ LOG_ERROR << "Failed to read baseband type" << "\n";
+ }
+
+ LOG_INFO << "JTAG rev ID = " << hex << jtagVersion << "\n";
+
+ switch (jtagVersion & device_id_mask)
+ {
+ case 0x612072F:
+ res = BASEBAND_TYPE_MARLON;
+ break;
+ case 0x632072F:
+ res = BASEBAND_TYPE_SPARROW;
+ break;
+ case 0x642072F:
+ case 0x007E0E1:
+ res = BASEBAND_TYPE_TALYN;
+ break;
+ default:
+ ////LOG_MESSAGE_WARN("Invalid device type - assuming Sparrow");
+ res = BASEBAND_TYPE_SPARROW;
+ break;
+ }
+
+ return res;
+ }
+};
+
+#endif // !_11AD_DEVICE_H_
diff --git a/debug-tools/host_manager_11ad/access_layer_11ad/DriverAPI.h b/debug-tools/host_manager_11ad/access_layer_11ad/DriverAPI.h
new file mode 100644
index 0000000..11bb3bf
--- /dev/null
+++ b/debug-tools/host_manager_11ad/access_layer_11ad/DriverAPI.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _11AD_PCI_DRIVER_API_H_
+#define _11AD_PCI_DRIVER_API_H_
+
+#include <string>
+#include <set>
+
+#include "OperatingSystemConstants.h"
+
+using namespace std;
+
+class DriverAPI
+{
+public:
+ DriverAPI(string interfaceName)
+ {
+ m_interfaceName = interfaceName;
+ }
+ virtual ~DriverAPI() {};
+
+ // Base access functions (to be implemented by specific device)
+ virtual bool Read(DWORD address, DWORD& value) = 0;
+ virtual bool ReadBlock(DWORD addr, DWORD blockSize, char *arrBlock) = 0;
+ virtual bool Write(DWORD address, DWORD value) = 0;
+ virtual bool WriteBlock(DWORD addr, DWORD blockSize, const char *arrBlock) = 0;
+
+ virtual bool IsOpened(void) = 0;
+
+ virtual bool Open() = 0;
+ virtual bool ReOpen() = 0;
+ virtual bool Ioctl(uint32_t Id,
+ const void *inBuf, uint32_t inBufSize,
+ void *outBuf, uint32_t outBufSize) = 0;
+ virtual DWORD DebugFS(char *FileName, void *dataBuf, DWORD dataBufLen, DWORD DebugFSFlags)
+ {
+ //do something with params
+ (void)FileName;
+ (void)dataBuf;
+ (void)dataBufLen;
+ (void)DebugFSFlags;
+ return -1;
+ }
+ virtual void Close() = 0;
+
+ virtual int GetDriverMode(int ¤tState) = 0;
+ virtual bool SetDriverMode(int newState, int &oldState) = 0;
+
+ virtual void Reset() = 0;
+
+protected:
+ string m_interfaceName;
+ void* m_deviceHandle;
+
+private:
+};
+
+
+#endif //_11AD_PCI_DRIVER_API_H_
diff --git a/debug-tools/host_manager_11ad/access_layer_11ad/OperatingSystemConstants.h b/debug-tools/host_manager_11ad/access_layer_11ad/OperatingSystemConstants.h
new file mode 100644
index 0000000..3b866b1
--- /dev/null
+++ b/debug-tools/host_manager_11ad/access_layer_11ad/OperatingSystemConstants.h
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#ifdef _WINDOWS
+
+#include <windows.h>
+#include <atlbase.h>
+#include <atlstr.h>
+#include <assert.h>
+
+typedef unsigned __int8 u_int8_t;
+typedef unsigned __int16 u_int16_t;
+typedef unsigned __int32 u_int32_t;
+typedef unsigned __int64 u_int64_t;
+#if (defined(_MSC_VER) && (_MSC_VER < 1900))
+//typedef __int8 int8_t;
+#endif
+typedef __int16 int16_t;
+typedef __int32 int32_t;
+typedef __int64 int64_t;
+typedef unsigned __int8 uint8_t;
+typedef unsigned __int16 uint16_t;
+typedef unsigned __int32 uint32_t;
+typedef unsigned __int64 uint64_t;
+
+#define WLCT_OS_ERROR_SUCCESS ERROR_SUCCESS
+#define WLCT_OS_ERROR_NOT_SUPPORTED ERROR_NOT_SUPPORTED
+#define WLCT_OS_ERROR_CALL_NOT_IMPLEMENTED ERROR_CALL_NOT_IMPLEMENTED
+#define WLCT_OS_ERROR_GEN_FAILURE ERROR_GEN_FAILURE
+#define WLCT_OS_ERROR_NOT_ENOUGH_MEMORY ERROR_NOT_ENOUGH_MEMORY
+#define WLCT_OS_ERROR_NO_SUCH_ENTRY ERROR_FILE_NOT_FOUND
+#define WLCT_OS_ERROR_OPEN_FAILED ERROR_OPEN_FAILED
+
+#define WLCT_ASSERT assert
+
+#define __TRY __try
+
+#define __EXCEPT __except
+
+#define sleep_ms Sleep
+
+#define WlctGetLastError GetLastError
+
+#else
+
+#include <stdint.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include <string>
+
+#define WLCT_ASSERT assert
+
+#define __INLINE __inline
+
+typedef uint8_t BYTE;
+typedef uint16_t WORD;
+typedef uint32_t DWORD;
+
+typedef unsigned char UCHAR;
+typedef unsigned int UINT;
+typedef char CHAR;
+typedef long LONG;
+typedef unsigned short USHORT;
+typedef unsigned long ULONG;
+typedef ULONG* ULONG_PTR;
+
+typedef char TCHAR;
+
+typedef uint8_t u_int8_t;
+typedef uint16_t u_int16_t;
+typedef uint32_t u_int32_t;
+typedef uint64_t u_int64_t;
+
+typedef const TCHAR *LPCTSTR;
+typedef TCHAR *LPTSTR;
+typedef CHAR *LPSTR;
+typedef const CHAR *LPCSTR;
+
+typedef DWORD HANDLE;
+
+typedef int BOOL;
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#include <errno.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <strings.h>
+
+typedef int wlct_os_err_t;
+
+#define WLCT_OS_ERROR_SUCCESS 0
+#define WLCT_OS_ERROR_NOT_SUPPORTED -ENOTSUP
+#define WLCT_OS_ERROR_CALL_NOT_IMPLEMENTED -ENOSYS
+#define WLCT_OS_ERROR_GEN_FAILURE -EINVAL
+#define WLCT_OS_ERROR_NOT_ENOUGH_MEMORY -ENOMEM
+#define WLCT_OS_ERROR_NO_SUCH_ENTRY -ENOENT
+#define WLCT_OS_ERROR_OPEN_FAILED -EBADF
+
+#define _T(x) (x)
+
+#define __TRY if (1)
+#define __EXCEPT(ignore) else if (0)
+
+#define WLCT_MSEC_IN_SEC 1000
+
+#define sleep_ms(msec) usleep(msec * WLCT_MSEC_IN_SEC)
+
+#define USES_CONVERSION
+
+#define T2A(x) (x)
+
+#define _tcscpy_s(x, y, z) snprintf((x), (y), "%s", (z))
+#define _tcslen strlen
+#define _stprintf_s snprintf
+#define _snprintf snprintf
+//#define sprintf_s sprintf
+//#define _stprintf sprintf
+#define sscanf_s sscanf
+#define _tcstok_s strtok_r
+#define _tcsstr strstr
+#define _tcsicmp strcasecmp
+#define _vsntprintf vsnprintf
+#define _tfopen fopen
+
+#define WlctGetLastError() errno
+
+#endif
+
+#define WLCT_UNREFERENCED_PARAM(x) ((x) = (x))
diff --git a/debug-tools/host_manager_11ad/access_layer_11ad/PciDevice.cpp b/debug-tools/host_manager_11ad/access_layer_11ad/PciDevice.cpp
new file mode 100644
index 0000000..93b7f01
--- /dev/null
+++ b/debug-tools/host_manager_11ad/access_layer_11ad/PciDevice.cpp
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "OperatingSystemConstants.h"
+#include "../DebugLogger.h"
+#ifdef _WINDOWS
+#include "WindowsDriverAPI.h"
+#else
+#include "UnixDriverAPI.h"
+#endif
+
+#include "PciDevice.h"
+
+
+//////////////////////////////////////////////////////////////////////////
+// PCI interface
+
+PciDevice::PciDevice(string deviceName, string interfaceName) : Device(deviceName, interfaceName)
+{
+ //LOG_MESSAGE_INFO(_T("Create PCI device access for: %s"), interfaceName.c_str());
+ m_initialized = false;
+
+#ifdef _WINDOWS
+ m_pDriverApi.reset(new WindowsDriverAPI(interfaceName));
+#else
+ m_pDriverApi.reset(new UnixDriverAPI(interfaceName));
+#endif
+
+ if (m_pDriverApi->Open())
+ {
+ m_initialized = true;
+ }
+ else
+ {
+ m_initialized = false;
+ }
+}
+PciDevice::~PciDevice()
+{
+ Close();
+}
+
+// Virtual access functions for device
+bool PciDevice::Read(DWORD address, DWORD& value)
+{
+ return (m_pDriverApi->Read(address, value));
+}
+bool PciDevice::ReadBlock(DWORD address, DWORD blockSize, vector<DWORD>& values)
+{
+ bool success = false;
+
+ DWORD* arrBlock = NULL;
+ try
+ {
+ arrBlock = new DWORD[blockSize];
+
+ // blockSize is in bytes, need to be multiplied by 4 for DWORDS
+ success = (m_pDriverApi->ReadBlock(address, blockSize * 4, (char*)arrBlock));
+
+ values = std::vector<DWORD>(arrBlock, arrBlock + (blockSize));
+
+ LOG_DEBUG << "Read: " << values.size() << " Values \n";
+ }
+ catch (...)
+ {
+ LOG_ERROR << "Exception when trying to read block\n";
+ delete[] arrBlock;
+ return false;
+ }
+
+ delete[] arrBlock;
+ return success;
+}
+bool PciDevice::Write(DWORD address, DWORD value)
+{
+ return (m_pDriverApi->Write(address, value));
+}
+bool PciDevice::WriteBlock(DWORD address, vector<DWORD> values)
+{
+ char* valuesToWrite = (char*)&values[0];
+
+ return (m_pDriverApi->WriteBlock(address, values.size() * 4, valuesToWrite));
+}
+
+bool PciDevice::Open()
+{
+ return m_pDriverApi->Open();
+}
+void PciDevice::Close()
+{
+ return m_pDriverApi->Close();
+}
+bool PciDevice::ReOpen()
+{
+ return m_pDriverApi->ReOpen();
+}
+
+bool PciDevice::SetDriverMode(int newState, int &oldState)
+{
+ return m_pDriverApi->SetDriverMode(newState, oldState);
+}
+int PciDevice::GetDriverMode(int ¤tState)
+{
+ return m_pDriverApi->GetDriverMode(currentState);
+}
+
+static string NameDevice(string interfaceName)
+{
+ return std::string("PCI") + DEVICE_NAME_DELIMITER + interfaceName;
+}
+
+void PciDevice::InterfaceReset()
+{
+ m_pDriverApi->Reset();
+ return;
+}
+
+set<string> PciDevice::Enumerate()
+{
+ // Hold all discovered hosts
+ set<string> discoveredDevices;
+
+#ifdef _WINDOWS
+ set<string> enumeratedDevices = WindowsDriverAPI::Enumerate();
+#else
+ set<string> enumeratedDevices = UnixDriverAPI::Enumerate();
+#endif
+
+ set<string>::iterator it;
+ for (it = enumeratedDevices.begin(); it != enumeratedDevices.end(); ++it)
+ {
+ string interfaceName = *it;
+
+ PciDevice device("Enum", interfaceName);
+
+ if (device.IsOpen())
+ {
+ discoveredDevices.insert(NameDevice(interfaceName));
+ device.Close();
+ }
+ }
+
+ return discoveredDevices;
+}
+
+bool PciDevice::try2open(int timeout)
+{
+ do
+ {
+ Open();
+ if (m_pDriverApi->IsOpened())
+ break;
+ sleep_ms(100);
+ timeout -= 100;
+ } while (timeout > 0);
+
+ if (!m_pDriverApi->IsOpened())
+ return false;
+ return true;
+}
+void PciDevice::rr32(DWORD addr, DWORD num_repeat, DWORD *arrBlock)
+{
+ //do something with params
+ (void)addr;
+ (void)num_repeat;
+ (void)arrBlock;
+ WLCT_ASSERT(0);
+}
diff --git a/debug-tools/host_manager_11ad/access_layer_11ad/PciDevice.h b/debug-tools/host_manager_11ad/access_layer_11ad/PciDevice.h
new file mode 100644
index 0000000..06f49b3
--- /dev/null
+++ b/debug-tools/host_manager_11ad/access_layer_11ad/PciDevice.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _11AD_PCI_DEVICE_H_
+#define _11AD_PCI_DEVICE_H_
+
+#ifdef _WINDOWS
+//#include "ioctl_if.h"
+#else
+// some definitions from ioctl_if.h
+#define WILOCITY_IOCTL_INDIRECT_READ IOCTL_INDIRECT_READ_OLD
+#define WILOCITY_IOCTL_INDIRECT_WRITE IOCTL_INDIRECT_WRITE_OLD
+#define WILOCITY_IOCTL_INDIRECT_READ_BLOCK IOCTL_INDIRECT_READ_BLOCK
+#define WILOCITY_IOCTL_INDIRECT_WRITE_BLOCK IOCTL_INDIRECT_WRITE_BLOCK
+#endif
+
+#include <memory>
+#include "Device.h"
+#include "DriverAPI.h"
+
+using namespace std;
+
+class PciDevice : public Device
+{
+public:
+ PciDevice(string deviceName, string interfaceName);
+ ~PciDevice();
+
+ // Device Management
+ bool Open();
+ void Close();
+
+ // Virtual access functions for device
+ bool Read(DWORD address, DWORD& value);
+ bool ReadBlock(DWORD address, DWORD blockSize, vector<DWORD>& values);
+ bool Write(DWORD address, DWORD value);
+ bool WriteBlock(DWORD address, vector<DWORD> values);
+
+ virtual void InterfaceReset();
+
+ virtual bool SetDriverMode(int newState, int &oldState);
+ virtual int GetDriverMode(int ¤tState);
+
+ static set<string> Enumerate();
+
+private:
+ void rr32(DWORD addr, DWORD num_repeat, DWORD *arrBlock);
+ bool ReOpen();
+ bool try2open(int timeout);
+
+ static void SamplingThreadProc(void *pDeviceAccss);
+ static void PciPluginThreadProc(void *pDeviceAccss);
+
+ // The driver API for the PCI access (OS specific)
+ unique_ptr<DriverAPI> m_pDriverApi;
+};
+
+#endif //_11AD_PCI_DEVICE_H_
\ No newline at end of file
diff --git a/debug-tools/host_manager_11ad/access_layer_11ad/TestDevice.cpp b/debug-tools/host_manager_11ad/access_layer_11ad/TestDevice.cpp
new file mode 100644
index 0000000..2641d0d
--- /dev/null
+++ b/debug-tools/host_manager_11ad/access_layer_11ad/TestDevice.cpp
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sstream>
+#include "TestDevice.h"
+
+//////////////////////////////////////////////////////////////////////////
+// Test Device interface
+
+TestDevice::TestDevice(string deviceName, string interfaceName) : Device(deviceName, interfaceName)
+{
+ //LOG_MESSAGE_INFO(_T("Create test device access for: %s"), interfaceName.c_str());
+ m_registersAddressToValue.insert(make_pair(0x880050, 0x12345678));
+
+ unsigned baseAddress = 0x880100;
+ unsigned numOfAddresses = 40;
+ unsigned numOfAddressesInRegister = 4;
+ unsigned value = 0x0;
+ for (unsigned i = 0; i < numOfAddresses * numOfAddressesInRegister; i += numOfAddressesInRegister)
+ {
+ m_registersAddressToValue.insert(make_pair(baseAddress + i, value++));
+ }
+}
+
+TestDevice::~TestDevice()
+{
+ Close();
+}
+
+// Virtual access functions for device
+bool TestDevice::Read(DWORD address, DWORD& value)
+{
+ auto registerElement = m_registersAddressToValue.find(address);
+ if (registerElement != m_registersAddressToValue.end())
+ {
+ value = registerElement->second;
+ return true;
+
+ }
+ value = Device::GetRegisterDefaultValue();
+ return false;
+}
+
+bool TestDevice::ReadBlock(DWORD address, DWORD blockSize, vector<DWORD>& values)
+{
+ auto registerElement = m_registersAddressToValue.find(address);
+ if (registerElement != m_registersAddressToValue.end())
+ {
+ for (DWORD v = 0x0; v < blockSize; ++v)
+ {
+ values.push_back(registerElement->second + v);
+ }
+ return true;
+ }
+ return false;
+}
+
+bool TestDevice::Write(DWORD address, DWORD value)
+{
+ auto registerElement = m_registersAddressToValue.find(address);
+ if (registerElement != m_registersAddressToValue.end())
+ {
+ registerElement->second = value;
+ return true;
+ }
+ return false;
+}
+
+bool TestDevice::WriteBlock(DWORD address, vector<DWORD> values)
+{
+ auto registerElement = m_registersAddressToValue.find(address);
+ if (registerElement != m_registersAddressToValue.end())
+ {
+ unsigned i = 0;
+ for (auto v = values.begin(); v != values.end(); ++v)
+ {
+ m_registersAddressToValue[address + i] = *v;
+ ++i;
+ }
+ return true;
+ }
+ return false;
+}
+
+bool TestDevice::Open()
+{
+ return true;
+}
+
+void TestDevice::Close()
+{
+ return;
+}
+
+void TestDevice::InterfaceReset()
+{
+ return;
+}
+
+bool TestDevice::SwReset()
+{
+ return true;
+}
+
+set<string> TestDevice::Enumerate()
+{
+ stringstream deviceNameDelimiter;
+ deviceNameDelimiter << DEVICE_NAME_DELIMITER;
+ set<string> discoveredDevices;
+
+ // add first device
+ string deviceName = std::string("TEST") + deviceNameDelimiter.str() + "wTest0";
+ discoveredDevices.insert(deviceName);
+
+ // add second device
+ deviceName = std::string("TEST") + deviceNameDelimiter.str() + "wTest1";
+ discoveredDevices.insert(deviceName);
+
+ return discoveredDevices;
+}
\ No newline at end of file
diff --git a/debug-tools/host_manager_11ad/access_layer_11ad/TestDevice.h b/debug-tools/host_manager_11ad/access_layer_11ad/TestDevice.h
new file mode 100644
index 0000000..4ede6b4
--- /dev/null
+++ b/debug-tools/host_manager_11ad/access_layer_11ad/TestDevice.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _11AD_TEST_DEVICE_H_
+#define _11AD_TEST_DEVICE_H_
+
+#include <map>
+#include "Device.h"
+
+using namespace std;
+
+class TestDevice : public Device
+{
+public:
+ TestDevice(string deviceName, string interfaceName);
+ ~TestDevice();
+
+ // Device Management
+ bool Open();
+ void Close();
+
+ // Virtual access functions for device
+ bool Read(DWORD address, DWORD& value);
+ bool ReadBlock(DWORD address, DWORD blockSize, vector<DWORD>& values);
+ bool Write(DWORD address, DWORD value);
+ bool WriteBlock(DWORD address, vector<DWORD> values);
+
+ virtual void InterfaceReset();
+ bool SwReset();
+
+ static set<string> Enumerate();
+
+private:
+ map<DWORD, DWORD> m_registersAddressToValue;
+};
+#endif //_11AD_TEST_DEVICE_H_
\ No newline at end of file
diff --git a/debug-tools/host_manager_11ad/access_layer_11ad/Unix/UnixDriverAPI.cpp b/debug-tools/host_manager_11ad/access_layer_11ad/Unix/UnixDriverAPI.cpp
new file mode 100644
index 0000000..751f224
--- /dev/null
+++ b/debug-tools/host_manager_11ad/access_layer_11ad/Unix/UnixDriverAPI.cpp
@@ -0,0 +1,386 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _WINDOWS
+
+#include <iostream>
+
+#include "UnixDriverAPI.h"
+
+#include <net/if.h> // for struct ifreq
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/ioctl.h> // for struct ifreq
+
+#define END_POINT_RESULT_MAX_SIZE 256
+#define NETWORK_INTERFACE_RESULT_MAX_SIZE 256
+
+using namespace std;
+
+UnixDriverAPI::~UnixDriverAPI()
+{
+ Close();
+}
+
+// Base access functions (to be implemented by specific device)
+bool UnixDriverAPI::Read(DWORD address, DWORD& value)
+{
+ IoctlIO io;
+
+ io.addr = address;
+ io.val = 0;
+ io.op = EP_OPERATION_READ;
+ if (!SendRWIoctl(io, m_fileDescriptor, m_interfaceName.c_str()))
+ {
+ return false;
+ }
+
+ value = io.val;
+
+ return true;
+}
+bool UnixDriverAPI::ReadBlock(DWORD addr, DWORD blockSize, char *arrBlock)
+{
+ IoctlIO io;
+
+ // cout << "Read block addr = " << addr << ". block size = " << blockSize << "\n";
+
+ //blocks must be 32bit alligned!
+ int numReads = blockSize / 4;
+ io.op = EP_OPERATION_READ;
+ io.addr = addr;
+ for (int i = 0; i < numReads; i++)
+ {
+ if (!SendRWIoctl(io, m_fileDescriptor, m_interfaceName.c_str()))
+ {
+ // cout << "Failed to Read in ReadBlock";
+ return false;
+ }
+
+ // Copy the read 32 bits into the arrBlock
+ memcpy(&arrBlock[(i * 4)], &io.val, sizeof(int32_t));
+ // cout << "Read block " << i << " out of " << numReads << ". val = " << io.val << "\n";
+
+ io.addr += sizeof(int32_t);
+ }
+
+ return true;
+}
+bool UnixDriverAPI::Write(DWORD address, DWORD value)
+{
+ IoctlIO io;
+
+ io.addr = address;
+ io.val = value;
+ io.op = EP_OPERATION_WRITE;
+
+ if (!SendRWIoctl(io, m_fileDescriptor, m_interfaceName.c_str()))
+ {
+ return false;
+ }
+
+ return true;
+}
+bool UnixDriverAPI::WriteBlock(DWORD addr, DWORD blockSize, const char *arrBlock)
+{
+ // cout << "Write Block addr = " << addr << ". block size = " << blockSize << "\n";
+
+ IoctlIO io;
+
+ io.addr = addr;
+
+ //blocks must be 32bit alligned!
+ int sizeToWrite = blockSize / 4;
+ io.op = EP_OPERATION_WRITE;
+ for (int i = 0; i < sizeToWrite; i++)
+ {
+ io.val = *((int*)&(arrBlock[i * 4]));
+
+ // cout << "Writing " << io.val << " to address " << io.addr << "\n";
+
+ Write(io.addr, io.val);
+
+ io.addr += sizeof(int32_t);
+ }
+
+ return true;
+}
+
+bool UnixDriverAPI::IsOpened(void)
+{
+ return m_initialized;
+}
+
+string GetInterfaceNameFromEP(string pciEndPoint)
+{
+ char szInterfaceCmdPattern[END_POINT_RESULT_MAX_SIZE];
+
+ // This command translates the End Point to the interface name
+ snprintf(szInterfaceCmdPattern, END_POINT_RESULT_MAX_SIZE, "ls /sys/module/wil6210/drivers/pci:wil6210/%s/net", pciEndPoint.c_str());
+
+ FILE* pIoStream = popen(szInterfaceCmdPattern, "r");
+ if (!pIoStream)
+ {
+ // cout << "Failed to run command to detect End Points" << "\n";
+ //LOG_MESSAGE_ERROR("Failed to run command to detect End Points\n" );
+ return "Invalid";
+ }
+
+ char foundInterfaceName[NETWORK_INTERFACE_RESULT_MAX_SIZE];
+
+ while (fgets(foundInterfaceName, END_POINT_RESULT_MAX_SIZE, pIoStream) != NULL)
+ {
+ // The command output contains a newline character that should be removed
+ foundInterfaceName[strcspn(foundInterfaceName, "\r\n")] = '\0';
+
+ string interfaceName(foundInterfaceName);
+
+ // cout << "PCI interface found: " << interfaceName << "\n";
+ //LOG_MESSAGE_DEBUG("PCI interface found: %s", interfaceName);
+
+ pclose(pIoStream);
+
+ return interfaceName;
+ }
+
+ pclose(pIoStream);
+ return "Invalid";
+}
+
+set<string> GetNetworkInterfaceNames()
+{
+ set<string> networkInterfaces;
+
+ // Holds the console ouput containing the current End Point
+ char pciEndPoints[END_POINT_RESULT_MAX_SIZE];
+
+ // This command retrieves the PCI endpoints enumerated
+ const char* szCmdPattern = "ls /sys/module/wil6210/drivers/pci\\:wil6210 | grep :";
+
+ FILE* pIoStream = popen(szCmdPattern, "r");
+ if (!pIoStream)
+ {
+ // cout << "Failed to run command to detect End Points" << "\n";
+ //LOG_MESSAGE_ERROR("Failed to run command to detect End Points\n" );
+ return networkInterfaces;
+ }
+
+ while (fgets(pciEndPoints, END_POINT_RESULT_MAX_SIZE, pIoStream) != NULL)
+ {
+ // The command output contains a newline character that should be removed
+ pciEndPoints[strcspn(pciEndPoints, "\r\n")] = '\0';
+
+ string pciEndPoint(pciEndPoints);
+ // cout << "PCI End Point Found:" << pciEndPoint << "\n";
+ //LOG_MESSAGE_DEBUG("PCI End Point Found: %s", pciEndPoint.c_str());
+
+ // Get interface name from End Point
+ string networkInterfaceName = GetInterfaceNameFromEP(pciEndPoint);
+
+ if (networkInterfaceName != "Invalid")
+ {
+ networkInterfaces.insert(networkInterfaceName);
+ }
+ }
+
+ pclose(pIoStream);
+ return networkInterfaces;
+}
+
+set<string> UnixDriverAPI::Enumerate()
+{
+ set<string> interfaces = GetNetworkInterfaceNames();
+
+ return interfaces;
+}
+
+bool UnixDriverAPI::Open()
+{
+ if(IsOpened())
+ {
+ return true;
+ }
+
+ // cout << "Trying to open device:" << m_interfaceName << "\n";
+ //LOG_MESSAGE_DEBUG("Trying to open device:", m_interfaceName.c_str());
+
+ m_fileDescriptor = socket(AF_INET, SOCK_DGRAM, 0);
+ if (INVALID_FD == m_fileDescriptor || m_fileDescriptor < 0)
+ {
+ // cout << "Failed to open socket to device:" << m_interfaceName << "\n";
+ //LOG_MESSAGE_ERROR("Failed to open socket to device %s", m_interfaceName.c_str());
+ Close();
+ return false;
+ }
+
+ // Validate interface is 11ad interface
+ if(!ValidateInterface())
+ {
+ // cout << "Failed to query interface:" << m_interfaceName << "\n";
+ //LOG_MESSAGE_ERROR("Failed to query interface %s", m_interfaceName.c_str());
+ Close();
+ return false;
+ }
+
+ // Unix command for getting Debug FS path
+ string debugFsFind = "echo \"/sys/kernel/debug/ieee80211/$(ls $(find /sys/devices -name " + m_interfaceName + ")/../../ieee80211 | grep -Eo \"phy[0-9]*\")/wil6210\"";
+
+ // cout << debugFsFind << "\n";
+
+ FILE* pIoStream = popen(debugFsFind.c_str(), "r");
+ if (!pIoStream)
+ {
+ // cout << "Failed to run command to detect DebugFS" << "\n";
+ //LOG_MESSAGE_ERROR("Failed to run command to detect DebugFS\n" );
+ Close();
+ return false;
+ }
+
+ char debugFSPath[DEBUG_FS_MAX_PATH_LENGTH];
+ while (fgets(debugFSPath, DEBUG_FS_MAX_PATH_LENGTH, pIoStream) != NULL)
+ {
+ // The command output contains a newline character that should be removed
+ debugFSPath[strcspn(debugFSPath, "\r\n")] = '\0';
+ string str = (debugFSPath);
+ m_debugFsPath = str;
+
+ // cout << "Found DebugFS Path:" << m_debugFsPath << "\n";
+ //LOG_MESSAGE_DEBUG("Found DebugFS Path: %s", debugFSPath);
+ }
+
+ pclose(pIoStream);
+ m_initialized = true;
+ return true;
+}
+
+bool UnixDriverAPI::ReOpen()
+{
+ return Open();
+}
+
+bool UnixDriverAPI::InternalOpen()
+{
+ return true;
+}
+
+DWORD UnixDriverAPI::DebugFS(char *FileName, void *dataBuf, DWORD dataBufLen, DWORD DebugFSFlags)
+{
+ //do something with params
+ (void)FileName;
+ (void)dataBuf;
+ (void)dataBufLen;
+ (void)DebugFSFlags;
+ return 0;
+}
+
+void UnixDriverAPI::Close()
+{
+ if (m_fileDescriptor != INVALID_FD)
+ {
+ close(m_fileDescriptor);
+ m_fileDescriptor = INVALID_FD;
+ }
+}
+
+int UnixDriverAPI::GetDriverMode(int ¤tState)
+{
+ //do something with params
+ (void)currentState;
+
+ return 0;
+}
+bool UnixDriverAPI::SetDriverMode(int newState, int &oldState)
+{
+ //do something with params
+ (void)newState;
+ (void)oldState;
+ return false;
+}
+
+void UnixDriverAPI::Reset()
+{
+ return;
+}
+
+bool UnixDriverAPI::Ioctl(uint32_t Id,
+ const void *inBuf, uint32_t inBufSize,
+ void *outBuf, uint32_t outBufSize)
+{
+ //do something with params
+ (void)Id;
+ (void)inBuf;
+ (void)inBufSize;
+ (void)outBuf;
+ (void)outBufSize;
+ return false;
+}
+
+bool UnixDriverAPI::SendRWIoctl(IoctlIO & io, int fd, const char* interfaceName)
+{
+ int ret;
+ struct ifreq ifr;
+ ifr.ifr_data = (char*)&io;
+
+ // cout << "Address is " << hex << io.addr << "\n";
+ // cout << "fd is " << fd << "\n";
+ // cout << "interfaceName is " << interfaceName << "\n";
+
+ snprintf(ifr.ifr_name, IFNAMSIZ, "%s", interfaceName);
+ ifr.ifr_name[IFNAMSIZ - 1] = 0;
+
+ ret = ioctl(fd, WIL_IOCTL_MEMIO, &ifr);
+ if (ret < 0)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+// Receives interface name (wigig#, wlan#) and checks if it is responding
+bool UnixDriverAPI::ValidateInterface()
+{
+ IoctlIO io;
+ io.addr = 0x880050; //baud rate
+ io.op = EP_OPERATION_READ;
+
+ // cout << "Checking interface name:" << m_interfaceName << "\n";
+ //LOG_MESSAGE_DEBUG("Checking interface name: %s", m_interfaceName.c_str());
+
+ if(SendRWIoctl(io, m_fileDescriptor, m_interfaceName.c_str()))
+ {
+ // cout << "Successfuly set interface name:" << m_interfaceName << "\n";
+ //LOG_MESSAGE_DEBUG("Successfuly set interface name: %s", interfaceName);
+ return true;
+ }
+
+ return false;
+}
+
+#endif // ifndef _WINDOWS
diff --git a/debug-tools/host_manager_11ad/access_layer_11ad/Unix/UnixDriverAPI.h b/debug-tools/host_manager_11ad/access_layer_11ad/Unix/UnixDriverAPI.h
new file mode 100644
index 0000000..fbccaf7
--- /dev/null
+++ b/debug-tools/host_manager_11ad/access_layer_11ad/Unix/UnixDriverAPI.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _11AD_PCI_UNIX_DRIVER_API_H_
+#define _11AD_PCI_UNIX_DRIVER_API_H_
+
+
+#ifndef _WINDOWS
+
+#include "DriverAPI.h"
+
+#define DEBUG_FS_MAX_PATH_LENGTH 1024
+
+using namespace std;
+
+class UnixDriverAPI : public DriverAPI
+{
+ typedef struct
+ {
+ DWORD deviceUID;
+ DWORD commandID;
+ DWORD dataSize; /* inBufSize + outBufSize */
+ DWORD inBufOffset;
+ DWORD inBufSize;
+ DWORD outBufOffset;
+ DWORD outBufSize;
+ } IoctlHeader;
+
+ #define IOCTL_FLAG_SET 0x1
+ #define IOCTL_FLAG_GET 0x2
+
+ #define EP_OPERATION_READ 0
+ #define EP_OPERATION_WRITE 1
+ #define WIL_IOCTL_MEMIO (SIOCDEVPRIVATE + 2)
+
+ #define INVALID_FD -1
+
+ static __INLINE BYTE *
+ IoctlDataIn(IoctlHeader *h)
+ {
+ return ((BYTE*)&h[1]) + h->inBufOffset;
+ }
+
+ static __INLINE BYTE *
+ IoctlDataOut(IoctlHeader *h)
+ {
+ return ((BYTE*)&h[1]) + h->outBufOffset;
+ }
+
+ typedef struct {
+ uint32_t op;
+ uint32_t addr; /* should be 32-bit aligned */
+ uint32_t val;
+ } IoctlIO;
+
+public:
+ UnixDriverAPI(string interfaceName) : DriverAPI(interfaceName)
+ {
+ m_initialized = false;
+ }
+ ~UnixDriverAPI();
+
+ // Base access functions (to be implemented by specific device)
+ bool Read(DWORD address, DWORD& value);
+ bool ReadBlock(DWORD addr, DWORD blockSize, char *arrBlock);
+ bool Write(DWORD address, DWORD value);
+ bool WriteBlock(DWORD addr, DWORD blockSize, const char *arrBlock);
+
+ bool IsOpened(void);
+
+ bool Open();
+ bool ReOpen();
+ bool InternalOpen();
+ bool Ioctl(uint32_t Id,
+ const void *inBuf, uint32_t inBufSize,
+ void *outBuf, uint32_t outBufSize);
+ DWORD DebugFS(char *FileName, void *dataBuf, DWORD dataBufLen, DWORD DebugFSFlags);
+ void Close();
+
+ int GetDriverMode(int ¤tState);
+ bool SetDriverMode(int newState, int &oldState);
+
+ void Reset();
+
+ static set<string> Enumerate();
+
+private:
+ bool InternalIoctl(void *dataBuf, DWORD dataBufLen, DWORD ioctlFlags);
+ bool SendRWIoctl(IoctlIO & io, int fd, const char* interfaceName);
+ bool ValidateInterface();
+
+ bool m_initialized;
+
+ int m_fileDescriptor;
+
+ string m_debugFsPath;
+};
+
+#endif // ifndef _WINDOWS
+
+#endif //_11AD_PCI_UNIX_DRIVER_API_H_
\ No newline at end of file
diff --git a/debug-tools/host_manager_11ad/main.cpp b/debug-tools/host_manager_11ad/main.cpp
new file mode 100644
index 0000000..1c41bad
--- /dev/null
+++ b/debug-tools/host_manager_11ad/main.cpp
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "OsHandler.h"
+#include "ArgumentsParser.h"
+#include <memory>
+//#include "Server.h"
+#include "DebugLogger.h"
+#include <iostream> //TODO - maybe remove in final
+#include "Host.h"
+
+using namespace std;
+
+#define DEFAULT_COMMANDS_TCP_SERVER_PORT 12348 //TODO - change back to 12348
+#define DEFAULT_EVENTS_TCP_SERVER_PORT 12339 //TODO - change back to 12347
+#define DEFAULT_UDP_SERVER_PORT_IN_GET_MESSAGE 12349 // This is a UDP port to get messages only from the remote server
+#define DEFAULT_REMOTE_UDP_SERVER_PORT_OUT_SEND_MESSAGE 12350 // This is the UDP port in the remote server to send messages only
+
+// *************************************************************************************************
+
+int main(int argc, char* argv[])
+{
+ try
+ {
+ unsigned int commandsTcpPort = DEFAULT_COMMANDS_TCP_SERVER_PORT;
+ unsigned int eventsTcpPort = DEFAULT_EVENTS_TCP_SERVER_PORT;
+ unsigned int udpPortIn = DEFAULT_UDP_SERVER_PORT_IN_GET_MESSAGE;
+ unsigned int udpPortOut = DEFAULT_REMOTE_UDP_SERVER_PORT_OUT_SEND_MESSAGE;
+
+ unique_ptr<ArgumentsParser> pArgumentsParser(new ArgumentsParser());
+ //support to change by the user the commands TCP port only,events Tcp port UDP ports are not changeable by the user
+ pArgumentsParser->ParseAndHandleArguments(argc, argv, commandsTcpPort);
+
+ //Handle OS specific configurations
+ unique_ptr<OsHandler> pOsHandler(new OsHandler());
+ pOsHandler->HandleOsSignals();
+
+ //Start Host object
+ LOG_INFO << "Starting Host Manager" << endl;
+ Host::GetHost().StartHost(commandsTcpPort, eventsTcpPort, udpPortIn, udpPortOut);
+
+ LOG_INFO << "Stopping host_manager_11ad" << endl;
+ }
+ catch (exception& e)
+ {
+ LOG_ERROR << "Stopping host_manager_11ad due to failure: " << e.what() << endl;
+ }
+
+ return 0;
+
+
+}
\ No newline at end of file
diff --git a/debug-tools/host_manager_11ad/pmc_file.cpp b/debug-tools/host_manager_11ad/pmc_file.cpp
new file mode 100644
index 0000000..a653884
--- /dev/null
+++ b/debug-tools/host_manager_11ad/pmc_file.cpp
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "pmc_file.h"
+//#include "debug.h" // TODO: change after fixing log issues
+#include <iostream> // TODO: ...and then, remove this line
+#include "UdpTempOsAbstruction.h" // TODO: fix OS issues
+#include "DebugLogger.h"
+
+#include <cstring>
+#include <cerrno>
+#include <sstream>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+// *************************************************************************************************
+#ifdef __ANDROID__
+#define PMC_DATA_DIRECTORY "/data/pmc"
+#else
+#define PMC_DATA_DIRECTORY "/var/pmc"
+#endif
+
+// PMC directory and file name pattern should be managed separately as directory is required as a
+// separate variable.
+
+const char* const PmcFile::s_pDirectory = PMC_DATA_DIRECTORY;
+const char* const PmcFile::s_pFileNamePrefix = "pmc_data_";
+
+// *************************************************************************************************
+
+PmcFile::PmcFile(int fileId)
+ : m_FileId(fileId)
+{
+ std::stringstream ss;
+ ss << s_pDirectory << '/' << s_pFileNamePrefix << fileId;
+ m_FileName = ss.str();
+
+ LOG_DEBUG << "PMC file name #" << fileId << " generated: " << m_FileName << std::endl;
+}
+
+std::ostream& operator<<(std::ostream& os, const PmcFile& pmcFile)
+{
+ return os << "PMC file #" << pmcFile.GetFileId() << " (" << pmcFile.GetFileName() << ')';
+}
+
+// *************************************************************************************************
+
+PmcFileWriter::PmcFileWriter(const PmcFile& pmcFile)
+ : m_PmcFile(pmcFile)
+{
+}
+
+// *************************************************************************************************
+
+bool PmcFileWriter::CreateDirectoryIfNeeded() const
+{
+ // Create a PMC directory if does not exist
+ struct stat st = {};
+ if (stat(m_PmcFile.GetDirectory(), &st) != -1)
+ {
+ LOG_DEBUG << "PMC directory " << m_PmcFile.GetDirectory()
+ << " exists for " << m_PmcFile.GetFileName() << std::endl;
+ return true;
+ }
+
+ LOG_DEBUG << "Creating a PMC directory: " << m_PmcFile.GetDirectory() << std::endl;
+
+ int status = UdpTempOsAbstruction::CreateFolder(m_PmcFile.GetDirectory()); // TDOO: original line: int status = mkdir(m_PmcFile.GetDirectory(), 0700);
+ if (0 != status)
+ {
+ LOG_ERROR << "Failed to create PMC directory. Path: " << m_PmcFile.GetDirectory() << endl;
+ /*int lastErrno = errno;
+ LOG_ERROR << "Cannot create PMC directory."
+ << " Path: " << m_PmcFile.GetDirectory()
+ << " Error:" << lastErrno
+ << " Message: " << strerror(lastErrno)
+ << std::endl;
+ */
+ return false;
+ }
+
+ return true;
+}
+
+// *************************************************************************************************
+
+bool PmcFileWriter::WriteFile() const
+{
+ if (false == CreateDirectoryIfNeeded())
+ {
+ LOG_ERROR << "Cannot create a PMC directory for " << m_PmcFile << std::endl;
+ return false;
+ }
+
+ // Create a PMC file
+ const char* pCmdPrefix =
+ "D=$(find /sys/kernel/debug/ieee80211/ -name wil6210); cat $D/pmcdata >> ";
+ std::stringstream ss;
+ ss << pCmdPrefix << m_PmcFile.GetFileName();
+
+ system(ss.str().c_str());
+ return true;
+
+}
+
+// *************************************************************************************************
+
+size_t PmcFileWriter::GetFileSize() const
+{
+ FILE *pFile = fopen(m_PmcFile.GetFileName(), "r");
+
+ if (NULL == pFile)
+ {
+ int lastErrno = errno;
+ LOG_ERROR << "Cannot open " << m_PmcFile << " for writing."
+ << " Error: " << lastErrno
+ << " Message: " << strerror(lastErrno)
+ << std::endl;
+ return 0;
+ }
+
+ fseek (pFile, 0, SEEK_END);
+ size_t fileSize = ftell(pFile);
+ fclose(pFile);
+
+ LOG_DEBUG << "Get PMC file size for " << m_PmcFile
+ << ": " << fileSize << "B" << std::endl;
+
+ return fileSize;
+}
diff --git a/debug-tools/host_manager_11ad/pmc_file.h b/debug-tools/host_manager_11ad/pmc_file.h
new file mode 100644
index 0000000..b7af0b7
--- /dev/null
+++ b/debug-tools/host_manager_11ad/pmc_file.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _PMC_FILE_H_
+#define _PMC_FILE_H_
+
+#include <stdio.h>
+#include <string>
+
+// *************************************************************************************************
+
+// Generates a PMC file name from its ID.
+class PmcFile
+{
+public:
+
+ explicit PmcFile(int fileId);
+
+ int GetFileId() const { return m_FileId; }
+ const char* GetFileName() const { return m_FileName.c_str(); }
+
+ static const char* GetDirectory() { return s_pDirectory; }
+
+private:
+
+ static const char* const s_pDirectory;
+ static const char* const s_pFileNamePrefix;
+
+ const int m_FileId; // File ID (expected to be unique)
+ std::string m_FileName; // File Name Buffer
+
+};
+
+std::ostream& operator<<(std::ostream& os, const PmcFile& pmcFile);
+
+// *************************************************************************************************
+
+// Creates a PMC data file according to a provided ID.
+class PmcFileWriter
+{
+public:
+
+ explicit PmcFileWriter(const PmcFile& pmcFile);
+
+ bool WriteFile() const;
+ size_t GetFileSize() const;
+
+private:
+
+ bool CreateDirectoryIfNeeded() const;
+
+ const PmcFile& m_PmcFile;
+
+};
+
+
+#endif // PMC_FILE_H_
diff --git a/debug-tools/lib/Android.mk b/debug-tools/lib/Android.mk
new file mode 100644
index 0000000..8e4e086
--- /dev/null
+++ b/debug-tools/lib/Android.mk
@@ -0,0 +1,6 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+include $(call all-makefiles-under, $(LOCAL_PATH))
+
diff --git a/debug-tools/lib/FlashAcss/Android.mk b/debug-tools/lib/FlashAcss/Android.mk
new file mode 100644
index 0000000..2fdbf9f
--- /dev/null
+++ b/debug-tools/lib/FlashAcss/Android.mk
@@ -0,0 +1,27 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libwigig_flashaccess
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_CPPFLAGS := -Wall -lpthread
+
+LOCAL_C_INCLUDES += \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/../inc \
+ $(LOCAL_PATH)/../inc/linux \
+ $(LOCAL_PATH)/../utils \
+ $(LOCAL_PATH)/../utils/linux \
+ $(LOCAL_PATH)/linux \
+ $(LOCAL_PATH)/../WlctPciAcss \
+ $(LOCAL_PATH)/../WlctPciAcss/linux
+
+LOCAL_SRC_FILES := $(shell find $(LOCAL_PATH) -name '*.cpp' | sed s:^$(LOCAL_PATH)::g )
+
+LOCAL_SHARED_LIBRARIES := \
+ libwigig_utils \
+ libwigig_pciaccess
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/debug-tools/lib/FlashAcss/FlashAcss.cpp b/debug-tools/lib/FlashAcss/FlashAcss.cpp
new file mode 100644
index 0000000..47f12f4
--- /dev/null
+++ b/debug-tools/lib/FlashAcss/FlashAcss.cpp
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "flashacss.h"
+#include "flash_gateway.h"
+#include "SparrowGateway.h"
+#include "MarlonGateway.h"
+
+FLSHACSS_API int wfa_create_flash_access_handler(DType devType, void* pDeviceAccess, void** pFlashAccess)
+{
+ flash_gateway* p_flash_gateway = NULL;
+ if (devType == MST_TALYN)
+ {
+ p_flash_gateway = new SparrowGateway(pDeviceAccess);
+ }
+ if (devType == MST_SPARROW)
+ {
+ p_flash_gateway = new SparrowGateway(pDeviceAccess);
+ }
+ else if (devType == MST_MARLON)
+ {
+ p_flash_gateway = new MarlonGateway(pDeviceAccess);
+ }
+ else
+ {
+ return WLCT_OS_ERROR_NOT_SUPPORTED;
+ }
+ *pFlashAccess = (void*)p_flash_gateway;
+ return 0;
+}
+
+FLSHACSS_API int wfa_close_flash_access_handler(void* pFlashAccess)
+{
+ int res = 0;
+ flash_gateway* p_flash_gateway = (flash_gateway*)pFlashAccess;
+ if (p_flash_gateway != NULL)
+ {
+ __TRY
+ {
+ delete p_flash_gateway;
+ }
+ __EXCEPT(EXCEPTION_ACCESS_VIOLATION == GetExceptionCode())
+ {
+ res = -1;
+ }
+ }
+ return res;
+}
+
+FLSHACSS_API int wfa_run_command(void* pFlashAccss, UCHAR flash_cmd, FLASH_PHASE phase, bool bWrite, unsigned long addr, unsigned long ulSize)
+{
+ int rc = 0;
+ if (pFlashAccss == NULL)
+ return -1;
+
+ __TRY
+ {
+ rc = ((flash_gateway*)pFlashAccss)->runCommand(flash_cmd, phase, bWrite, addr, ulSize);
+ }
+ __EXCEPT(EXCEPTION_ACCESS_VIOLATION == GetExceptionCode())
+ {
+ }
+ return rc;
+}
+
+FLSHACSS_API int wfa_set_data(void* pFlashAccss, const BYTE *buffer, unsigned long size)
+{
+ int rc = 0;
+ if (pFlashAccss == NULL)
+ return -1;
+
+ __TRY
+ {
+ rc = ((flash_gateway*)pFlashAccss)->setData(buffer, size);
+ }
+ __EXCEPT(EXCEPTION_ACCESS_VIOLATION == GetExceptionCode())
+ {
+ }
+ return rc;
+}
+
+FLSHACSS_API int wfa_get_data(void* pFlashAccss, BYTE *buffer, unsigned long size)
+{
+ int rc = 0;
+ if (pFlashAccss == NULL)
+ return -1;
+
+ __TRY
+ {
+ rc = ((flash_gateway*)pFlashAccss)->getData(buffer, size);
+ }
+ __EXCEPT(EXCEPTION_ACCESS_VIOLATION == GetExceptionCode())
+ {
+ }
+ return rc;
+}
+
+FLSHACSS_API int wfa_wait_done(void* pFlashAccss)
+{
+ int rc = 0;
+ if (pFlashAccss == NULL)
+ return -1;
+
+ __TRY
+ {
+ rc = ((flash_gateway*)pFlashAccss)->wait_done();
+ }
+ __EXCEPT(EXCEPTION_ACCESS_VIOLATION == GetExceptionCode())
+ {
+ }
+ return rc;
+}
+
+FLSHACSS_API int wfa_boot_done(void* pFlashAccss)
+{
+ int rc = 0;
+ if (pFlashAccss == NULL)
+ return -1;
+
+ __TRY
+ {
+ rc = ((flash_gateway*)pFlashAccss)->boot_done();
+ }
+ __EXCEPT(EXCEPTION_ACCESS_VIOLATION == GetExceptionCode())
+ {
+ }
+ return rc;
+}
+
+FLSHACSS_API bool wfa_get_lock (void* pFlashAccss)
+{
+ bool ret = false;
+
+ if (pFlashAccss == NULL)
+ return ret;
+
+ __TRY
+ {
+ ret = ((flash_gateway*)pFlashAccss)->get_lock();
+ }
+ __EXCEPT(EXCEPTION_ACCESS_VIOLATION == GetExceptionCode())
+ {
+ }
+ return ret;
+}
+
+FLSHACSS_API int wfa_force_lock (void* pFlashAccss)
+{
+ int rc = 0;
+ if (pFlashAccss == NULL)
+ return -1;
+
+ __TRY
+ {
+ rc = ((flash_gateway*)pFlashAccss)->force_lock();
+ }
+ __EXCEPT(EXCEPTION_ACCESS_VIOLATION == GetExceptionCode())
+ {
+ }
+ return rc;
+}
+
+FLSHACSS_API int wfa_release_lock(void* pFlashAccss)
+{
+ int rc = 0;
+ if (pFlashAccss == NULL)
+ return -1;
+
+ __TRY
+ {
+ rc = ((flash_gateway*)pFlashAccss)->release_lock();
+ }
+ __EXCEPT(EXCEPTION_ACCESS_VIOLATION == GetExceptionCode())
+ {
+ }
+ return rc;
+}
diff --git a/debug-tools/lib/FlashAcss/Makefile b/debug-tools/lib/FlashAcss/Makefile
new file mode 100644
index 0000000..3189001
--- /dev/null
+++ b/debug-tools/lib/FlashAcss/Makefile
@@ -0,0 +1,46 @@
+-include $(TOPDIR)/rules.mk
+
+CFLAGS := -fPIC -Wall -g -MMD
+LDFLAGS := -shared -fPIC
+
+LIB := libwigig_flashaccess.so
+
+.DEFAULT_GOAL = all
+
+ifneq ($(CONFIG_TARGET_ipq)$(CONFIG_TARGET_ipq806x),)
+is_ipq806x = 1
+endif
+
+ifeq ($(is_ipq806x), 1)
+ifneq ($(strip $(TOOLPREFIX)),)
+CROSS:=$(TOOLPREFIX)
+endif
+endif
+
+CC = $(CROSS)gcc
+CXX = $(CROSS)g++
+
+INCLUDES = -I . \
+ -I ../inc/linux \
+ -I ../inc \
+ -I ../utils/linux \
+ -I ../utils \
+ -I ./linux \
+ -I ../WlctPciAcss \
+
+all: $(LIB)
+
+CPP_FILES := $(shell find . -type f -name '*.cpp')
+OBJ_FILES := $(CPP_FILES:.cpp=.o)
+
+$(LIB): $(OBJ_FILES)
+ $(CXX) $(LDFLAGS) -o $(LIB) $(OBJ_FILES)
+
+%.o : %.cpp
+ $(CXX) $(CFLAGS) $(INCLUDES) -o $@ -c $<
+
+clean:
+ rm -rf $(LIB)
+ find . -type f \( -name "*.d" -o -name "*.o" \) -delete
+
+-include $(OBJ_FILES:%.o=%.d)
diff --git a/debug-tools/lib/FlashAcss/MarlonGateway.cpp b/debug-tools/lib/FlashAcss/MarlonGateway.cpp
new file mode 100644
index 0000000..859b9c8
--- /dev/null
+++ b/debug-tools/lib/FlashAcss/MarlonGateway.cpp
@@ -0,0 +1,335 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include "MarlonGateway.h"
+
+#define ONES32(size) ((size)?(0xffffffff>>(32-(size))):0)
+#define MASK32(offset,size) (ONES32(size)<<(offset))
+
+#define EXTRACT_C32(source,offset,size) ((((unsigned)(source))>>(offset)) & ONES32(size))
+#define EXTRACT32(src,start,len) (((len)==32)?(src):EXTRACT_C32(src,start,len))
+
+#define MERGE_C32(rsrc1,rsrc2,start,len) ((((rsrc2)<<(start)) & (MASK32((start),(len)))) | ((rsrc1) & (~MASK32((start),(len)))))
+#define MERGE32(rsrc1,rsrc2,start,len) (((len)==32)?(rsrc2):MERGE_C32(rsrc1,rsrc2,start,len))
+
+MarlonGateway::MarlonGateway(const char *device_name)
+{
+ m_got_lock = false;
+ int res;
+ res = CreateDeviceAccessHandler( device_name, MST_MARLON, &m_handler );
+ WLCT_UNREFERENCED_PARAM(res);
+}
+
+MarlonGateway::MarlonGateway(void* flashHandle)
+{
+ m_got_lock = false;
+ m_handler = flashHandle;
+}
+
+MarlonGateway::~MarlonGateway(void)
+{
+ int res = CloseDeviceAccessHandler(m_handler);
+
+ WLCT_UNREFERENCED_PARAM(res);
+// if (m_got_lock)
+// {
+// release_lock();
+// }
+}
+
+int MarlonGateway::runCommand(UCHAR flash_cmd, FLASH_PHASE phase, bool bWrite, DWORD addr, DWORD ulSize)
+{
+ int rc = 0;
+ // write the address if it needed (according to the instruction phase)
+ switch (phase)
+ {
+ case INSTRUCTION_PHASE:
+ break;
+ case INSTRUCTION_ADDRESS_PHASE:
+ rc = setAddr(addr);
+ break;
+ case INSTRUCTION_DATA_PHASE:
+ break;
+ case INSTRUCTION_ADDRESS_DATA_PHASE:
+ rc = setAddr(addr);
+ break;
+ }
+ if (rc != 0)
+ {
+ return rc;
+ }
+
+ u_int32_t opcode_n_len = 0;
+
+ // write the number of bytes to read or write
+ opcode_n_len = MERGE32(opcode_n_len, ulSize, 0, 16);
+
+ if (bWrite)
+ {
+ opcode_n_len = MERGE32(opcode_n_len, 1, BIT_OFFSET_WRITE_OP, 1);
+ }
+
+ switch (phase)
+ {
+ case INSTRUCTION_PHASE:
+ break;
+ case INSTRUCTION_ADDRESS_PHASE:
+ opcode_n_len = MERGE32(opcode_n_len, 1, BIT_OFFSET_ADDR_PHASE, 1);
+ break;
+ case INSTRUCTION_DATA_PHASE:
+ opcode_n_len = MERGE32(opcode_n_len, 1, BIT_OFFSET_DATA_PHASE, 1);
+ break;
+ case INSTRUCTION_ADDRESS_DATA_PHASE:
+ opcode_n_len = MERGE32(opcode_n_len, 1, BIT_OFFSET_DATA_PHASE, 1);
+ opcode_n_len = MERGE32(opcode_n_len, 1, BIT_OFFSET_ADDR_PHASE, 1);
+ break;
+ }
+ opcode_n_len = MERGE32(opcode_n_len, flash_cmd, BIT_OFFSET_INST, BIT_SIZE_INST);
+
+ rc = w(CR_FLASH_OPCODE, opcode_n_len);
+ if (rc != 0)
+ {
+ return rc;
+ }
+ rc = execute_cmd();
+ return rc;
+}
+
+int MarlonGateway::setAddr(DWORD addr)
+{
+ int rc = 0;
+ rc = w(CR_FLASH_ADDR, addr);
+ return rc;
+}
+
+
+int MarlonGateway::execute_cmd () const
+{
+ int rc = 0;
+ // BIT_GO
+ u_int32_t cmd = 0x40000000;
+ if (m_got_lock)
+ {
+ // BIT_GO & BIT_LOCK
+ cmd = 0xC0000000;
+ }
+
+ rc = w(CR_FLASH_STAT_CTL, cmd);
+ if (rc != 0)
+ {
+ return rc;
+ }
+ rc = wait_done();
+ return rc;
+}
+
+typedef struct _FOUR_BYTES_ {
+ union {
+ struct {
+ u_int8_t b[4];
+ }dummyStrct;
+
+ u_int32_t _dword_;
+ }dummyUnion;
+}FOUR_BYTES;
+
+int MarlonGateway::setData(const BYTE *buffer, DWORD size)
+{
+ int rc = 0;
+ u_int32_t word;
+ if ((size & 0x3) == 0)
+ { // size is module 4
+ rc = wb(CR_FLASH_DATA, size, buffer);
+ }
+ else
+ {
+ for (u_int32_t i = 0 ; i < size ; i += 4)
+ {
+ // check the case that size is not DWORD align
+ if (i+4 > size)
+ {
+ FOUR_BYTES fb;
+ fb.dummyUnion._dword_ = 0;
+ // copy the entire array (1, 2, or 3 bytes)
+ for (DWORD j = 0; j < (size-i); j++)
+ {
+ fb.dummyUnion.dummyStrct.b[j] = buffer[i+j];
+ }
+ word = fb.dummyUnion._dword_;
+ }
+ else
+ {
+ word = *((u_int32_t*)(&buffer[i]));
+ }
+ rc = w(CR_FLASH_DATA + i, word );
+ if (rc != 0)
+ {
+ return rc;
+ }
+ }
+ }
+ return rc;
+}
+
+int MarlonGateway::getData(BYTE *buffer, DWORD size)
+{
+ int rc = 0;
+ DWORD val;
+ DWORD size2 = (size >> 2) << 2;
+ DWORD remainder = size - size2;
+ rc = rb(CR_FLASH_DATA, size2, buffer);
+ return rc;
+
+ WLCT_UNREFERENCED_PARAM(val);
+ WLCT_UNREFERENCED_PARAM(remainder);
+}
+
+int MarlonGateway::wait_done (void) const
+{
+ int rc = 0;
+ DWORD val;
+ u_int32_t timeout = 0;
+ do {
+ rc = r(CR_FLASH_STAT_CTL, val);
+ if (rc != 0)
+ {
+ return rc;
+ }
+ if (EXTRACT32(val, BIT_OFFSET_BUSY, 1) == 0) {
+ return rc;
+ }
+ sleep_ms( 10 );
+ timeout+= 10;
+ } while (timeout <= 100);
+
+ ERR("wait_done:: timeout reached\n");
+ return (-1);
+}
+
+int MarlonGateway::boot_done(void) const
+{
+ int rc = 0;
+ return rc;
+}
+
+bool MarlonGateway::get_lock ()
+{
+ if (g_debug) DBG("Trying to get flash lock\n");
+ int rc = 0;
+ u_int32_t timeout = 0;
+ DWORD value;
+
+ do {
+ rc = r(CR_FLASH_STAT_CTL, value);
+ if (rc != 0)
+ {
+ return false;
+ }
+ // bit BIT_LOCK
+ if ( (value & 0x80000000) == 0) {
+ m_got_lock = true;
+ if (g_debug) DBG("Done\n");
+ return true;
+ }
+ sleep_ms( 10 );
+ timeout++;
+ } while (timeout <= 10 );
+
+ if (g_debug) DBG("Failed. Semaphore is 0x%04x\n", (unsigned int)value);
+ return false;
+}
+
+int MarlonGateway::force_lock ()
+{
+ int rc = 0;
+ //w (CR_FLASH_STAT_CTL, 1<<15);
+ m_got_lock = true;
+ if (g_debug) DBG("Forced flash lock\n");
+ return rc;
+}
+
+int MarlonGateway::release_lock()
+{
+ int rc = 0;
+ DWORD val;
+ if ( m_got_lock )
+ {
+ rc = r(CR_FLASH_STAT_CTL, val);
+ if (rc != 0)
+ {
+ return rc;
+ }
+ rc = w(CR_FLASH_STAT_CTL, val & 0x7fffffff);
+ m_got_lock = false;
+ if (g_debug) DBG("Released flash lock\n");
+ }
+ return rc;
+}
+
+int MarlonGateway::w(u_int32_t offset, DWORD val) const
+{
+ int rc = 0;
+ rc = WlctAccssWrite(m_handler, offset, val);
+ if( 0 != rc ) {
+ ERR("Failed writing offset 0x%04x rc=%d\n", offset, rc);
+ }
+ return rc;
+}
+
+int MarlonGateway::r(u_int32_t offset, DWORD & val) const
+{
+ int rc = 0;
+ rc = WlctAccssRead(m_handler, offset, val);
+ if( 0 != rc ) {
+ ERR("Failed reading offset 0x%04x rc=%d\n", offset, rc);
+ }
+ return rc;
+}
+
+int MarlonGateway::wb(u_int32_t offset, DWORD size, const BYTE *buffer)
+{
+ int rc = 0;
+ rc = writeBlock(m_handler, offset, size, (char*)buffer);
+ if( 0 != rc ) {
+ ERR("Failed writing offset 0x%04x rc=%d\n", offset, rc);
+ }
+ return rc;
+}
+
+int MarlonGateway::rb(u_int32_t offset, DWORD size, const BYTE *buffer)
+{
+ int rc = 0;
+ rc = readBlock(m_handler, offset, size, (char*)buffer);
+ if( 0 != rc ) {
+ ERR("Failed reading offset 0x%04x rc=%d\n", offset, rc);
+ }
+ return rc;
+}
+
diff --git a/debug-tools/lib/FlashAcss/MarlonGateway.h b/debug-tools/lib/FlashAcss/MarlonGateway.h
new file mode 100644
index 0000000..6d275b2
--- /dev/null
+++ b/debug-tools/lib/FlashAcss/MarlonGateway.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+#include "flashacss.h"
+
+class MarlonGateway : public flash_gateway
+{
+public:
+ MarlonGateway(const char *device_name);
+ MarlonGateway(void* flashHandle);
+ virtual ~MarlonGateway(void);
+ virtual int runCommand(UCHAR flash_cmd, FLASH_PHASE phase, bool bWrite, DWORD addr, DWORD ulSize);
+ virtual int setData(const BYTE *buffer, DWORD size);
+ virtual int getData(BYTE *buffer, DWORD size);
+ virtual int wait_done (void) const;
+ virtual int boot_done(void) const;
+ virtual bool get_lock ();
+ virtual int force_lock ();
+ virtual int release_lock();
+
+private:
+
+ int setAddr(DWORD addr);
+// void setSize(DWORD size);
+ int setCommand(UCHAR cmd, FLASH_PHASE phase, bool bWrite);
+
+ int wb(u_int32_t offset, DWORD size, const BYTE *buffer);
+ int rb(u_int32_t offset, DWORD size, const BYTE *buffer);
+ int r(u_int32_t offset, DWORD & val) const;
+ int w(u_int32_t offset, DWORD val) const;
+ int execute_cmd() const;
+
+ bool m_got_lock;
+
+ enum constants{
+ CR_USER = 0x880000,
+#ifndef MARLON_B0
+ CR_FLASH_DATA = CR_USER + 0xA8,
+ CR_FLASH_ADDR = CR_USER + 0x1B0,
+ CR_FLASH_OPCODE = CR_USER + 0x1AC,
+ CR_FLASH_STAT_CTL = CR_USER + 0x1A8,
+#else
+ CR_FLASH_DATA = CR_USER + 0x5C,
+ CR_FLASH_ADDR = CR_USER + 0x164,
+ CR_FLASH_OPCODE = CR_USER + 0x160,
+ CR_FLASH_STAT_CTL = CR_USER + 0x15C,
+#endif // MARLON_B0
+
+ // CR_FLASH_OPCODE
+ BIT_OFFSET_INST = 16,
+ BIT_SIZE_INST = 8,
+ BIT_OFFSET_ADDR_PHASE = 24,
+ BIT_OFFSET_DATA_PHASE = 25,
+ BIT_OFFSET_WRITE_OP = 31,
+
+ BIT_FLASH_STATUS_OFFSET = 0,
+ BIT_FLASH_STATUS_SIZE = 8,
+ BIT_OFFSET_BUSY = 29,
+ BIT_GO = 30,
+ BIT_LOCK = 31,
+ };
+
+};
diff --git a/debug-tools/lib/FlashAcss/SparrowGateway.cpp b/debug-tools/lib/FlashAcss/SparrowGateway.cpp
new file mode 100644
index 0000000..2146643
--- /dev/null
+++ b/debug-tools/lib/FlashAcss/SparrowGateway.cpp
@@ -0,0 +1,335 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include "SparrowGateway.h"
+
+#define ONES32(size) ((size)?(0xffffffff>>(32-(size))):0)
+#define MASK32(offset,size) (ONES32(size)<<(offset))
+
+#define EXTRACT_C32(source,offset,size) ((((unsigned)(source))>>(offset)) & ONES32(size))
+#define EXTRACT32(src,start,len) (((len)==32)?(src):EXTRACT_C32(src,start,len))
+
+#define MERGE_C32(rsrc1,rsrc2,start,len) ((((rsrc2)<<(start)) & (MASK32((start),(len)))) | ((rsrc1) & (~MASK32((start),(len)))))
+#define MERGE32(rsrc1,rsrc2,start,len) (((len)==32)?(rsrc2):MERGE_C32(rsrc1,rsrc2,start,len))
+
+SparrowGateway::SparrowGateway(const char *device_name)
+{
+ m_got_lock = false;
+ int res;
+ res = CreateDeviceAccessHandler( device_name, MST_SPARROW, &m_handler );
+ WLCT_UNREFERENCED_PARAM(res);
+}
+
+SparrowGateway::SparrowGateway(void* flashHandle)
+{
+ m_got_lock = false;
+ m_handler = flashHandle;
+}
+
+SparrowGateway::~SparrowGateway(void)
+{
+ int res = CloseDeviceAccessHandler(m_handler);
+
+ WLCT_UNREFERENCED_PARAM(res);
+// if (m_got_lock)
+// {
+// release_lock();
+// }
+}
+
+int SparrowGateway::runCommand(UCHAR flash_cmd, FLASH_PHASE phase, bool bWrite, DWORD addr, DWORD ulSize)
+{
+ int rc = 0;
+ // write the address if it needed (according to the instruction phase)
+ switch (phase)
+ {
+ case INSTRUCTION_PHASE:
+ break;
+ case INSTRUCTION_ADDRESS_PHASE:
+ rc = setAddr(addr);
+ break;
+ case INSTRUCTION_DATA_PHASE:
+ break;
+ case INSTRUCTION_ADDRESS_DATA_PHASE:
+ rc = setAddr(addr);
+ break;
+ }
+ if (rc != 0)
+ {
+ return rc;
+ }
+
+ u_int32_t opcode_n_len = 0;
+
+ // write the number of bytes to read or write
+ opcode_n_len = MERGE32(opcode_n_len, ulSize, 0, 16);
+
+ if (bWrite)
+ {
+ opcode_n_len = MERGE32(opcode_n_len, 1, BIT_OFFSET_WRITE_OP, 1);
+ }
+
+ switch (phase)
+ {
+ case INSTRUCTION_PHASE:
+ break;
+ case INSTRUCTION_ADDRESS_PHASE:
+ opcode_n_len = MERGE32(opcode_n_len, 1, BIT_OFFSET_ADDR_PHASE, 1);
+ break;
+ case INSTRUCTION_DATA_PHASE:
+ opcode_n_len = MERGE32(opcode_n_len, 1, BIT_OFFSET_DATA_PHASE, 1);
+ break;
+ case INSTRUCTION_ADDRESS_DATA_PHASE:
+ opcode_n_len = MERGE32(opcode_n_len, 1, BIT_OFFSET_DATA_PHASE, 1);
+ opcode_n_len = MERGE32(opcode_n_len, 1, BIT_OFFSET_ADDR_PHASE, 1);
+ break;
+ }
+ opcode_n_len = MERGE32(opcode_n_len, flash_cmd, BIT_OFFSET_INST, BIT_SIZE_INST);
+
+ rc = w(CR_FLASH_OPCODE, opcode_n_len);
+ if (rc != 0)
+ {
+ return rc;
+ }
+ rc = execute_cmd();
+ return rc;
+}
+
+int SparrowGateway::setAddr(DWORD addr)
+{
+ int rc = 0;
+ rc = w(CR_FLASH_ADDR, addr);
+ return rc;
+}
+
+
+int SparrowGateway::execute_cmd () const
+{
+ int rc = 0;
+ // BIT_GO
+ u_int32_t cmd = 0x40000000;
+ if (m_got_lock)
+ {
+ // BIT_GO & BIT_LOCK
+ cmd = 0xC0000000;
+ }
+
+ rc = w(CR_FLASH_STAT_CTL, cmd);
+ if (rc != 0)
+ {
+ return rc;
+ }
+ rc = wait_done();
+ return rc;
+}
+
+typedef struct _FOUR_BYTES_ {
+ union {
+ struct {
+ u_int8_t b[4];
+ }dummyStrct;
+
+ u_int32_t _dword_;
+ }dummyUnion;
+}FOUR_BYTES;
+
+int SparrowGateway::setData(const BYTE *buffer, DWORD size)
+{
+ int rc = 0;
+ u_int32_t word;
+ if ((size & 0x3) == 0)
+ { // size is module 4
+ rc = wb(CR_FLASH_DATA, size, buffer);
+ }
+ else
+ {
+ for (u_int32_t i = 0 ; i < size ; i += 4)
+ {
+ // check the case that size is not DWORD align
+ if (i+4 > size)
+ {
+ FOUR_BYTES fb;
+ fb.dummyUnion._dword_ = 0;
+ // copy the entire array (1, 2, or 3 bytes)
+ for (DWORD j = 0; j < (size-i); j++)
+ {
+ fb.dummyUnion.dummyStrct.b[j] = buffer[i+j];
+ }
+ word = fb.dummyUnion._dword_;
+ }
+ else
+ {
+ word = *((u_int32_t*)(&buffer[i]));
+ }
+ rc = w(CR_FLASH_DATA + i, word );
+ if (rc != 0)
+ {
+ return rc;
+ }
+ }
+ }
+ return rc;
+}
+
+int SparrowGateway::getData(BYTE *buffer, DWORD size)
+{
+ int rc = 0;
+ DWORD val;
+ DWORD size2 = (size >> 2) << 2;
+ DWORD remainder = size - size2;
+ rc = rb(CR_FLASH_DATA, size2, buffer);
+ return rc;
+
+ WLCT_UNREFERENCED_PARAM(val);
+ WLCT_UNREFERENCED_PARAM(remainder);
+}
+
+int SparrowGateway::wait_done (void) const
+{
+ int rc = 0;
+ DWORD val;
+ u_int32_t timeout = 0;
+ do {
+ rc = r(CR_FLASH_STAT_CTL, val);
+ if (rc != 0)
+ {
+ return rc;
+ }
+ if (EXTRACT32(val, BIT_OFFSET_BUSY, 1) == 0) {
+ return rc;
+ }
+ sleep_ms( 10 );
+ timeout+= 10;
+ } while (timeout <= 100);
+
+ ERR("wait_done:: timeout reached\n");
+ return (-1);
+}
+
+int SparrowGateway::boot_done(void) const
+{
+ int rc = 0;
+ return rc;
+}
+
+bool SparrowGateway::get_lock ()
+{
+ if (g_debug) DBG("Trying to get flash lock\n");
+ int rc = 0;
+ u_int32_t timeout = 0;
+ DWORD value;
+
+ do {
+ rc = r(CR_FLASH_STAT_CTL, value);
+ if (rc != 0)
+ {
+ return false;
+ }
+ // bit BIT_LOCK
+ if ( (value & 0x80000000) == 0) {
+ m_got_lock = true;
+ if (g_debug) DBG("Done\n");
+ return true;
+ }
+ sleep_ms( 10 );
+ timeout++;
+ } while (timeout <= 10 );
+
+ if (g_debug) DBG("Failed. Semaphore is 0x%04x\n", (unsigned int)value);
+ return false;
+}
+
+int SparrowGateway::force_lock ()
+{
+ int rc = 0;
+ //w (CR_FLASH_STAT_CTL, 1<<15);
+ m_got_lock = true;
+ if (g_debug) DBG("Forced flash lock\n");
+ return rc;
+}
+
+int SparrowGateway::release_lock()
+{
+ int rc = 0;
+ DWORD val;
+ if ( m_got_lock )
+ {
+ rc = r(CR_FLASH_STAT_CTL, val);
+ if (rc != 0)
+ {
+ return rc;
+ }
+ rc = w(CR_FLASH_STAT_CTL, val & 0x7fffffff);
+ m_got_lock = false;
+ if (g_debug) DBG("Released flash lock\n");
+ }
+ return rc;
+}
+
+int SparrowGateway::w(u_int32_t offset, DWORD val) const
+{
+ int rc = 0;
+ rc = WlctAccssWrite(m_handler, offset, val);
+ if( 0 != rc ) {
+ ERR("Failed writing offset 0x%04x rc=%d\n", offset, rc);
+ }
+ return rc;
+}
+
+int SparrowGateway::r(u_int32_t offset, DWORD & val) const
+{
+ int rc = 0;
+ rc = WlctAccssRead(m_handler, offset, val);
+ if( 0 != rc ) {
+ ERR("Failed reading offset 0x%04x rc=%d\n", offset, rc);
+ }
+ return rc;
+}
+
+int SparrowGateway::wb(u_int32_t offset, DWORD size, const BYTE *buffer)
+{
+ int rc = 0;
+ rc = writeBlock(m_handler, offset, size, (char*)buffer);
+ if( 0 != rc ) {
+ ERR("Failed writing offset 0x%04x rc=%d\n", offset, rc);
+ }
+ return rc;
+}
+
+int SparrowGateway::rb(u_int32_t offset, DWORD size, const BYTE *buffer)
+{
+ int rc = 0;
+ rc = readBlock(m_handler, offset, size, (char*)buffer);
+ if( 0 != rc ) {
+ ERR("Failed reading offset 0x%04x rc=%d\n", offset, rc);
+ }
+ return rc;
+}
+
diff --git a/debug-tools/lib/FlashAcss/SparrowGateway.h b/debug-tools/lib/FlashAcss/SparrowGateway.h
new file mode 100644
index 0000000..1d293ba
--- /dev/null
+++ b/debug-tools/lib/FlashAcss/SparrowGateway.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+#include "flashacss.h"
+
+class SparrowGateway : public flash_gateway
+{
+public:
+ SparrowGateway(const char *device_name);
+ SparrowGateway(void* flashHandle);
+ virtual ~SparrowGateway(void);
+ virtual int runCommand(UCHAR flash_cmd, FLASH_PHASE phase, bool bWrite, DWORD addr, DWORD ulSize);
+ virtual int setData(const BYTE *buffer, DWORD size);
+ virtual int getData(BYTE *buffer, DWORD size);
+ virtual int wait_done (void) const;
+ virtual int boot_done(void) const;
+ virtual bool get_lock ();
+ virtual int force_lock ();
+ virtual int release_lock();
+
+private:
+
+ int setAddr(DWORD addr);
+// void setSize(DWORD size);
+ int setCommand(UCHAR cmd, FLASH_PHASE phase, bool bWrite);
+
+ int wb(u_int32_t offset, DWORD size, const BYTE *buffer);
+ int rb(u_int32_t offset, DWORD size, const BYTE *buffer);
+ int r(u_int32_t offset, DWORD & val) const;
+ int w(u_int32_t offset, DWORD val) const;
+ int execute_cmd() const;
+
+ bool m_got_lock;
+
+ enum constants{
+ CR_USER = 0x880000,
+#ifndef MARLON_B0
+ CR_FLASH_DATA = CR_USER + 0xA8,
+ CR_FLASH_ADDR = CR_USER + 0x1B0,
+ CR_FLASH_OPCODE = CR_USER + 0x1AC,
+ CR_FLASH_STAT_CTL = CR_USER + 0x1A8,
+#else
+ CR_FLASH_DATA = CR_USER + 0x5C,
+ CR_FLASH_ADDR = CR_USER + 0x164,
+ CR_FLASH_OPCODE = CR_USER + 0x160,
+ CR_FLASH_STAT_CTL = CR_USER + 0x15C,
+#endif // MARLON_B0
+
+ // CR_FLASH_OPCODE
+ BIT_OFFSET_INST = 16,
+ BIT_SIZE_INST = 8,
+ BIT_OFFSET_ADDR_PHASE = 24,
+ BIT_OFFSET_DATA_PHASE = 25,
+ BIT_OFFSET_WRITE_OP = 31,
+
+ BIT_FLASH_STATUS_OFFSET = 0,
+ BIT_FLASH_STATUS_SIZE = 8,
+ BIT_OFFSET_BUSY = 29,
+ BIT_GO = 30,
+ BIT_LOCK = 31,
+ };
+
+};
diff --git a/debug-tools/lib/FlashAcss/flash.cpp b/debug-tools/lib/FlashAcss/flash.cpp
new file mode 100644
index 0000000..63c8c79
--- /dev/null
+++ b/debug-tools/lib/FlashAcss/flash.cpp
@@ -0,0 +1,852 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "flash.h"
+#include "wlct_os.h"
+
+bool g_debug = false;
+
+void flash_base::set_exit_flag(bool bExit)
+{
+ m_bExit = bExit;
+}
+
+flash::flash(DType device_type)
+ :flash_base(device_type)
+{
+ m_pDeviceAccss = NULL;
+ m_pFlashAccss = NULL;
+ if (device_type == MST_SPARROW)
+ m_size = FLASH_SIZE_SPARROW;
+ if (device_type == MST_MARLON)
+ m_size = FLASH_SIZE_MARLON;
+ if (device_type == MST_TALYN)
+ m_size = FLASH_SIZE_TALYN;
+ m_hw_read_chunk_size = 256;
+ m_hw_write_chunk_size = 256;
+ m_page_erased = new bool [m_size / FLASH_PAGE_SIZE];
+ memset(m_page_erased, 0, m_size / FLASH_PAGE_SIZE);
+ m_buffer = NULL;
+ update_erased_flash(false);
+
+ flag_reading_not_done = false;
+ m_address = 0;
+ m_length = 0;
+}
+
+flash::~flash(void)
+{
+ if (m_pFlashAccss != NULL)
+ {
+ wfa_release_lock(m_pFlashAccss);
+ close ();
+ }
+
+ free_buffer();
+
+ delete m_page_erased;
+}
+
+void flash::free_buffer ()
+{
+ if (m_buffer != NULL)
+ {
+ delete [] m_buffer;
+ }
+}
+
+#ifdef _WINDOWS
+void readThread(void* pFlashDevice)
+#else
+ void *readThread(void* pFlashDevice)
+#endif
+{
+ flash *pFlash = (flash*)pFlashDevice;
+ pFlash->set_flag_reading_not_done(true);
+
+ u_int32_t address = pFlash->get_address();
+ u_int32_t length = pFlash->get_length();
+ BYTE* buffer = (BYTE*)pFlash->get_buffer_ptr();
+
+ pFlash->read( address , length , buffer);
+
+ pFlash->set_flag_reading_not_done(false);
+#ifndef _WINDOWS
+ return NULL;
+#endif
+}
+
+int flash::read_async( const u_int32_t address, const u_int32_t length )
+{
+ if (flag_reading_not_done)
+ {
+ return BUFFER_NOT_READY;
+ }
+
+ m_address = address;
+ m_length = length;
+
+ free_buffer(); //free memory if already allocated before
+ m_buffer = new BYTE[length];
+
+#ifdef _WINDOWS
+ m_thread = (HANDLE)_beginthread(readThread, 0 , this);
+#else
+ if (0 != pthread_create(&m_thread, NULL, readThread, this))
+ {
+ ERR("Failed to create Read thread\n");
+ free_buffer();
+ return BUFFER_NOT_READY;
+ }
+#endif
+
+ return BUFFER_OK;
+}
+
+int flash::open (const char *device_name, DType dtype, bool ignore_lock)
+{
+ int res = 0;
+ res = CreateDeviceAccessHandler( device_name, dtype, &m_pDeviceAccss);
+ if (res != 0)
+ return res;
+ deviceType = dtype;
+ res = wfa_create_flash_access_handler(dtype, m_pDeviceAccss, &m_pFlashAccss);
+ if (res != 0)
+ return res;
+
+ res = wfa_boot_done(m_pFlashAccss);
+ if (res != 0)
+ return res;
+
+ if (ignore_lock) {
+ res = wfa_force_lock(m_pFlashAccss);
+ } else {
+ if (wfa_get_lock(m_pFlashAccss) == false) {
+ ERR("Failed getting Flash lock."
+ "Use -ignore_lock option to ignore locking mechanism\n");
+ return (-1);
+ }
+ }
+
+ res = retrive_info();
+ return res;
+}
+
+int flash::open (void *m_pDeviceAccss, DType dtype, bool ignore_lock)
+{
+ int res = 0;
+ if (m_pDeviceAccss == NULL)
+ return -1;
+ deviceType = dtype;
+ res = wfa_create_flash_access_handler(dtype, m_pDeviceAccss, &m_pFlashAccss);
+ if (res != 0)
+ return res;
+
+ res = wfa_boot_done(m_pFlashAccss);
+ if (res != 0)
+ return res;
+
+ if (ignore_lock) {
+ res = wfa_force_lock(m_pFlashAccss);
+ } else {
+ if (wfa_get_lock(m_pFlashAccss) == false) {
+ ERR("Failed getting Flash lock."
+ "Use -ignore_lock option to ignore locking mechanism\n");
+ return (-1);
+ }
+ }
+
+ res = retrive_info();
+ return res;
+}
+
+void flash::close ()
+{
+ if (m_pFlashAccss)
+ {
+ wfa_close_flash_access_handler(m_pFlashAccss);
+ m_pFlashAccss = NULL;
+ }
+ int res = CloseDeviceAccessHandler(m_pDeviceAccss);
+
+ WLCT_UNREFERENCED_PARAM(res);
+ if (g_debug ) DBG("Closed device\n");
+}
+
+int flash::retrive_info()
+{
+ int res = 0;
+ res = wfa_run_command(m_pFlashAccss, FC_RDID, INSTRUCTION_DATA_PHASE, false, 0, 20);
+ if (res != 0)
+ {
+#ifdef _WINDOWS /* TODO: Handle error in linux */
+ // 1 - OK
+ // 2 = cancel
+ //int mb = MessageBox(NULL, L"Failed access to flash.\nPress OK to continue or\nCancel to abort.", L"Error", MB_OKCANCEL );
+ //if (mb == 2)
+ {
+ return res;
+ }
+ //res = 0;
+#endif
+ }
+
+ memset((void*)&m_info, 0, sizeof(m_info));
+ res = wfa_get_data(m_pFlashAccss,(BYTE*)&m_info, sizeof(m_info) - 4);
+ if (res != 0)
+ return 0;
+
+ INFO ("Flash Manufactured by ");
+ switch (m_info.manufacturer_id)
+ {
+ case 0x20:
+ {
+ INFO("Numonyx ");
+ switch (m_info.device_id1)
+ {
+ case 0x80 :
+ {
+ INFO("M25PE ");
+ break;
+ }
+ case 0x20 :
+ {
+ INFO("M25P ");
+ break;
+ }
+ default : INFO("Unknown device ID ");
+ }
+
+ switch (m_info.device_id2)
+ {
+ case 0x11 :
+ {
+ INFO("Capacity of 1Mbits ");
+ break;
+ }
+ case 0x12 :
+ {
+ INFO("Capacity of 2Mbits ");
+ break;
+ }
+ case 0x14 :
+ {
+ INFO("Capacity of 8Mbits ");
+ break;
+ }
+ default : INFO("Unknown capacity ");
+ }
+
+ break;
+ }
+
+ case 0xC2:
+ {
+ INFO("Macronix ");
+ switch (m_info.device_id1)
+ {
+ case 0x20 :
+ {
+ INFO("MX25L8006E ");
+ break;
+ }
+ default : INFO("Unknown device ID ");
+ }
+
+ switch (m_info.device_id2)
+ {
+ case 0x11 :
+ {
+ INFO("Capacity of 1Mbits ");
+ break;
+ }
+ case 0x12 :
+ {
+ INFO("Capacity of 2Mbits ");
+ break;
+ }
+ case 0x13 :
+ {
+ INFO("Capacity of 4Mbits ");
+ break;
+ }
+ case 0x14 :
+ {
+ INFO("Capacity of 8Mbits ");
+ break;
+ }
+ default : INFO("Unknown capacity ");
+ }
+
+ break;
+ }
+
+ case 0x1F:
+ {
+ INFO("Atmel ");
+ switch (m_info.device_id1)
+ {
+ case 0x43 :
+ {
+ INFO("AT25DF021 ");
+ break;
+ }
+ default : INFO("Unknown device ID ");
+ }
+ break;
+ }
+ default:
+ {
+ INFO("Unknown manufacturer");
+ }
+ }
+
+ //if (m_info.extended_string_length != 0) {
+ //INFO("Extended INFO %s ", m_info.extended_string);
+ //}
+ INFO("\n --------------------------- \n");
+ return res;
+}
+
+
+int flash::read( const u_int32_t address, const u_int32_t length, BYTE *buffer ) const
+{
+ int res = 0;
+ if (address & 0x1) {
+ ERR("address 0x%04x is not word aligned\n",address);
+ return -1;
+ }
+
+ if (length & 0x1) {
+ ERR("length 0x%04x is not word aligned\n",length);
+ return -1;
+ }
+ if (address + length > this->m_size) {
+ ERR("address 0x%04x + length 0x%04x exceeds flash size of 0x%04x\n",address,length,this->m_size);
+ //return -1;
+ }
+
+ u_int32_t offset = 0;
+ while (!m_bExit && offset < length )
+ {
+ u_int16_t current_size = FLASH_PAGE_SIZE - ((address + offset) & 0xff); // Part of a page
+ if (current_size > length ) {
+ current_size = (u_int16_t)length;
+ }
+
+ if (offset + current_size > length ) {
+ current_size = (u_int16_t)(length - offset);
+ }
+ //while ( offset < length ) {
+ // if( m_bExit ) {
+ // reruen(-1);
+ // }
+
+ // u_int32_t curr_length = min(m_hw_read_chunk_size, length - offset);
+ u_int32_t curr_address = address + offset;
+ if (g_debug) DBG("Reading 0x%04x bytes from address 0x%04x\n", current_size, curr_address);
+
+ res = wfa_run_command(m_pFlashAccss, FC_READ, INSTRUCTION_ADDRESS_DATA_PHASE, false, curr_address, current_size);
+ if (res != 0)
+ break;
+ res = wfa_get_data(m_pFlashAccss,buffer + offset, current_size);
+ if (res != 0)
+ break;
+ offset += current_size;
+ }
+ return res;
+}
+
+int flash::write( const u_int32_t address, const u_int32_t length, const BYTE *buffer, bool verify )
+{
+
+ //unused param
+ (void)verify;
+ int res = -1;
+
+ res = write_wen();
+ if (res != 0)
+ return res;
+
+ u_int32_t offset = 0;
+ while (!m_bExit && offset < length )
+ {
+ u_int16_t current_size = FLASH_PAGE_SIZE - ((address + offset) & 0xff); // Part of a page
+ if (current_size > length ) {
+ current_size = (u_int16_t)length;
+ }
+
+ if (offset + current_size > length ) {
+ current_size = (u_int16_t)(length - offset);
+ }
+
+ // u_int32_t curr_length = min(m_hw_read_chunk_size, length - offset);
+ u_int32_t curr_address = address + offset;
+ if (g_debug) DBG("Reading 0x%04x bytes from address 0x%04x\n", current_size, curr_address);
+
+ res = wfa_set_data(m_pFlashAccss,buffer + offset, current_size);
+ if (res != 0)
+ break;
+ res = wfa_run_command(m_pFlashAccss, FC_PW, INSTRUCTION_ADDRESS_DATA_PHASE, true, curr_address, current_size);
+ if (res != 0)
+ break;
+ offset += current_size;
+ }
+ return res;
+}
+
+int flash::program( const u_int32_t address, const u_int32_t length, const BYTE *buffer, bool verify )
+{
+ int res = -1;
+
+ // u_int8_t type = m_erased ? FC_PP : FC_PW;
+ // u_int8_t type = FC_PW;
+ u_int8_t type = FC_PP;
+
+ if (address & 0x1) {
+ ERR("address 0x%04x is not word aligned\n",address);
+ return -1;
+ }
+
+ if (length & 0x1) {
+ ERR("length 0x%04x is not word aligned\n",length);
+ return -1;
+ }
+ if (address + length > this->m_size) {
+ ERR("address 0x%04x + length 0x%04x exceeds flash size of 0x%04x\n",address,length,this->m_size);
+ return -1;
+ }
+
+ u_int32_t offset = 0;
+ BYTE *verify_buffer = new BYTE[FLASH_PAGE_SIZE];
+ u_int32_t loop = 0;
+ bool dbg_verify = false;
+ while (!m_bExit && offset < length )
+ {
+ loop++;
+ if (loop%50 == 0 || loop < 10)
+ dbg_verify = true;
+ else
+ dbg_verify = false;
+
+ u_int16_t current_size = FLASH_PAGE_SIZE - ((address + offset) & 0xff); // Part of a page
+ if (current_size > length ) {
+ current_size = (u_int16_t)length;
+ }
+
+ if (offset + current_size > length ) {
+ current_size = (u_int16_t)(length - offset);
+ }
+
+ if (type == FC_PP) {
+ bool all_ff = true;
+ for (u_int32_t i = 0; i < current_size ; i+=2) {
+ if ( (*(u_int16_t*)(buffer + offset + i)) != (u_int16_t)(-1) ) {
+ all_ff = false;
+ break;
+ }
+ }
+
+ if (all_ff) {
+ if (g_debug) {
+ DBG(" - skipped empty page 0x%04x - ", address+offset);
+ } else {
+ INFO("\rSkip - ");
+ }
+ offset += current_size;
+ INFO("%03.2f%%", (float)offset / (float)length * 100);
+ if (g_debug) DBG("\n");
+ continue;
+ }
+ }
+
+ INFO("\rWrite - ");
+ res = page_write_program(address+offset, current_size, &buffer[offset], type);
+ if (res != 0)
+ break;
+
+ if (verify || dbg_verify) {
+ INFO("\rRead - ");
+ res = read(address+offset, current_size, verify_buffer);
+ if (res != 0)
+ break;
+ INFO("\rVerify - ");
+ if( memcmp(&buffer[offset], verify_buffer, current_size) != 0 ) {
+ ERR("Data verification failed on address 0x%04x length 0x%03x\n", address+offset, current_size);
+ res = -1;
+ break;
+ }
+ }
+
+ offset += current_size;
+ INFO("%03.2f%%", (float)offset / (float)length * 100);
+ if (g_debug) DBG("\n");
+ }
+ delete[] verify_buffer;
+ printf("\n");
+ return res;
+}
+
+int flash::page_write_program( const u_int32_t address, const u_int16_t length, const BYTE *buffer, u_int8_t type )
+{
+ int res = 0;
+ if( m_bExit ) {
+ return (-1);
+ }
+
+ if (type == FC_PP) {
+ if ( !is_erased(address) ) {
+ res = sub_sector_erase( address );
+// sector_erase( address );
+ }
+ if (g_debug) DBG("Programing page address 0x%04x length 0x%03x\n", address, length);
+ }
+ else {
+ if (g_debug) DBG("Writing page address 0x%04x length 0x%03x\n", address, length);
+ }
+
+ res = write_wen();
+ if (res != 0)
+ return res;
+ res = wfa_set_data(m_pFlashAccss, buffer, length);
+ if (res != 0)
+ return res;
+ res = wfa_run_command(m_pFlashAccss, type, INSTRUCTION_ADDRESS_DATA_PHASE, true, address, length);
+ if (res != 0)
+ return res;
+
+ res = wait_wip();
+ return res;
+}
+
+int flash::write_wen (void) const
+{
+ int res = 0;
+// execute_cmd(0x0106);
+ res = wfa_run_command(m_pFlashAccss, FC_WREN, INSTRUCTION_PHASE, true, 0, 0);
+ return res;
+}
+
+int flash::erase (void)
+{
+ int res = 0;
+ res = wfa_boot_done(m_pFlashAccss);
+ if (res != 0)
+ return res;
+ res = write_wen();
+ if (res != 0)
+ return res;
+
+ //erase
+ res = wfa_run_command(m_pFlashAccss, FC_BE, INSTRUCTION_PHASE, true, 0, 0);
+ if (res != 0)
+ return res;
+
+ res = wait_wip();
+ if (res != 0)
+ return res;
+ update_erased_flash( true );
+ return res;
+}
+
+int flash::page_erase(u_int32_t address)
+{
+ int res = 0;
+ write_wen();
+ if (res != 0)
+ return res;
+
+ res = wfa_run_command(m_pFlashAccss, FC_PE, INSTRUCTION_ADDRESS_PHASE, true, address, 0);
+ if (res != 0)
+ return res;
+ res = wait_wip();
+ if (res != 0)
+ return res;
+ if (g_debug) DBG("Cmd is 0x%04x, Status is 0x%04x\n",FC_PE, get_status() );
+ if (g_debug) DBG("Erased page address 0x%04x\n", address);
+ update_erased_page(address, true);
+ return res;
+}
+
+int flash::sector_erase(u_int32_t address)
+{
+ int res = 0;
+ res = write_wen();
+ if (res != 0)
+ return res;
+
+ res = wfa_run_command(m_pFlashAccss, FC_SE, INSTRUCTION_ADDRESS_PHASE, true, address, 0);
+ if (res != 0)
+ return res;
+ res = wait_wip();
+ if (res != 0)
+ return res;
+ if (g_debug) DBG("Cmd is 0x%04x, Status is 0x%04x\n",FC_SE, get_status() );
+ if (g_debug) DBG("Erased sector address 0x%04x\n", address);
+ update_erased_sector(address, true);
+ return res;
+}
+
+int flash::sub_sector_erase(u_int32_t address)
+{
+ int res = 0;
+ printf("Erasing sub_sector %d\n", address / SUB_SECTOR_SIZE);
+ res = write_wen();
+ if (res != 0)
+ return res;
+
+ res = wfa_run_command(m_pFlashAccss, FC_SSE, INSTRUCTION_ADDRESS_PHASE, true, address, 0);
+ if (res != 0)
+ return res;
+ res = wait_wip();
+ if (res != 0)
+ return res;
+ if (g_debug) DBG("Cmd is 0x%04x, Status is 0x%04x\n",FC_SSE, get_status() );
+ if (g_debug) {
+ DBG(" - Erased sub_sector address 0x%04x - ", address);
+ } else {
+ INFO("\rErase - ");
+ }
+ update_erased_sub_sector(address, true);
+ return res;
+}
+
+u_int8_t flash::get_status() const
+{
+ int res = 0;
+ res = wfa_run_command(m_pFlashAccss, FC_RDSR, INSTRUCTION_DATA_PHASE, false, 0, 1);
+
+ u_int32_t value;
+ unsigned long size = sizeof(u_int32_t);
+ res = wfa_get_data(m_pFlashAccss, (BYTE*)&value, size);
+
+ WLCT_UNREFERENCED_PARAM(res);
+ return (u_int8_t)value;
+}
+
+int flash::wait_wip (void) const
+{
+ int res = 0;
+ u_int16_t value;
+ u_int32_t timeout = 0;
+ WLCT_UNREFERENCED_PARAM(res);
+
+ do {
+ value = get_status();
+ if (EXTRACT(value, 0, 1) == 0) {
+ if (EXTRACT(value, 1, 1) == 1 ) {
+ ERR("WIP bit is 0 but WEL bit is 1. Status = 0x%04x\n", value);
+ return (-1);
+ }
+ return 0;
+ }
+ timeout++;
+ } while (timeout <= 1000000 );
+
+ ERR("wait_wip:: timeout reached\n");
+ return -1;
+}
+
+void flash::update_erased_page (u_int32_t offset, bool erased )
+{
+ m_page_erased[offset/FLASH_PAGE_SIZE] = erased;
+}
+
+void flash::update_erased_sub_sector (u_int32_t offset, bool erased )
+{
+ u_int32_t page_offset = offset / SUB_SECTOR_SIZE * SUB_SECTOR_SIZE;
+ for (u_int32_t i =0; i < PAGES_PER_SUB_SECTOR; i++) {
+ update_erased_page( page_offset + i * FLASH_PAGE_SIZE, erased );
+ }
+}
+
+void flash::update_erased_sector (u_int32_t offset, bool erased )
+{
+ u_int32_t page_offset = offset / SECTOR_SIZE * SECTOR_SIZE;
+ for (u_int32_t i =0; i < SUB_SECTORS_PER_SECTOR; i++) {
+ update_erased_sub_sector( page_offset + i * SUB_SECTOR_SIZE, erased );
+ }
+}
+
+void flash::update_erased_flash (bool erased )
+{
+ for (u_int32_t i =0; i < SECTORS_PER_FLASH; i++) {
+ update_erased_sector( i * SECTOR_SIZE, erased );
+ }
+}
+
+bool flash::is_erased( u_int32_t page_offset ) const{
+ u_int32_t page_index = page_offset/FLASH_PAGE_SIZE;
+ bool erased = m_page_erased[page_index];
+ return erased;
+}
+
+void flash::clear_erased( u_int32_t page_offset ) {
+ u_int32_t page_index = page_offset/FLASH_PAGE_SIZE;
+ m_page_erased[page_index] = false;
+}
+
+int flash_file::open (const char *device_name, DType dtype, bool ignore_lock = true)
+{
+ //unused param
+ (void)ignore_lock;
+
+// m_device_name = device_name;
+ m_handler = fopen( device_name, "rb+");
+ m_buffer = new char [m_size];
+ if (0 == m_handler) { // File doesn't exist
+ if (g_debug) DBG("file %s type %d does not exist. Creating...\n", device_name, dtype);
+ m_handler = fopen( device_name, "wb");
+ if (0 == m_handler) {
+ ERR("Failed creating file %s type %d\n", device_name, dtype);
+ return (-1);
+ }
+ memset(m_buffer, 0, m_size);
+ } else {
+ int res = fread(m_buffer, 1, m_size, (FILE*)m_handler);
+ if( (u_int32_t)res != m_size ) {
+ ERR("Expected %d bytes and read %d bytes\n", m_size, res);
+ return (-1);
+ }
+ rewind((FILE*)m_handler);
+ //res = fclose((FILE*)m_handler);
+ //if (0 != res) {
+ // ERR("Failed closing file\n");
+ // return (-1);
+ //}
+ if (g_debug) DBG("Opened file %s type %d\n", device_name, dtype);
+ }
+ return 0;
+}
+
+void flash_file::close ()
+{
+ //m_handler = fopen( this->m_device_name.c_str(), "w");
+ //if (0 == m_handler) {
+ // ERR("Failed opening file for writing\n");
+ // return (-1);
+ //}
+
+
+ int res = fwrite(m_buffer, 1, m_size, (FILE*)m_handler);
+ if( (u_int32_t)res != m_size ) {
+ ERR("Expected %d bytes and wrote %d bytes\n", m_size, res);
+ return;
+ }
+
+ res = fclose((FILE*)m_handler);
+
+ if (0 != res) {
+ ERR("Failed closing device\n");
+ return;
+ }
+
+ if (g_debug ) DBG("Closed device\n");
+}
+
+int flash_file::erase (void)
+{
+ memset(m_buffer, 0xff, m_size);
+ this->update_erased_flash( true );
+ return 0;
+}
+
+flash_file::flash_file(DType device_type)
+ :flash(device_type)
+{
+ m_buffer = 0;
+}
+
+flash_file::~flash_file(void)
+{
+ if (0 != m_handler) {
+ close ();
+ m_handler = 0;
+ }
+ if (0 != m_buffer) {
+ delete m_buffer;
+ m_buffer = 0;
+ }
+}
+
+int flash_file::page_write_program( const u_int32_t address, const u_int16_t length, const BYTE *buffer, u_int8_t type )
+{
+ if( m_bExit ) {
+ return(-1);
+ }
+
+ if (type == FC_PP) {
+ if ( !this->is_erased(address) ) {
+ sub_sector_erase( address );
+ // sector_erase( address );
+ }
+ if (g_debug) DBG("Programing page address 0x%04x length 0x%03x\n", address, length);
+ }
+ else {
+ if (g_debug) DBG("Writing page address 0x%04x length 0x%03x\n", address, length);
+ }
+
+ memcpy(m_buffer+address, buffer, length);
+ return 0;
+}
+
+int flash_file::sub_sector_erase(u_int32_t address)
+{
+ printf("Erasing sub_sector %d\n", address / SUB_SECTOR_SIZE);
+
+ memset(m_buffer+address, 0xff, SUB_SECTOR_SIZE);
+ if (g_debug) {
+ DBG(" - Erased sub_sector address 0x%04x - ", address);
+ } else {
+ INFO("\rErase - ");
+ }
+ this->update_erased_sub_sector(address, true);
+ return 0;
+}
+
+int flash_file::read( const u_int32_t address, const u_int32_t length, BYTE *buffer ) const
+{
+ if (address & 0x1) {
+ ERR("address 0x%04x is not word aligned\n",address);
+ return(-1);
+ }
+
+ if (length & 0x1) {
+ ERR("length 0x%04x is not word aligned\n",length);
+ return(-1);
+ }
+
+ if (address + length > this->m_size) {
+ ERR("address 0x%04x + length 0x%04x exceeds flash size of 0x%04x\n",address,length,this->m_size);
+ return(-1);
+ }
+
+ memcpy(buffer, m_buffer+address, length);
+ return 0;
+}
diff --git a/debug-tools/lib/FlashAcss/flash.h b/debug-tools/lib/FlashAcss/flash.h
new file mode 100644
index 0000000..9625baf
--- /dev/null
+++ b/debug-tools/lib/FlashAcss/flash.h
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <string>
+#include "WlctPciAcss.h"
+#include "flashacss.h"
+
+#ifdef _WINDOWS
+#ifdef FLSHACSS_EXPORTS
+#define FLSHACSS_CPP_API __declspec(dllexport)
+#else
+#define FLSHACSS_CPP_API __declspec(dllimport)
+#endif
+#else //#ifdef _WINDOWS
+#define FLSHACSS_CPP_API
+#endif //#ifdef _WINDOWS
+
+#define BUFFER_NOT_READY -1
+#define BUFFER_OK 0
+
+extern "C"
+{
+class FLSHACSS_CPP_API flash_base
+{
+public:
+ enum {
+ //FLASH_SIZE_SWIFT = 256*1024,
+ FLASH_SIZE_SPARROW = 1024*512,
+ //FLASH_SIZE_MARLON = 1024*1024,
+ FLASH_SIZE_MARLON = 1024*512,
+ FLASH_SIZE_TALYN = 1024*512*4
+ };
+ flash_base(DType device_type)
+ {
+ m_bExit = false;
+ if (device_type == MST_SPARROW)
+ m_size = FLASH_SIZE_SPARROW;
+ if (device_type == MST_MARLON)
+ m_size = FLASH_SIZE_MARLON;
+ if (device_type == MST_TALYN)
+ m_size = FLASH_SIZE_TALYN;
+ };
+ virtual ~flash_base(void) {};
+ virtual int open (const char *device_name, DType dtype, bool ignore_lock) = 0;
+ virtual int open (void *m_pDeviceAccss, DType dtype, bool ignore_lock) = 0;
+ virtual void close () = 0;
+ virtual int read( const u_int32_t address, const u_int32_t length, BYTE *buffer ) const = 0;
+ virtual int write( const u_int32_t address, const u_int32_t length, const BYTE *buffer, bool verify ) = 0;
+ virtual int program( const u_int32_t address, const u_int32_t length, const BYTE *buffer, bool verify ) = 0;
+ virtual int erase (void) = 0;
+ virtual void clear_erased( u_int32_t page_offset ) = 0;
+
+ void set_exit_flag(bool bExit);
+ DType GetDeviceType()
+ {
+ return deviceType;
+ }
+
+ protected:
+ bool m_bExit;
+ DType deviceType;
+ u_int32_t m_size;
+ };
+
+ class FLSHACSS_CPP_API flash: public flash_base
+ {
+ public:
+ flash(DType device_type);
+ virtual ~flash(void);
+ virtual int open (const char *device_name, DType dtype, bool ignore_lock);
+ virtual int open (void *m_pDeviceAccss, DType dtype, bool ignore_lock);
+ virtual void close ();
+ virtual int read( const u_int32_t address, const u_int32_t length, BYTE *buffer ) const;
+ virtual int read_async( const u_int32_t address, const u_int32_t length);
+ int write( const u_int32_t address, const u_int32_t length, const BYTE *buffer, bool verify );
+ int program( const u_int32_t address, const u_int32_t length, const BYTE *buffer, bool verify );
+ virtual int erase (void);
+ bool get_flag_reading_not_done () {return flag_reading_not_done; };
+ void set_flag_reading_not_done (bool new_val) {flag_reading_not_done = new_val;};
+ void* get_buffer_ptr () {return m_buffer; };
+ void free_buffer ();
+
+ u_int32_t get_address () {return m_address; };
+ u_int32_t get_length () {return m_length; };
+
+
+ public:
+ enum {
+ FLASH_PAGE_SIZE = 256,
+ PAGES_PER_SUB_SECTOR = 16,
+ SUB_SECTOR_SIZE = PAGES_PER_SUB_SECTOR * FLASH_PAGE_SIZE,
+ SUB_SECTORS_PER_SECTOR = 16,
+ SECTOR_SIZE = SUB_SECTORS_PER_SECTOR * SUB_SECTOR_SIZE,
+#ifdef FLASH_256KB
+ SECTORS_PER_FLASH = 4, // support 1MB flash
+#else
+ //SECTORS_PER_FLASH = 16, // support 1MB flash
+ SECTORS_PER_FLASH = 8, // support 0.5MB flash
+#endif
+ };
+
+ public:
+ struct {
+ BYTE manufacturer_id;
+ BYTE device_id1;
+ BYTE device_id2;
+ BYTE extended_string_length;
+ char extended_string [256]; // maximal size
+ } m_info; // according to JEDEC standard
+
+ protected:
+ int page_erase(u_int32_t offset);
+ int sector_erase(u_int32_t address);
+ virtual int sub_sector_erase(u_int32_t address);
+ virtual int page_write_program( const u_int32_t address, const u_int16_t length, const BYTE *buffer, u_int8_t type );
+ int wait_wip (void) const;
+ int write_wen (void) const;
+ u_int8_t get_status(void) const;
+ void update_erased_page (u_int32_t offset, bool erased );
+ void update_erased_sub_sector (u_int32_t offset, bool erased );
+ void update_erased_sector (u_int32_t offset, bool erased );
+ void update_erased_flash ( bool erased );
+ bool is_erased( u_int32_t page_offset ) const;
+ void clear_erased( u_int32_t page_offset );
+ int retrive_info();
+
+ protected:
+ bool *m_page_erased;
+ u_int32_t m_hw_read_chunk_size;
+ u_int32_t m_hw_write_chunk_size;
+
+#if _WINDOWS
+ HANDLE m_thread;
+#else
+ pthread_t m_thread;
+#endif
+
+ protected:
+// string m_device_name;
+
+ protected:
+ enum FlashCommand {
+ FC_WREN = 0x06,
+ FC_WRDI = 0x04,
+ FC_RDID = 0x9F,
+ FC_RDSR = 0x05,
+ FC_WRLR = 0xE5,
+ FC_WRSR = 0x01,
+ FC_RDLR = 0xE8,
+ FC_READ = 0x03,
+ FC_FAST_READ = 0x0B,
+ FC_PW = 0x0A,
+ FC_PP = 0x02,
+ FC_PE = 0xDB,
+ FC_SSE = 0x20,
+ FC_SE = 0xD8,
+ FC_BE = 0xC7,
+ FC_DP = 0xB9,
+ FC_RDP = 0xAB
+ };
+ private:
+// flash_gateway* m_flash_gateway;
+ void* m_pDeviceAccss;
+ void* m_pFlashAccss;
+
+ bool flag_reading_not_done;
+ u_int32_t m_address;
+ u_int32_t m_length;
+ BYTE* m_buffer;
+ };
+
+
+ class FLSHACSS_CPP_API flash_file: public flash
+ {
+ public:
+ flash_file(DType device_type);
+ ~flash_file(void);
+ virtual int read( const u_int32_t address, const u_int32_t length, BYTE *buffer ) const;
+ virtual int erase ();
+ virtual int open (const char *device_name, DType dtype, bool ignore_lock);
+ virtual int open (void *m_pDeviceAccss, DType dtype, bool ignore_lock)
+ {
+ //do something with params
+ (void)m_pDeviceAccss;
+ (void)dtype;
+ (void)ignore_lock;
+ return -1;
+ }
+ virtual void close ();
+
+ private:
+ virtual int page_write_program( const u_int32_t address, const u_int16_t length, const BYTE *buffer, u_int8_t type );
+ virtual int sub_sector_erase(u_int32_t address);
+ private:
+ mutable char *m_buffer;
+ void *m_handler;
+ };
+};
diff --git a/debug-tools/lib/FlashAcss/flash_gateway.h b/debug-tools/lib/FlashAcss/flash_gateway.h
new file mode 100644
index 0000000..ee86d7a
--- /dev/null
+++ b/debug-tools/lib/FlashAcss/flash_gateway.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+#include "flashacss.h"
+#include "WlctPciAcss.h"
+
+//using namespace std;
+
+#define ONES16(size) ((size)?(0xffff>>(16-(size))):0)
+#define MASK16(offset,size) (ONES16(size)<<(offset))
+
+#define EXTRACT_C(source,offset,size) ((((unsigned)(source))>>(offset)) & ONES16(size))
+#define EXTRACT(src,start,len) (((len)==16)?(src):EXTRACT_C(src,start,len))
+
+#define MERGE_C(rsrc1,rsrc2,start,len) ((((rsrc2)<<(start)) & (MASK16((start),(len)))) | ((rsrc1) & (~MASK16((start),(len)))))
+#define MERGE(rsrc1,rsrc2,start,len) (((len)==16)?(rsrc2):MERGE_C(rsrc1,rsrc2,start,len))
+
+typedef enum _FlashGatewayType
+{
+ FPT_SPARROW,
+ FPT_MARLON
+
+}FlashGatewayType;
+
+typedef enum _FLASH_PHASE
+{
+ INSTRUCTION_PHASE = 0,
+ INSTRUCTION_ADDRESS_PHASE = 1,
+ INSTRUCTION_DATA_PHASE = 2,
+ INSTRUCTION_ADDRESS_DATA_PHASE = 3
+}FLASH_PHASE;
+
+class flash_gateway
+{
+protected:
+
+public:
+ flash_gateway(const char *device_name);
+ flash_gateway(void* flashHandle);
+ flash_gateway(){}
+ virtual ~flash_gateway(){};
+ virtual int runCommand(UCHAR flash_cmd, FLASH_PHASE phase, bool bWrite, DWORD addr, DWORD ulSize) = 0;
+ virtual int setData(const BYTE *buffer, DWORD size) = 0;
+ virtual int getData(BYTE *buffer, DWORD size) = 0;
+ virtual int wait_done (void) const = 0;
+ virtual int boot_done(void) const = 0;
+ virtual bool get_lock () = 0;
+ virtual int force_lock () = 0;
+ virtual int release_lock() = 0;
+
+protected:
+ void *m_handler;
+};
diff --git a/debug-tools/lib/FlashAcss/flashacss.h b/debug-tools/lib/FlashAcss/flashacss.h
new file mode 100644
index 0000000..f56f290
--- /dev/null
+++ b/debug-tools/lib/FlashAcss/flashacss.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "flash_gateway.h"
+
+#define ERR printf
+#define DBG printf
+#define INFO printf
+//#define _EXIT_(val) {exit (val);}
+
+extern bool g_debug;
+
+
+typedef struct _FLSH_ACCSS_DLL_VERSION
+{
+ int major;
+ int minor;
+ int maintenance;
+ int build;
+ char fullFilePath[256];
+
+}FLSH_ACCSS_DLL_VERSION;
+
+
+// The following ifdef block is the standard way of creating macros which make exporting
+// from a DLL simpler. All files within this DLL are compiled with the WLCTPCIACSS_EXPORTS
+// symbol defined on the command line. this symbol should not be defined on any project
+// that uses this DLL. This way any other project whose source files include this file see
+// WLCTPCIACSS_API functions as being imported from a DLL, whereas this DLL sees symbols
+// defined with this macro as being exported.
+
+#ifdef _WINDOWS
+#ifdef FLSHACSS_EXPORTS
+#define FLSHACSS_API __declspec(dllexport)
+#else
+#define FLSHACSS_API __declspec(dllimport)
+#endif
+#endif // _WINDOWS
+
+#if defined(__GNUC__)
+#if defined(__i386)
+#define FLSHACSS_API extern "C" __attribute__((cdecl))
+#else
+#define FLSHACSS_API extern "C"
+#endif
+#endif // __GNUC__
+
+
+FLSHACSS_API int wfa_create_flash_access_handler(DType devType, void* pDeviceAccess, void** pFlashAccess);
+FLSHACSS_API int wfa_close_flash_access_handler(void* pFlashAccess);
+FLSHACSS_API int wfa_read(void* pFlashAccess, BYTE *buffer, unsigned long offset, unsigned long size);
+FLSHACSS_API int wfa_write(void* pFlashAccess, const BYTE *buffer, unsigned long offset, unsigned long size);
+FLSHACSS_API int wfa_program(void* pFlashAccess);
+FLSHACSS_API int wfa_erase(void* pFlashAccess);
+
+FLSHACSS_API int wfa_run_command(void* pFlashAccss, UCHAR flash_cmd, FLASH_PHASE phase, bool bWrite, unsigned long addr, unsigned long ulSize);
+FLSHACSS_API int wfa_set_data(void* pFlashAccss, const BYTE *buffer, unsigned long size);
+FLSHACSS_API int wfa_get_data(void* pFlashAccss, BYTE *buffer, unsigned long size);
+FLSHACSS_API int wfa_wait_done(void* pFlashAccss);
+FLSHACSS_API int wfa_boot_done(void* pFlashAccss);
+FLSHACSS_API bool wfa_get_lock(void* pFlashAccss);
+FLSHACSS_API int wfa_force_lock(void* pFlashAccss);
+FLSHACSS_API int wfa_release_lock(void* pFlashAccss);
+
diff --git a/debug-tools/lib/WlctPciAcss/Android.mk b/debug-tools/lib/WlctPciAcss/Android.mk
new file mode 100644
index 0000000..65b6c68
--- /dev/null
+++ b/debug-tools/lib/WlctPciAcss/Android.mk
@@ -0,0 +1,24 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libwigig_pciaccess
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_CPPFLAGS := -Wall -lpthread
+
+LOCAL_C_INCLUDES += \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/../inc \
+ $(LOCAL_PATH)/../inc/linux \
+ $(LOCAL_PATH)/../utils \
+ $(LOCAL_PATH)/../utils/linux \
+ $(LOCAL_PATH)/linux
+
+LOCAL_SRC_FILES := $(shell find $(LOCAL_PATH) -name '*.cpp' | sed s:^$(LOCAL_PATH)::g )
+
+LOCAL_SHARED_LIBRARIES := \
+ libwigig_utils \
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/debug-tools/lib/WlctPciAcss/DeviceAccess.h b/debug-tools/lib/WlctPciAcss/DeviceAccess.h
new file mode 100644
index 0000000..34b7640
--- /dev/null
+++ b/debug-tools/lib/WlctPciAcss/DeviceAccess.h
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "wlct_os.h"
+#include "WlctPciAcss.h"
+#include "LoggerSupport.h"
+
+#define _DeviceTypeCOM 1
+#define _DeviceTypePCI 2
+#define _DeviceTypeJTAG 3
+#define _DeviceTypeMEMORY 4
+
+#define MAX_DEVICE_NAME_LEN 256
+
+class IDeviceAccess
+{
+public:
+ typedef enum
+ {
+ ETypeUnknown = -1, // Unknown
+ ETypeCOM = _DeviceTypeCOM,
+ ETypePCI = _DeviceTypePCI,
+ ETypeJTAG = _DeviceTypeJTAG,
+ ETypeMEMORY = _DeviceTypeMEMORY,
+ }
+ EType;
+
+ IDeviceAccess(const TCHAR* tchDeviceName, DType devType);
+ IDeviceAccess(){deviceType = MST_NONE;}
+ virtual ~IDeviceAccess(void){}
+ virtual int CloseDevice() = 0;
+ virtual int GetType() = 0;
+
+ virtual int r32(DWORD addr, DWORD & val) = 0;
+ virtual int w32(DWORD addr, DWORD val) = 0;
+
+ // read block
+ virtual int rb(DWORD addr, DWORD blockSize, char *arrBlock) = 0;
+ // write block
+ virtual int wb(DWORD addr, DWORD blockSize, const char *arrBlock) = 0;
+ // read repeat
+ virtual int rr(DWORD addr, DWORD num_repeat, DWORD *arrBlock) = 0;
+
+ virtual int getFwDbgMsg(FW_DBG_MSG** pMsg) = 0;
+ virtual int clearAllFwDbgMsg() = 0;
+ virtual int do_reset(BOOL bFirstTime = TRUE) = 0;
+ virtual int do_sw_reset() = 0;
+ virtual int do_interface_reset() = 0;
+
+ virtual int startSampling(
+ DWORD* pRegsArr,
+ DWORD regArrSize,
+ DWORD interval,
+ DWORD maxSampling,
+ DWORD transferMethod)
+ {
+ //do something with params
+ (void)pRegsArr;
+ (void)regArrSize;
+ (void)interval;
+ (void)maxSampling;
+ (void)transferMethod;
+
+ LOG_MESSAGE_ERROR(_T("NOT IMPLEMENTED"));
+ return WLCT_OS_ERROR_CALL_NOT_IMPLEMENTED;
+ }
+ virtual int stopSampling()
+ {
+ LOG_MESSAGE_ERROR(_T("NOT IMPLEMENTED"));
+ return WLCT_OS_ERROR_CALL_NOT_IMPLEMENTED;
+ }
+ virtual int getSamplingData(DWORD** pDataSamples)
+ {
+ //do something with params
+ (void)pDataSamples;
+ LOG_MESSAGE_ERROR(_T("NOT IMPLEMENTED"));
+ return WLCT_OS_ERROR_CALL_NOT_IMPLEMENTED;
+ }
+ virtual int alloc_pmc(int num_of_descriptors, int size_of_descriptor)
+ {
+ //do something with params
+ (void)num_of_descriptors;
+ (void)size_of_descriptor;
+ LOG_MESSAGE_ERROR(_T("NOT IMPLEMENTED"));
+ return WLCT_OS_ERROR_CALL_NOT_IMPLEMENTED;
+ }
+
+ bool isInitialized()
+ {
+ return bInitialized;
+ }
+ wlct_os_err_t GetLastError()
+ {
+ return lastError;
+ }
+ void SetLastError(wlct_os_err_t err)
+ {
+ lastError = err;
+ }
+ TCHAR* GetInterfaceName()
+ {
+ return szInterfaceName;
+ }
+ DType GetDeviceType()
+ {
+ return deviceType;
+ }
+ DEVICE_STEP GetDeviceStep()
+ {
+ return deviceStep;
+ }
+ void SetDeviceStep(DEVICE_STEP devStep)
+ {
+ deviceStep = devStep;
+ }
+
+ //virtual int alloc_pmc(){
+ // return WLCT_OS_ERROR_CALL_NOT_IMPLEMENTED;
+ //}
+protected:
+ bool bInitialized;
+ DType deviceType;
+ DEVICE_STEP deviceStep;
+ TCHAR szInterfaceName[MAX_DEVICE_NAME_LEN];
+ std::deque<FW_DBG_MSG*> m_dbgMsgsList;
+
+public:
+ // Sampling
+ DWORD m_no_sampling_regs;
+ DWORD m_interval;
+ DWORD m_maxSampling;
+ DWORD* m_pRegsArr;
+ DWORD m_sampling_head;
+ DWORD m_sampling_tail;
+ DWORD m_loops;
+ DWORD oneSamplingSize;
+ // cyclic buffer that hold the sampling
+ DWORD* m_sampling_arr;
+ // I'm using this buffer for optimizations
+ // when getSamplingData will called, we will copy the data that was capture
+ // till now to this buffer.
+ // We do not need to allocate it each time and not release it.
+ DWORD* m_get_sampling_arr;
+ DWORD m_transferMethod; // 1-save to file 2-save to buffer
+
+ LONG m_flag_busy;
+ wlct_os_err_t lastError;
+};
+
+
diff --git a/debug-tools/lib/WlctPciAcss/IoctlDevXFace.h b/debug-tools/lib/WlctPciAcss/IoctlDevXFace.h
new file mode 100644
index 0000000..ae37ca4
--- /dev/null
+++ b/debug-tools/lib/WlctPciAcss/IoctlDevXFace.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "wlct_os.h"
+
+class IIoctlDev
+{
+public:
+ IIoctlDev(const TCHAR* tchDeviceName)
+ {
+ WLCT_ASSERT(tchDeviceName != NULL);
+ WLCT_ASSERT(sizeof(szInterfaceName) > _tcslen(tchDeviceName));
+ _tcscpy_s(szInterfaceName, INTERFACE_NAME_LENGTH, tchDeviceName);
+ }
+
+ virtual ~IIoctlDev()
+ {
+
+ }
+
+ virtual bool IsOpened(void) = 0;
+
+ virtual wlct_os_err_t Open() = 0;
+ virtual wlct_os_err_t Ioctl(uint32_t Id,
+ const void *inBuf, uint32_t inBufSize,
+ void *outBuf, uint32_t outBufSize) = 0;
+ virtual wlct_os_err_t DebugFS(char *FileName, void *dataBuf, DWORD dataBufLen, DWORD DebugFSFlags){
+ //do something with params
+ (void)FileName;
+ (void)dataBuf;
+ (void)dataBufLen;
+ (void)DebugFSFlags;
+ return -1;
+ }
+ virtual void Close() = 0;
+
+protected:
+ static const size_t INTERFACE_NAME_LENGTH = 256;
+ TCHAR szInterfaceName[INTERFACE_NAME_LENGTH];
+};
diff --git a/debug-tools/lib/WlctPciAcss/Makefile b/debug-tools/lib/WlctPciAcss/Makefile
new file mode 100644
index 0000000..2e5ef56
--- /dev/null
+++ b/debug-tools/lib/WlctPciAcss/Makefile
@@ -0,0 +1,52 @@
+-include $(TOPDIR)/rules.mk
+
+CFLAGS := -fPIC -Wall -g -MMD
+LDFLAGS := -shared -fPIC
+
+LIB := libwigig_pciaccess.so
+
+.DEFAULT_GOAL = all
+
+ifneq ($(CONFIG_TARGET_ipq)$(CONFIG_TARGET_ipq806x),)
+is_ipq806x = 1
+endif
+
+ifeq ($(is_ipq806x), 1)
+ifneq ($(strip $(TOOLPREFIX)),)
+CROSS:=$(TOOLPREFIX)
+endif
+endif
+
+CC = $(CROSS)gcc
+CXX = $(CROSS)g++
+
+INCLUDES = -I . \
+ -I ../inc/linux \
+ -I ../inc \
+ -I ../utils/linux \
+ -I ../utils \
+ -I ./linux \
+
+all: $(LIB)
+
+CPP_FILES := $(shell find . -type f -name '*.cpp')
+C_FILES := $(shell find . -type f -name '*.c')
+
+OBJ_FILES := $(CPP_FILES:.cpp=.o)
+OBJ_FILES += $(C_FILES:.c=.o)
+
+$(LIB): $(OBJ_FILES)
+ $(CXX) $(LDFLAGS) -o $(LIB) $(OBJ_FILES)
+
+%.o : %.cpp
+ $(CXX) $(CFLAGS) $(INCLUDES) -o $@ -c $<
+
+%.o : %.c
+ $(CC) $(CFLAGS) $(INCLUDES) -o $@ -c $<
+
+clean:
+ rm -rf $(LIB)
+ find . -type f \( -name "*.d" -o -name "*.o" \) -delete
+
+
+-include $(OBJ_FILES:%.o=%.d)
diff --git a/debug-tools/lib/WlctPciAcss/MemoryAccess.cpp b/debug-tools/lib/WlctPciAcss/MemoryAccess.cpp
new file mode 100644
index 0000000..758c4cb
--- /dev/null
+++ b/debug-tools/lib/WlctPciAcss/MemoryAccess.cpp
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "MemoryAccess.h"
+
+CMemoryAccess::CMemoryAccess(const TCHAR* tchDeviceName, DType devType)
+{
+ //do something with params
+ (void)tchDeviceName;
+ //if (devType == MST_MARLON)
+ //{
+ m_size = WLCT_DEV_MEMORY_SIZE;
+ m_baseAddress = 0x800000;
+ //}
+
+ deviceType = devType;
+ m_pMem = new char[m_size];
+ memset(m_pMem, 0, m_size);
+}
+
+CMemoryAccess::~CMemoryAccess(void)
+{
+ CloseDevice();
+}
+
+int CMemoryAccess::GetType()
+{
+ return IDeviceAccess::ETypeMEMORY;
+}
+
+int CMemoryAccess::CloseDevice()
+{
+ if (m_pMem != NULL)
+ {
+ delete []m_pMem;
+ m_pMem = NULL;
+ }
+ return 0;
+}
+
+int CMemoryAccess::r32(DWORD addr, DWORD & val)
+{
+ DWORD actualAddr = addr - m_baseAddress;
+
+ if (actualAddr >= m_size)
+ return -1;
+
+ actualAddr = actualAddr >> 2;
+ val = ((DWORD*)m_pMem)[actualAddr];
+ LOG_MESSAGE_DEBUG(_T("ADDR(in bytes): %04X Value: 0x%08X"), addr, val);
+ return 0;
+}
+
+int CMemoryAccess::w32(DWORD addr, DWORD val)
+{
+ DWORD actualAddr = addr - m_baseAddress;
+ if (actualAddr >= m_size)
+ return -1;
+
+ actualAddr = actualAddr >> 2;
+ ((DWORD*)m_pMem)[actualAddr] = val;
+ LOG_MESSAGE_DEBUG(_T("ADDR: %04X Value: 0x%04X"),addr, val);
+ return 0;
+}
+
+int CMemoryAccess::rb(DWORD addr, DWORD blockSize, char *arrBlock)
+{
+ DWORD actualAddr = addr;
+// DWORD val;
+
+ //if (GetDeviceType() == MST_MARLON)
+ //{
+ actualAddr = addr - m_baseAddress;
+ //}
+
+ if ((actualAddr+blockSize) >= m_size)
+ return -1;
+
+ memcpy(arrBlock, &(m_pMem[actualAddr]), blockSize);
+
+// for (int inx = 0; inx < blockSize; inx++)
+// {
+// // wait between each loop
+// DWORD readFromIndex = actualAddr+inx;
+//
+// if (GetDeviceType() == MST_SWIFT)
+// {
+// val = ((USHORT*)m_pMem)[readFromIndex];
+// }
+//
+// if (GetDeviceType() == MST_MARLON)
+// {
+// val = ((DWORD*)m_pMem)[actualAddr];
+// }
+//
+// arrBlock[inx] = val;
+// }
+
+ return 0;
+}
+
+int CMemoryAccess::wb(DWORD addr, DWORD blockSize, const char *arrBlock)
+{
+ //do something with params
+ (void)addr;
+ (void)blockSize;
+ (void)arrBlock;
+
+ return 0;
+}
+
+void CMemoryAccess::rr32(DWORD addr, DWORD num_repeat, DWORD *arrBlock)
+{
+ DWORD* pFrom = &((DWORD*)m_pMem)[addr>>2];
+ for (DWORD loop = 0; loop < num_repeat; loop++)
+ {
+ // wait between each loop
+
+ arrBlock[loop] = *pFrom;
+ }
+}
+
+int CMemoryAccess::rr(DWORD addr, DWORD num_repeat, DWORD *arrBlock)
+{
+ if (!isInitialized())
+ return -1;
+
+ DWORD actualAddr = addr;
+
+ //if (GetDeviceType() == MST_MARLON)
+ //{
+ actualAddr = addr - m_baseAddress;
+ //}
+
+ if (actualAddr >= m_size)
+ return -1;
+
+ //if (GetDeviceType() == MST_MARLON)
+ //{
+ rr32(actualAddr, num_repeat, arrBlock);
+ //}
+ return 0;
+}
+
+int CMemoryAccess::getFwDbgMsg(FW_DBG_MSG** pMsg)
+{
+ //do something with params
+ (void)pMsg;
+
+// LOG_MESSAGE_ERROR(_T("NOT IMPLEMENTED"));
+ return WLCT_OS_ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+int CMemoryAccess::clearAllFwDbgMsg()
+{
+ LOG_MESSAGE_ERROR(_T("NOT IMPLEMENTED"));
+ return WLCT_OS_ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+int CMemoryAccess::do_reset(BOOL bFirstTime)
+{
+ //do something with params
+ (void)bFirstTime;
+ LOG_MESSAGE_ERROR(_T("NOT IMPLEMENTED"));
+ return WLCT_OS_ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+
+int CMemoryAccess::do_sw_reset()
+{
+ LOG_MESSAGE_ERROR(_T("NOT IMPLEMENTED"));
+ return WLCT_OS_ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+
+int CMemoryAccess::do_interface_reset()
+{
+ LOG_MESSAGE_ERROR(_T("NOT IMPLEMENTED"));
+ return WLCT_OS_ERROR_CALL_NOT_IMPLEMENTED;
+}
diff --git a/debug-tools/lib/WlctPciAcss/MemoryAccess.h b/debug-tools/lib/WlctPciAcss/MemoryAccess.h
new file mode 100644
index 0000000..3240327
--- /dev/null
+++ b/debug-tools/lib/WlctPciAcss/MemoryAccess.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+#include "DeviceAccess.h"
+
+#define WLCT_DEV_MEMORY_SIZE (0x129000)
+
+
+extern "C" class CMemoryAccess : public IDeviceAccess
+{
+public:
+ CMemoryAccess(const TCHAR* tchDeviceName, DType devType);
+ virtual ~CMemoryAccess(void);
+ virtual int CloseDevice();
+ virtual int GetType();
+ virtual int r32(DWORD addr, DWORD & val);
+ virtual int w32(DWORD addr, DWORD val);
+ virtual int rb(DWORD addr, DWORD blockSize, char *arrBlock);
+ virtual int wb(DWORD addr, DWORD blockSize, const char *arrBlock);
+ virtual int rr(DWORD addr, DWORD num_repeat, DWORD *arrBlock);
+ virtual int getFwDbgMsg(FW_DBG_MSG** pMsg);
+ virtual int clearAllFwDbgMsg();
+ virtual int do_reset(BOOL bFirstTime = TRUE);
+ virtual int do_sw_reset();
+ virtual int do_interface_reset();
+
+private:
+ void rr32(DWORD addr, DWORD num_repeat, DWORD *arrBlock);
+
+private:
+ char* m_pMem;
+ DWORD m_size;
+ DWORD m_baseAddress;
+};
diff --git a/debug-tools/lib/WlctPciAcss/PciDeviceAccess.cpp b/debug-tools/lib/WlctPciAcss/PciDeviceAccess.cpp
new file mode 100644
index 0000000..343a650
--- /dev/null
+++ b/debug-tools/lib/WlctPciAcss/PciDeviceAccess.cpp
@@ -0,0 +1,1265 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "wlct_os.h"
+
+#include "PciDeviceAccess.h"
+#include "WlctPciAcssHelper.h"
+#include "DeviceAccess.h"
+#include <ctime>
+#include "Util.h"
+
+
+//////////////////////////////////////////////////////////////////////////
+// PCI interface
+
+CPciDeviceAccess::CPciDeviceAccess(const TCHAR* tchDeviceName, DType devType)
+ : IoctlDev(tchDeviceName)/*, SamplingThread(SamplingThreadProc, this),
+ PciPluginThread(this)*/
+{
+ LOG_MESSAGE_INFO(_T("Create PCI device access for: %s"), tchDeviceName);
+ _tcscpy_s(szInterfaceName, MAX_DEVICE_NAME_LEN, tchDeviceName);
+ deviceType = devType;
+ m_close_state = 2;
+ m_open_state = 0;
+ //LOG_MESSAGE_INFO(_T("[close %d] [open %d]"), m_close_state, m_open_state);
+ bInitialized = false;
+ Open();
+ if (bInitialized)
+ {
+// PciPluginThread.Start();
+ }
+ return;
+}
+
+void CPciDeviceAccess::Open()
+{
+ if (IoctlDev.IsOpened())
+ {
+ LOG_MESSAGE_INFO(_T("Already open. changing m_close_state = 0 and m_open_state = 2 [close %d] [open %d]"), m_close_state, m_open_state);
+ bInitialized = true;
+ m_close_state = 0;
+ m_open_state = 2;
+ return;
+ }
+
+ m_sampling_arr = NULL;
+ m_get_sampling_arr = NULL;
+// m_hMonitorwPciPluginThread = NULL;
+ lastError = WLCT_OS_ERROR_SUCCESS;
+ dwBaseAddress = 0x880000;
+
+ bIsLocal = true;
+ TCHAR LorR = szInterfaceName[_tcslen(szInterfaceName) - 1];
+ if (LorR == _T('R') || LorR == _T('r'))
+ {
+ bIsLocal = false;
+ dwBaseAddress += 0x100000;
+ }
+
+ lastError = IoctlDev.Open();
+ if (lastError != WLCT_OS_ERROR_SUCCESS)
+ {
+ //LOG_MESSAGE_ERROR(_T("PCIdeviceAccess: failed to open driver wPci. ERROR_FILE_NOT_FOUND = %d"), lastError);
+ return;
+ }
+
+// ReOpen();
+
+ bInitialized = true;
+// LOG_MESSAGE_INFO(_T("changing m_close_state to 0 and m_open_state to 2 [close %d] [open %d]"), m_close_state, m_open_state);
+ m_close_state = 0;
+ m_open_state = 2;
+
+ m_flag_busy = false;
+}
+
+CPciDeviceAccess::~CPciDeviceAccess()
+{
+ CloseDevice();
+}
+
+int CPciDeviceAccess::ReOpen()
+{
+ LOG_MESSAGE_INFO(_T("Sending ioctl IOCTL_FILTER_OPEN_DEVICE"));
+
+ FILTER_OPEN_DEVICE openDevice;
+
+ lastError = IoctlDev.Ioctl(bIsLocal?IOCTL_FILTER_OPEN_LOCAL_DEVICE:IOCTL_FILTER_OPEN_REMOTE_DEVICE,
+ NULL, 0, &openDevice, sizeof(openDevice));
+ if ( lastError != WLCT_OS_ERROR_SUCCESS )
+ {
+ LOG_MESSAGE_ERROR(_T("Error in DeviceIoControl: IOCTL_FILTER_OPEN_DEVICE [err %d]"), lastError);
+ return -1;
+ }
+
+ LOG_MESSAGE_INFO(_T("Successfully sent ioctl IOCTL_FILTER_OPEN_DEVICE"));
+
+ return 0;
+}
+
+int CPciDeviceAccess::GetType()
+{
+ return IDeviceAccess::ETypePCI;
+}
+
+int CPciDeviceAccess::InternalCloseDevice()
+{
+// DWORD bytesReturned = 0;
+
+// sleep_ms(100);
+
+// if (bIsLocal)
+// {
+// bRc = DeviceIoControl (hPciCtrlDevice, IOCTL_FILTER_CLOSE_LOCAL_DEVICE, NULL, 0, NULL, 0, &bytesReturned, NULL);
+// }
+// else
+// {
+// bRc = DeviceIoControl (hPciCtrlDevice, IOCTL_FILTER_CLOSE_REMOTE_DEVICE, NULL, 0, NULL, 0, &bytesReturned, NULL);
+// }
+// lastError = ::GetLastError();
+// if ( !bRc || bytesReturned != 0)
+// {
+// LOG_MESSAGE_WARN(_T("Error in DeviceIoControl : %d"), lastError);
+// }
+// else
+// {
+// LOG_MESSAGE_INFO(_T("Successfully sent ioctl IOCTL_FILTER_CLOSE_DEVICE"))
+// }
+
+ IoctlDev.Close();
+// LOG_MESSAGE_INFO(_T("changing m_close_state to 2 [close %d] [open %d]"), m_close_state, m_open_state);
+ m_close_state = 2;
+
+ return 0;
+}
+
+int CPciDeviceAccess::CloseDevice()
+{
+ //PciPluginThread.Stop();
+ if (InternalCloseDevice() == 0)
+ {
+ bInitialized = false;
+ //LOG_MESSAGE_INFO(_T("changing m_open_state to 0 and bInitialized to false [close %d] [open %d]"), m_close_state, m_open_state);
+ m_open_state = 0;
+ }
+ return 0;
+}
+
+#ifdef _WINDOWS
+int CPciDeviceAccess::SetDriverMode(int newState, int &oldState, int &payloadResult)
+{
+ if(!isInitialized()){
+ return -1;
+ }
+ if (m_close_state == 2)
+ Open();
+ if (!IoctlDev.IsOpened())
+ return -1;
+
+ SET_MODE_CMD_INPUT inBuffer;
+ SET_MODE_CMD_OUTPUT outBuffer;
+
+ memset(&inBuffer, 0, sizeof(SET_MODE_CMD_INPUT));
+ memset(&outBuffer, 0, sizeof(SET_MODE_CMD_OUTPUT));
+
+ inBuffer.mode = (DRIVER_MODE)newState;
+
+ lastError = IoctlDev.Ioctl(WILOCITY_IOCTL_SET_MODE_NEW, &inBuffer, sizeof(inBuffer), &outBuffer, sizeof(outBuffer));
+
+ if (lastError != WLCT_OS_ERROR_SUCCESS)
+ {
+ LOG_MESSAGE_WARN(_T("WILOCITY_IOCTL_SET_MODE_NEW failed. %X"), lastError);
+ oldState = -1;
+ return -1;
+ payloadResult = -1;
+ }
+ if(!outBuffer.result){
+ LOG_MESSAGE_WARN(_T("WILOCITY_IOCTL_SET_MODE_NEW did not change the mode"));
+ }
+ payloadResult = outBuffer.result;
+ oldState = outBuffer.previousMode;
+ return 0;
+}
+
+
+int CPciDeviceAccess::GetDriverMode(int ¤tState){
+ if(!isInitialized()){
+ return false;
+ }
+ if (m_close_state == 2)
+ Open();
+ if (!IoctlDev.IsOpened())
+ return -1;
+
+ GET_MODE_CMD_OUTPUT currentModeBuffer;
+ memset(¤tModeBuffer, 0, sizeof(GET_MODE_CMD_OUTPUT));
+
+
+ lastError = IoctlDev.Ioctl(WILOCITY_IOCTL_GET_MODE_NEW, NULL, 0, ¤tModeBuffer, sizeof(currentModeBuffer));
+
+ if (lastError != WLCT_OS_ERROR_SUCCESS)
+ {
+ LOG_MESSAGE_WARN(_T("WILOCITY_IOCTL_GET_MODE_NEW failed. %X"), lastError);
+ return -1;
+ }
+
+ currentState = currentModeBuffer.currentMode;
+ return 0;
+}
+#endif //_WINDOWS
+
+// MARLON
+int CPciDeviceAccess::r32(DWORD addr, DWORD & val)
+{
+ if (!isInitialized())
+ return -1;
+ if (m_close_state == 2)
+ Open();
+ if (!IoctlDev.IsOpened())
+ return -1;
+
+ FILTER_1_ULONG_PARAM inParams;
+ FILTER_1_ULONG_PARAM outParams;
+
+ inParams.param = addr;
+
+ if (!bIsLocal)
+ {
+ inParams.param += 0x100000;
+ }
+
+ if (IoctlDev.bOldIoctls)
+ lastError = IoctlDev.Ioctl(IOCTL_INDIRECT_READ_OLD, &inParams, sizeof(inParams), &outParams, sizeof(outParams));
+ else
+ lastError = IoctlDev.Ioctl(WILOCITY_IOCTL_INDIRECT_READ, &inParams, sizeof(inParams), &outParams, sizeof(outParams));
+
+ if (lastError != WLCT_OS_ERROR_SUCCESS)
+ {
+ LOG_MESSAGE_WARN(_T("WILOCITY_IOCTL_INDIRECT_READ failed. %X"), lastError);
+ return -1;
+ }
+
+ val = outParams.param;
+ LOG_MESSAGE_DEBUG(_T("ADDR(in bytes): 0x%X Value: 0x%X"), addr, val);
+ return 0;
+}
+
+bool CPciDeviceAccess::try2open(int timeout)
+{
+ do
+ {
+ Open();
+ if (IoctlDev.IsOpened())
+ break;
+ sleep_ms(100);
+ timeout -= 100;
+ } while (timeout > 0);
+
+ if (!IoctlDev.IsOpened())
+ return false;
+ return true;
+}
+
+
+int CPciDeviceAccess::do_interface_reset()
+{
+ if (!isInitialized())
+ return -1;
+ if (m_close_state == 2)
+ Open();
+ if (!IoctlDev.IsOpened())
+ return -1;
+
+ FILTER_1_ULONG_PARAM inParams;
+ FILTER_1_ULONG_PARAM outParams;
+
+ /*inParams.param = addr;
+
+ if (!bIsLocal)
+ {
+ inParams.param += 0x100000;
+ }*/
+
+ lastError = IoctlDev.Ioctl(WILOCITY_IOCTL_DEVICE_SW_RESET, &inParams, sizeof(inParams), &outParams, sizeof(outParams));
+
+
+ if (lastError != WLCT_OS_ERROR_SUCCESS)
+ {
+ LOG_MESSAGE_WARN(_T("WILOCITY_IOCTL_DEVICE_SW_RESET failed. %X"), lastError);
+ InternalCloseDevice();
+ return -1;
+ }
+
+ //val = outParams.param;
+ LOG_MESSAGE_INFO(_T("Pci Interface Reset using IOCTL"));
+ return 0;
+}
+
+int CPciDeviceAccess::do_sw_reset()
+{
+ LOG_MESSAGE_ERROR(_T("NOT IMPLEMENTED"));
+ return WLCT_OS_ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+
+#define USING_RESET_FUNCTION 0
+int CPciDeviceAccess::do_reset(BOOL bFirstTime)
+{
+ if (USING_RESET_FUNCTION == 0)
+ {
+ LOG_MESSAGE_WARN(_T("reset was not done because USING_RESET_FUNCTION == 0"));
+ return -1;
+ }
+
+ if (!isInitialized())
+ return -1;
+ if (m_close_state == 2)
+ Open();
+ if (!IoctlDev.IsOpened())
+ return -1;
+
+ DWORD addr;
+ if (deviceStep == STEP_NONE)
+ addr = 0x880AE0;
+ else if (deviceStep == MARLON_STEP_B0 || deviceStep == SPARROW_STEP_A0 || deviceStep == SPARROW_STEP_B0)
+ addr = 0x880B04;
+ else // default
+ {
+ addr = 0x880B04;
+ }
+
+ DWORD val;
+ bool bres;
+
+ // check if there is an access to the board
+ int ret = r32(BAUD_RATE_REGISTER, val);
+ if (ret != 0 || val == 0 || val == 0xFFFFFFFF)
+ {
+ // access failed.
+ if (bFirstTime == FALSE)
+ return -1;
+
+ // do disable enable
+ InternalCloseDevice();
+ sleep_ms(500);
+ bres = Util::ICHDisableEnable();
+ if (!bres)
+ sleep_ms(1000);
+ Open();
+ do_reset(FALSE);
+ }
+
+ w32(addr, 1);
+ InternalCloseDevice();
+ sleep_ms(500);
+ bres = Util::ICHDisableEnable();
+
+ bres = try2open(2000);
+ if (!bres)
+ {
+ LOG_MESSAGE_INFO(_T("do_reset: failed to open the device after reset"));
+ return -1;
+ }
+
+
+ int timeout = 2000;
+ bres = false;
+ do
+ {
+ ret = r32(BAUD_RATE_REGISTER, val);
+ if (ret == 0 && val > 0 && val < 0xFFFFFFFF)
+ {
+ bres = true;
+ break;
+ }
+ sleep_ms(100);
+ timeout -= 100;
+ } while (timeout > 0);
+ if (!bres)
+ {
+ LOG_MESSAGE_ERROR(_T("ERROR: failed to read the baudrate after reset."));
+ return -1;
+ }
+ return 0;
+}
+
+int CPciDeviceAccess::reset_complete()
+{
+ DWORD val;
+ bool bres;
+ int ret;
+
+ InternalCloseDevice();
+ sleep_ms(500);
+ Util::ICHDisableEnable();
+
+ bres = try2open(2000);
+ if (!bres)
+ {
+ LOG_MESSAGE_INFO(_T("failed to open the device after reset"));
+ return -1;
+ }
+
+ int timeout = 2000;
+ bres = false;
+ do
+ {
+ ret = r32(BAUD_RATE_REGISTER, val);
+ if (ret == 0 && val > 0 && val < 0xFFFFFFFF)
+ {
+ bres = true;
+ break;
+ }
+ sleep_ms(100);
+ timeout -= 100;
+ } while (timeout > 0);
+ if (!bres)
+ {
+ LOG_MESSAGE_ERROR(_T("ERROR: failed to read the baudrate after reset."));
+ return -1;
+ }
+ return 0;
+}
+
+// marlon
+int CPciDeviceAccess::w32(DWORD addr, DWORD val)
+{
+ if (!isInitialized())
+ return -1;
+ if (m_close_state == 2)
+ Open();
+ if (!IoctlDev.IsOpened())
+ return -1;
+
+
+ FILTER_2_ULONG_PARAM inParams;
+
+ inParams.param1 = addr;
+
+ if (!bIsLocal)
+ {
+ inParams.param1 += 0x100000;
+ }
+
+ inParams.param2 = val;
+
+
+ if (IoctlDev.bOldIoctls)
+ lastError = IoctlDev.Ioctl(IOCTL_INDIRECT_WRITE_OLD, &inParams, sizeof(inParams), NULL, 0);
+ else
+ lastError = IoctlDev.Ioctl(WILOCITY_IOCTL_INDIRECT_WRITE, &inParams, sizeof(inParams), NULL, 0);
+
+
+ if (lastError != WLCT_OS_ERROR_SUCCESS)
+ {
+ LOG_MESSAGE_WARN(_T("IOCTL_INDIRECT_WRITE failed. %X"), lastError);
+ InternalCloseDevice();
+ return -1;
+ }
+
+ if (USING_RESET_FUNCTION == 0)
+ {
+ if (((deviceStep == STEP_NONE) && (addr == 0x880AE0)) || ((deviceStep == MARLON_STEP_B0 || deviceStep == SPARROW_STEP_A0 || deviceStep == SPARROW_STEP_B0) && (addr == 0x880B04)))
+ {
+ if (val & 0x1)
+ {
+ LOG_MESSAGE_WARN(_T("Calling reset from write command instead of calling reset directly!!!!!!!!!!!!!!!!!!!!!!!!!!"));
+ reset_complete();
+ }
+ }
+ }
+
+ LOG_MESSAGE_DEBUG(_T("ADDR: 0x%X Value: 0x%X"),addr, val);
+ return 0;
+}
+
+// addr is in bytes.
+// block size for SWITH is number of 16 bits and MARLON is number of bytes
+// In MARLON the block size should be align to 32 bits (otherwise it will be
+// truncated by the hardware)
+//
+int CPciDeviceAccess::rb(DWORD addr, DWORD blockSize, char *arrBlock)
+{
+ if (!isInitialized())
+ return -1;
+// if (m_close_state == 1)
+// InternalCloseDevice();
+// if (m_open_state == 1)
+// Open();
+// if (m_close_state == 2)
+// return -1;
+ if (m_close_state == 2)
+ Open();
+ if (!IoctlDev.IsOpened())
+ return -1;
+
+
+ //if (GetDeviceType() == MST_MARLON)
+ //{
+ FILTER_1_ULONG_PARAM inParams;
+
+ inParams.param = addr;
+
+ if (!bIsLocal)
+ {
+ inParams.param += 0x100000;
+ }
+
+
+ if (IoctlDev.bOldIoctls)
+ lastError = IoctlDev.Ioctl(IOCTL_INDIRECT_READ_BLOCK, &inParams, sizeof(inParams), arrBlock, blockSize);
+ else
+ lastError = IoctlDev.Ioctl(WILOCITY_IOCTL_INDIRECT_READ_BLOCK, &inParams, sizeof(inParams), arrBlock, blockSize);
+
+ // DWORD le = GetLastError();
+ // LOG_MESSAGE_WARN(_T("IOCTL_INDIRECT_READ return %d [lastError 0x%X]"), bRc, le);
+ if (lastError != WLCT_OS_ERROR_SUCCESS)
+ {
+ LOG_MESSAGE_WARN(_T("IOCTL_INDIRECT_READ failed. %X"), lastError);
+ InternalCloseDevice();
+ return -1;
+ }
+ //}
+
+ return 0;
+}
+
+int CPciDeviceAccess::wb(DWORD addr, DWORD blockSize, const char *arrBlock)
+{
+ if (!isInitialized())
+ return -1;
+ if (m_close_state == 2)
+ Open();
+ if (!IoctlDev.IsOpened())
+ return -1;
+
+ PFILTER_WRITE_BLOCK pinParams;
+ char* p = new char[2*sizeof(ULONG) + blockSize];
+ pinParams = (PFILTER_WRITE_BLOCK)p;
+ pinParams->address = addr;
+
+ if (!bIsLocal)
+ {
+ pinParams->address += 0x100000;
+ }
+
+ pinParams->size = blockSize;
+ memcpy(pinParams->buffer, arrBlock, blockSize);
+
+
+ if (IoctlDev.bOldIoctls)
+ lastError = IoctlDev.Ioctl(IOCTL_INDIRECT_WRITE_BLOCK, pinParams, 2*sizeof(ULONG) + blockSize, NULL, 0);
+ else
+ lastError = IoctlDev.Ioctl(WILOCITY_IOCTL_INDIRECT_WRITE_BLOCK, pinParams, 2*sizeof(ULONG) + blockSize, NULL, 0);
+
+ if (lastError != WLCT_OS_ERROR_SUCCESS)
+ {
+ LOG_MESSAGE_WARN(_T("WILOCITY_IOCTL_INDIRECT_WRITE_BLOCK failed. %X"), lastError);
+ InternalCloseDevice();
+ delete [] p;
+ return -1;
+ }
+
+ delete [] p;
+ return 0;
+}
+
+void CPciDeviceAccess::rr32(DWORD addr, DWORD num_repeat, DWORD *arrBlock)
+{
+ WLCT_UNREFERENCED_PARAM(addr);
+ WLCT_UNREFERENCED_PARAM(num_repeat);
+ WLCT_UNREFERENCED_PARAM(arrBlock);
+ WLCT_ASSERT(0);
+}
+
+int CPciDeviceAccess::rr(DWORD addr, DWORD num_repeat, DWORD *arrBlock)
+{
+ if (!isInitialized())
+ return -1;
+ if (m_close_state == 2)
+ Open();
+ if (!IoctlDev.IsOpened())
+ return -1;
+
+ //if (GetDeviceType() == MST_MARLON)
+ //{
+ FILTER_1_ULONG_PARAM inParams;
+ inParams.param = addr;
+ if (!bIsLocal)
+ {
+ inParams.param += 0x100000;
+ }
+
+ lastError = IoctlDev.Ioctl(IOCTL_INDIRECT_READ_REPEAT, &inParams, sizeof(inParams), arrBlock, num_repeat*sizeof(DWORD));
+ if (lastError != WLCT_OS_ERROR_SUCCESS)
+ {
+ LOG_MESSAGE_WARN(_T("IOCTL_INDIRECT_READ failed. %X"), lastError);
+ InternalCloseDevice();
+ return -1;
+ }
+
+
+// actualAddr = addr - dwBaseAddress;
+// if (actualAddr >= CRSsize)
+// return -1;
+//
+// rr32(actualAddr>>2, num_repeat, arrBlock);
+ //}
+ return 0;
+}
+
+int CPciDeviceAccess::getFwDbgMsg(FW_DBG_MSG** pMsg)
+{
+ (void)pMsg;
+ // LOG_MESSAGE_DEBUG(_T("NOT IMPLEMENTED"));
+ return WLCT_OS_ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+int CPciDeviceAccess::clearAllFwDbgMsg()
+{
+ LOG_MESSAGE_ERROR(_T("NOT IMPLEMENTED"));
+ return WLCT_OS_ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+/*
+ void CPciDeviceAccess::SamplingThreadProc(void *pDeviceAccss)
+ {
+ LOG_MESSAGE_DEBUG(_T("start running"));
+ CPciDeviceAccess *pDevice = (CPciDeviceAccess*)pDeviceAccss;
+ #ifdef WCLT_SAMPLING_TO_FILE_IS_SUPPORTED
+ HANDLE hSamplingFile = INVALID_HANDLE_VALUE;
+ #endif
+ uint64_t startTS;
+
+ pDevice->m_sampling_head = 0;
+ pDevice->m_sampling_tail = 0;
+ pDevice->m_loops = 0;
+
+ startTS = GetTimeStampMs();
+
+ WLCT_UNREFERENCED_PARAM(startTS);
+
+ SAMPLING_REGS* currEntry;
+
+ #ifdef WCLT_SAMPLING_TO_FILE_IS_SUPPORTED
+ DWORD written = 0;
+ if (pDevice->m_transferMethod == 1)
+ { // saving to file
+ TCHAR file_name[256];
+ _stprintf (file_name, _T("c:\\sampling_%X.bin"), GetTickCount());
+ hSamplingFile = CreateFile(file_name, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (hSamplingFile == INVALID_HANDLE_VALUE)
+ {
+ return;
+ }
+ // first data in the file is the number of registers in each sampling
+ WriteFile(hSamplingFile, &pDevice->m_no_sampling_regs, sizeof(pDevice->m_no_sampling_regs), &written, NULL);
+ // then write the registers address
+ WriteFile(hSamplingFile, pDevice->m_pRegsArr, sizeof(DWORD)* pDevice->m_no_sampling_regs, &written, NULL);
+ }
+ #endif
+
+ uint64_t last_timeStamp = 0;
+ do
+ {
+ //sleep_ms(pDevice->m_interval);
+ do
+ {
+ sleep_ms(0);
+ } while ( (GetTimeStampMs() - last_timeStamp) < pDevice->m_interval);
+ last_timeStamp = GetTimeStampMs();
+
+ currEntry = (SAMPLING_REGS*)(pDevice->m_sampling_arr + pDevice->m_sampling_head * (pDevice->m_no_sampling_regs + 1));
+ currEntry->timeStamp = (DWORD)last_timeStamp;
+ for (DWORD i = 0; i < pDevice->m_no_sampling_regs; i++)
+ {
+ DWORD val;
+ if (pDevice->GetDeviceType() == MST_SWIFT)
+ {
+ pDevice->r2(pDevice->m_pRegsArr[i], val);
+ currEntry->regArr[i] = val;
+ }
+ else if (pDevice->GetDeviceType() == MST_MARLON)
+ {
+ pDevice->r32(pDevice->m_pRegsArr[i], currEntry->regArr[i]);
+ }
+ }
+
+ pDevice->m_sampling_head++;
+ if (pDevice->m_sampling_head >= pDevice->m_maxSampling)
+ {
+ pDevice->m_sampling_head = 0;
+ #ifdef WCLT_SAMPLING_TO_FILE_IS_SUPPORTED
+ if (pDevice->m_transferMethod == 1)
+ {
+ // save the buffer to the disk;
+ WriteFile(hSamplingFile, pDevice->m_sampling_arr, pDevice->oneSamplingSize * pDevice->m_maxSampling, &written, NULL);
+ }
+ #endif
+ if (pDevice->m_transferMethod == 2)
+ {
+ pDevice->m_loops++;
+ }
+
+ }
+
+ } while (!pDevice->SamplingThread.ShouldStop());
+ #ifdef WCLT_SAMPLING_TO_FILE_IS_SUPPORTED
+ if (pDevice->m_transferMethod == 1)
+ {
+ CloseHandle(hSamplingFile);
+ }
+ #endif
+ LOG_MESSAGE_DEBUG(_T("Leaving"));
+ }
+
+ int CPciDeviceAccess::startSampling(
+ DWORD* pRegsArr,
+ DWORD regArrSize,
+ DWORD interval,
+ DWORD maxSampling,
+ DWORD transferMethod)
+ {
+ m_no_sampling_regs = regArrSize;
+ m_pRegsArr = new DWORD[regArrSize];
+ memcpy(m_pRegsArr, pRegsArr, sizeof(DWORD)*regArrSize);
+ m_interval = interval;
+ m_maxSampling = maxSampling;
+ m_transferMethod = transferMethod;
+
+ // allocate the sampling buffer
+ // each sampling required:
+ // m_no_sampling_regs * sizeof(DWORD) + timestamp
+ oneSamplingSize = m_no_sampling_regs * sizeof(DWORD) + sizeof(DWORD);
+ m_sampling_arr = new DWORD[oneSamplingSize * m_maxSampling];
+ m_get_sampling_arr = new DWORD[oneSamplingSize * m_maxSampling];
+
+ // start the read tread
+ SamplingThread.Start();
+ sleep_ms(100);
+
+ return 0;
+ }
+
+ int CPciDeviceAccess::stopSampling()
+ {
+ SamplingThread.Stop();
+
+ // free the sampling buffers
+ delete [] m_pRegsArr;
+ delete [] m_sampling_arr;
+ delete [] m_get_sampling_arr;
+ return 0;
+ }
+
+ int CPciDeviceAccess::getSamplingData(DWORD** pDataSamples)
+ {
+ DWORD total_copy = 0;
+
+ // get the head and tail position
+ DWORD head = m_sampling_head;
+ DWORD tail = m_sampling_tail;
+
+ LOG_MESSAGE_DEBUG(_T("[head %X] [tail %X] [loops %d]"), head, tail, m_loops);
+
+ memset(m_get_sampling_arr, 0, oneSamplingSize * m_maxSampling);
+
+ // 0 - no new data. nothing to copy
+ // -1 - error
+ // 1 - copy from tail to head
+ // 2 - copy from tail to end buffer and then from start buffer to head
+ // 3 - overlapped. copy from head to head.
+ //
+ DWORD copy_type = 0;
+ if (m_loops == 0)
+ {
+ if (head == tail)
+ {
+ // no new data
+ copy_type = 0;
+ }
+ else if (head > tail)
+ {
+ // new data. copy from tail to head
+ copy_type = 1;
+ }
+ else if (head < tail)
+ {
+ // error
+ LOG_MESSAGE_ERROR(_T("ERROR: !!!!!!!! loop is ZERO [head %X] [tail %X]"), head, tail);
+ copy_type = -1;
+ }
+ }
+ else if (m_loops == 1)
+ {
+ if (head == tail)
+ {
+ // overlapped. copy head to head
+ copy_type = 3;
+ }
+ else if (head > tail)
+ {
+ // overlapped. copy head to head
+ copy_type = 3;
+ }
+ else if (head < tail)
+ {
+ // copy from tail to end buffer and then from start buffer to head
+ copy_type = 2;
+ }
+ }
+ else if (m_loops > 1)
+ {
+ // overlapped. copy head to head
+ copy_type = 3;
+ }
+
+ DWORD srcPos;
+ switch (copy_type)
+ {
+ case 1:
+ {
+ srcPos = oneSamplingSize * tail / sizeof(DWORD);
+ memcpy(m_get_sampling_arr, &(m_sampling_arr[srcPos]), oneSamplingSize * (head - tail));
+ total_copy = oneSamplingSize * (head - tail);
+ }
+ break;
+ case 2:
+ {
+ // copy from tail to the end of the buffer
+ srcPos = oneSamplingSize * tail / sizeof(DWORD);
+ memcpy(m_get_sampling_arr, &(m_sampling_arr[srcPos]), oneSamplingSize * (m_maxSampling - tail));
+ //
+ DWORD nextIndex = (oneSamplingSize * (m_maxSampling - tail))/sizeof(DWORD);
+ memcpy(&(m_get_sampling_arr[nextIndex]), m_sampling_arr, oneSamplingSize * head);
+ total_copy = oneSamplingSize * (m_maxSampling - tail) + oneSamplingSize * head;
+ }
+ break;
+ case 3:
+ {
+ // copy all the cyclic buffer, starting from the head
+ // the head is pointing to the next place to put there new sample.
+ // there is a racing condition because it is possible that just before
+ // we will start coping a context switch will happened and the read
+ // sampling thread will overwrite this area.
+ // we are not locking this sharing resource for now
+ memcpy(m_get_sampling_arr, &(m_sampling_arr[head]), oneSamplingSize * (m_maxSampling - head));
+ // copy from the beginning till the head
+ DWORD nextIndex = (oneSamplingSize * (m_maxSampling - head))/sizeof(DWORD);
+ memcpy(&(m_get_sampling_arr[nextIndex]), &(m_sampling_arr[0]), oneSamplingSize * head);
+ total_copy = oneSamplingSize * m_maxSampling;
+
+ LOG_MESSAGE_WARN(_T("detect a loop [%d]. samples lost."), m_loops);
+ }
+ break;
+ }
+
+ m_loops = 0;
+ m_sampling_tail = head;
+ LOG_MESSAGE_DEBUG(_T("[m_sampling_tail %X] [total_copy %d]"), m_sampling_tail, total_copy);
+
+ *pDataSamples = m_get_sampling_arr;
+ return total_copy;
+ }
+*/
+int CPciDeviceAccess::alloc_pmc(int num_of_descriptors, int size_of_descriptor){
+ if (!isInitialized())
+ {
+ LOG_MESSAGE_ERROR(_T("alloc_pmc - Not initialized"));
+ return -1;
+ }
+ if (m_close_state == 2)
+ {
+ Open();
+ }
+ if (!IoctlDev.IsOpened())
+ {
+ LOG_MESSAGE_ERROR(_T("alloc_pmc - Not opened"));
+ return -1;
+ }
+
+ int data[2] = {num_of_descriptors, size_of_descriptor};
+ int res = IoctlDev.DebugFS((char*)"pmccfg", data, 8, 0);
+
+ if (res != WLCT_OS_ERROR_SUCCESS)
+ {
+ LOG_MESSAGE_ERROR(_T("Cannot open DebugFS for pmccfg: 0x%X"), res);
+ }
+
+ return res;
+}
+#ifdef _WINDOWS
+int CPciDeviceAccess::send_wmi_cmd(SEND_RECEIVE_WMI* wmi)
+{
+ LOG_MESSAGE_INFO(_T("send_wmi_cmd: 0x%X"), wmi->uCmdId);
+
+ if (!isInitialized())
+ return -1;
+
+
+ lastError = IoctlDev.Ioctl(WILOCITY_IOCTL_SEND_WMI, wmi, sizeof(SEND_RECEIVE_WMI), NULL, 0);
+
+ if (lastError != WLCT_OS_ERROR_SUCCESS)
+ {
+ LOG_MESSAGE_WARN(_T("WILOCITY_IOCTL_SEND_WMI failed. %X"), lastError);
+ return lastError;
+ }
+
+
+ return 0;
+}
+
+int CPciDeviceAccess::recieve_wmi_event(SEND_RECEIVE_WMI* evt)
+{
+ LOG_MESSAGE_INFO(_T("recieve_wmi_event"));
+
+ if (!isInitialized())
+ return -1;
+
+
+ lastError = IoctlDev.Ioctl( WILOCITY_IOCTL_RECEIVE_WMI, NULL, 0, evt, sizeof(SEND_RECEIVE_WMI));
+
+ if (lastError != WLCT_OS_ERROR_SUCCESS)
+ {
+ LOG_MESSAGE_WARN(_T("WILOCITY_IOCTL_RECEIVE_WMI failed. %X"), lastError);
+ return lastError;
+ }
+
+ return 0;
+}
+#endif //_WINDOWS
+
+int CPciDeviceAccess::register_driver_mailbox_event(HANDLE* pMailboxEventHandle )
+{
+ LOG_MESSAGE_INFO(_T("register_driver_mailbox_event"));
+
+ if (!isInitialized())
+ return -1;
+ if (!IoctlDev.IsOpened())
+ return -1;
+
+ REGISTER_EVENT req;
+ memset(&req, 0, sizeof(REGISTER_EVENT));
+
+ req.hEvent = *pMailboxEventHandle;
+
+ lastError = IoctlDev.Ioctl(WILOCITY_IOCTL_REGISTER_WMI_RX_EVENT, &req, sizeof(REGISTER_EVENT), NULL, 0);
+
+ if (lastError != WLCT_OS_ERROR_SUCCESS)
+ {
+ LOG_MESSAGE_WARN(_T("WILOCITY_IOCTL_REGISTER_WMI_RX_EVENT failed. 0x%X"), lastError);
+ InternalCloseDevice();
+ return -1;
+ }
+
+ return ERROR_SUCCESS;
+}
+
+int CPciDeviceAccess::register_device_unplug2(INT_PTR hEvent){
+ LOG_MESSAGE_INFO(_T("register_device_unplug2"));
+
+ WLCT_UNREFERENCED_PARAM(hEvent);
+
+ if (!isInitialized())
+ return -1;
+ if (!IoctlDev.IsOpened())
+ return -1;
+
+
+#ifdef _WINDOWS
+ DRIVER_REGISTER_EVENT req;
+ memset(&req, 0, sizeof(DRIVER_REGISTER_EVENT));
+ LOG_MESSAGE_INFO(_T("register_device_unplug2: <Event Pointer=0x%p>"), hEvent);
+ req.UserEventHandle = hEvent;
+
+ lastError = IoctlDev.Ioctl( WILOCITY_IOCTL_REGISTER_DEVICE, &req, sizeof(req), NULL, 0);
+
+
+#endif //_WINDOWS
+
+ if (lastError != WLCT_OS_ERROR_SUCCESS)
+ {
+ LOG_MESSAGE_WARN(_T("register_device_unplug2 failed. 0x%X"), lastError);
+ InternalCloseDevice();
+ return -1;
+ }
+
+ return ERROR_SUCCESS;
+}
+
+int CPciDeviceAccess::unregister_device_unplug2(){
+ LOG_MESSAGE_INFO(_T("unregister_device_unplug2"));
+
+ if (!isInitialized())
+ return -1;
+ if (!IoctlDev.IsOpened())
+ return -1;
+
+
+#ifdef _WINDOWS
+ DRIVER_REGISTER_EVENT req;
+ memset(&req, 0, sizeof(DRIVER_REGISTER_EVENT));
+ LONG invalidPointer = -1;
+ LOG_MESSAGE_INFO(_T("register_device_unplug2: <Event Pointer=0x%X>"), invalidPointer);
+ req.UserEventHandle = invalidPointer;
+
+ lastError = IoctlDev.Ioctl( WILOCITY_IOCTL_REGISTER_DEVICE, &req, sizeof(req), NULL, 0);
+
+
+#endif //_WINDOWS
+
+ if (lastError != WLCT_OS_ERROR_SUCCESS)
+ {
+ LOG_MESSAGE_WARN(_T("register_device_unplug2 failed. 0x%X"), lastError);
+ InternalCloseDevice();
+ return -1;
+ }
+
+ return ERROR_SUCCESS;
+}
+
+
+
+int CPciDeviceAccess::register_driver_device_event(INT_PTR hEvent,int deviceId, int eventId)
+{
+ LOG_MESSAGE_INFO(_T("register_driver_device_event"));
+ WLCT_UNREFERENCED_PARAM(hEvent);
+ WLCT_UNREFERENCED_PARAM(deviceId);
+ WLCT_UNREFERENCED_PARAM(eventId);
+
+ if (!isInitialized())
+ return -1;
+ if (!IoctlDev.IsOpened())
+ return -1;
+
+
+#ifdef _WINDOWS
+
+ LOG_MESSAGE_INFO(_T("register_driver_device_event: <Event Pointer=0x%p> <deviceId=0x%x> <EventId=0x%x>"), hEvent, deviceId, eventId);
+
+ // Our DLL assumed to be always compiled for 32bit application.
+ // Since the driver excpects to recieve HANDLEs of size that IS platform speciefic,
+ // we must dynamically find out if we are running on 64bit OS or now.
+ // for more information, read remarks on WlcyPciAcssWmi.h file
+ if (Util::Is64BitWindows())
+ {
+ LOG_MESSAGE_INFO(_T("register_driver_device_event Driver HANDLE problem WA, using 64bit struct"));
+ EVENT_HANDLE_64BIT req;
+ memset(&req, 0, sizeof(EVENT_HANDLE_64BIT));
+ req.DeviceId = deviceId;
+ req.EventId = eventId;
+ req.hEvent_l = hEvent;
+ req.hEvent_h = 0;
+
+ lastError = IoctlDev.Ioctl( WILOCITY_IOCTL_REGISTER_EVENT, &req, sizeof(req), NULL, 0);
+
+
+ }
+ else
+ {
+ LOG_MESSAGE_INFO(_T("register_driver_device_event Driver HANDLE problem WA, using 32bit struct"));
+ EVENT_HANDLE_32BIT req;
+ memset(&req, 0, sizeof(EVENT_HANDLE_32BIT));
+
+ req.DeviceId = deviceId;
+ req.EventId = eventId;
+ req.hEvent = hEvent;
+
+ lastError = IoctlDev.Ioctl( WILOCITY_IOCTL_REGISTER_EVENT, &req, sizeof(req), NULL, 0);
+ }
+
+#endif //_WINDOWS
+
+ if (lastError != WLCT_OS_ERROR_SUCCESS)
+ {
+ LOG_MESSAGE_WARN(_T("WILOCITY_IOCTL_REGISTER_EVENT failed. 0x%X"), lastError);
+ InternalCloseDevice();
+ return -1;
+ }
+ //do something with params
+ (void)deviceId;
+ (void)eventId;
+ return ERROR_SUCCESS;
+}
+int CPciDeviceAccess::register_driver_device_events(INT_PTR hDnEvent, INT_PTR hUpEvent, INT_PTR hUnplugEvent, INT_PTR hSysAssertEvent)
+{
+ LOG_MESSAGE_INFO(_T("register_driver_device_events"));
+ WLCT_UNREFERENCED_PARAM(hDnEvent);
+ WLCT_UNREFERENCED_PARAM(hUpEvent);
+ WLCT_UNREFERENCED_PARAM(hUnplugEvent);
+ WLCT_UNREFERENCED_PARAM(hSysAssertEvent);
+
+ if (!isInitialized())
+ return -1;
+ if (!IoctlDev.IsOpened())
+ return -1;
+
+
+#ifdef _WINDOWS
+
+ LOG_MESSAGE_INFO(_T("register_driver_device_events: <hDnEvent=0x%p> <hUpEvent=0x%p> <hUnplugEvent=0x%p> <hSysAssertEvent=0x%p>"), hDnEvent, hUpEvent, hUnplugEvent, hSysAssertEvent );
+
+ // Our DLL assumed to be always compiled for 32bit application.
+ // Since the driver excpects to recieve HANDLEs of size that IS platform speciefic,
+ // we must dynamically find out if we are running on 64bit OS or now.
+ // for more information, read remarks on WlcyPciAcssWmi.h file
+ if (Util::Is64BitWindows())
+ {
+ LOG_MESSAGE_INFO(_T("register_driver_device_events Driver HANDLES problem WA, using 64bit struct"));
+ SHARED_EVENT_64BIT req;
+ memset(&req, 0, sizeof(SHARED_EVENT_64BIT));
+
+ req.hDnEvent_l = hDnEvent;
+ req.hDnEvent_h = 0;
+ req.hUpEvent_l = hUpEvent;
+ req.hUpEvent_h = 0;
+ req.unplugEvent_l = hUnplugEvent;
+ req.hUpEvent_h = 0;
+ req.sysAssertEvent_l = hSysAssertEvent;
+ req.sysAssertEvent_h = 0;
+
+ lastError = IoctlDev.Ioctl( IOCTL_OPEN_USER_MODE_EVENT, &req, sizeof(req), NULL, 0);
+
+
+ }
+ else
+ {
+ LOG_MESSAGE_INFO(_T("register_driver_device_events Driver HANDLES problem WA, using 32bit struct"));
+ SHARED_EVENT_32BIT req;
+ memset(&req, 0, sizeof(SHARED_EVENT_32BIT));
+
+ req.hDnEvent = hDnEvent;
+ req.hUpEvent = hUpEvent;
+ req.unplugEvent = hUnplugEvent;
+ req.sysAssertEvent = hSysAssertEvent;
+
+ lastError = IoctlDev.Ioctl( IOCTL_OPEN_USER_MODE_EVENT, &req, sizeof(req), NULL, 0);
+ }
+
+#endif //_WINDOWS
+
+ if (lastError != WLCT_OS_ERROR_SUCCESS)
+ {
+ LOG_MESSAGE_WARN(_T("IOCTL_OPEN_USER_MODE_EVENT failed. 0x%X"), lastError);
+ InternalCloseDevice();
+ return -1;
+ }
+
+ return ERROR_SUCCESS;
+}
+
+int CPciDeviceAccess::unregister_driver_device_events()
+{
+ LOG_MESSAGE_INFO(_T("unregister_driver_device_events"));
+
+ if (!isInitialized())
+ return -1;
+ if (!IoctlDev.IsOpened())
+ return -1;
+
+
+#ifdef _WINDOWS
+
+ LOG_MESSAGE_INFO(_T("unregister_driver_device_events with invalid handles"));
+
+ // Our DLL assumed to be always compiled for 32bit application.
+ // Since the driver excpects to recieve HANDLEs of size that IS platform speciefic,
+ // we must dynamically find out if we are running on 64bit OS or now.
+ // for more information, read remarks on WlcyPciAcssWmi.h file
+ if (Util::Is64BitWindows())
+ {
+ LOG_MESSAGE_INFO(_T("register_driver_device_events Driver HANDLES problem WA, using 64bit struct"));
+ SHARED_EVENT_64BIT req;
+ memset(&req, 0, sizeof(SHARED_EVENT_64BIT));
+
+ req.hDnEvent_l = -1;
+ req.hDnEvent_h = -1;
+ req.hUpEvent_l = -1;
+ req.hUpEvent_h = -1;
+ req.unplugEvent_l = -1;
+ req.hUpEvent_h = -1;
+ req.sysAssertEvent_l = -1;
+ req.sysAssertEvent_h = -1;
+
+ lastError = IoctlDev.Ioctl( IOCTL_OPEN_USER_MODE_EVENT, &req, sizeof(req), NULL, 0);
+
+
+ }
+ else
+ {
+ LOG_MESSAGE_INFO(_T("register_driver_device_events Driver HANDLES problem WA, using 32bit struct"));
+ SHARED_EVENT_32BIT req;
+ memset(&req, 0, sizeof(SHARED_EVENT_32BIT));
+
+ req.hDnEvent = -1;
+ req.hUpEvent = -1;
+ req.unplugEvent = -1;
+ req.sysAssertEvent = -1;
+
+ lastError = IoctlDev.Ioctl( IOCTL_OPEN_USER_MODE_EVENT, &req, sizeof(req), NULL, 0);
+ }
+
+#endif //_WINDOWS
+
+ if (lastError != WLCT_OS_ERROR_SUCCESS)
+ {
+ LOG_MESSAGE_WARN(_T("IOCTL_OPEN_USER_MODE_EVENT failed. 0x%X"), lastError);
+ InternalCloseDevice();
+ return -1;
+ }
+
+ return ERROR_SUCCESS;
+}
+
+int CPciDeviceAccess::setMpDriverLogLevels(ULONG logModulesEnableMsk, ULONG logModuleLevelsMsk[WILO_DRV_NUM_LOG_COMPS])
+{
+ LOG_MESSAGE_INFO(_T("setMpDriverLogLevels"));
+
+ if (!isInitialized())
+ return -1;
+ if (!IoctlDev.IsOpened())
+ return -1;
+
+ DRIVER_LOGS_CFG req;
+ memset(&req, 0, sizeof(DRIVER_LOGS_CFG));
+ req.logModulesEnableMsk = logModulesEnableMsk;
+ memcpy( req.logModuleLevelsMsk, logModuleLevelsMsk, (WILO_DRV_NUM_LOG_COMPS*4)) ;
+
+ lastError = IoctlDev.Ioctl( WILOCITY_IOCTL_DRIVER_LOG_LEVELS_CFG, &req, sizeof(req), NULL, 0);
+
+ if (lastError != WLCT_OS_ERROR_SUCCESS)
+ {
+ LOG_MESSAGE_WARN(_T("WILOCITY_IOCTL_DRIVER_LOG_LEVELS_CFG failed. 0x%X"), lastError);
+ InternalCloseDevice();
+ return -1;
+ }
+
+ return ERROR_SUCCESS;
+}
diff --git a/debug-tools/lib/WlctPciAcss/PciDeviceAccess.h b/debug-tools/lib/WlctPciAcss/PciDeviceAccess.h
new file mode 100644
index 0000000..8c2d741
--- /dev/null
+++ b/debug-tools/lib/WlctPciAcss/PciDeviceAccess.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "DeviceAccess.h"
+#include "WlctPciAcss.h"
+#include "IoctlDev.h"
+#include "Thread.h"
+#include "public.h"
+
+#ifdef _WINDOWS
+#include "ioctl_if.h"
+#else
+// some definitions from ioctl_if.h
+#define WILOCITY_IOCTL_INDIRECT_READ IOCTL_INDIRECT_READ_OLD
+#define WILOCITY_IOCTL_INDIRECT_WRITE IOCTL_INDIRECT_WRITE_OLD
+#define WILOCITY_IOCTL_INDIRECT_READ_BLOCK IOCTL_INDIRECT_READ_BLOCK
+#define WILOCITY_IOCTL_INDIRECT_WRITE_BLOCK IOCTL_INDIRECT_WRITE_BLOCK
+#endif
+
+extern "C" class CPciDeviceAccess : public IDeviceAccess
+{
+public:
+ CPciDeviceAccess(const TCHAR* tchDeviceName, DType devType);
+ ~CPciDeviceAccess();
+
+ virtual int CloseDevice();
+ virtual int GetType();
+ virtual int r32(DWORD addr, DWORD & val);
+ virtual int w32(DWORD addr, DWORD val);
+ virtual int rb(DWORD addr, DWORD blockSize, char *arrBlock);
+ virtual int wb(DWORD addr, DWORD blockSize, const char *arrBlock);
+ virtual int rr(DWORD addr, DWORD num_repeat, DWORD *arrBlock);
+ virtual int getFwDbgMsg(FW_DBG_MSG** pMsg);
+ virtual int clearAllFwDbgMsg();
+ virtual int do_reset(BOOL bFirstTime = TRUE);
+ virtual int do_sw_reset();
+ virtual int do_interface_reset();
+#ifdef _WINDOWS
+ virtual int send_wmi_cmd(SEND_RECEIVE_WMI* wmi) ;
+ virtual int recieve_wmi_event(SEND_RECEIVE_WMI* evt) ;
+
+ virtual int SetDriverMode(int newState, int &oldState, int &payload);
+ virtual int GetDriverMode(int ¤tState);
+#endif // _WINDOWS
+ virtual int register_driver_mailbox_event(HANDLE* pMailboxEventHandle );
+ virtual int register_driver_device_events(INT_PTR hDnEvent, INT_PTR hUpEvent, INT_PTR hUnplugEvent, INT_PTR hSysAssertEvent);
+ virtual int unregister_driver_device_events();
+ virtual int register_driver_device_event(INT_PTR hEvent, int eventId, int deviceId);
+ virtual int register_device_unplug2(INT_PTR hEvent);
+ virtual int unregister_device_unplug2();
+ virtual int setMpDriverLogLevels(ULONG logModulesEnableMsk, ULONG logModuleLevelsMsk[WILO_DRV_NUM_LOG_COMPS]);
+ virtual int alloc_pmc(int num_of_descriptors, int size_of_descriptor);
+
+ int reset_complete();
+ void Open();
+ int InternalCloseDevice();
+
+ /*virtual int startSampling(
+ DWORD* pRegsArr,
+ DWORD regArrSize,
+ DWORD interval,
+ DWORD maxSampling,
+ DWORD transferMethod);
+ virtual int stopSampling();
+ virtual int getSamplingData(DWORD** pDataSamples);*/
+
+ // 0 - not closed
+ // 1 - need to be close
+ // 2 - close
+ DWORD m_close_state;
+ // 0 - not opened
+ // 1 - need to be open
+ // 2 - open
+ DWORD m_open_state;
+
+private:
+ void rr32(DWORD addr, DWORD num_repeat, DWORD *arrBlock);
+ int ReOpen();
+ bool try2open(int timeout);
+
+private:
+ static void SamplingThreadProc(void *pDeviceAccss);
+ static void PciPluginThreadProc(void *pDeviceAccss);
+
+ // handle to the control device in wPci driver
+ CIoctlDev IoctlDev;
+
+ // true if device is Local (wPciL)
+ // false if device is remote (wPciR)
+ bool bIsLocal;
+
+ DWORD dwBaseAddress;
+
+};
diff --git a/debug-tools/lib/WlctPciAcss/PciPluginThreadXFace.h b/debug-tools/lib/WlctPciAcss/PciPluginThreadXFace.h
new file mode 100644
index 0000000..fc5937d
--- /dev/null
+++ b/debug-tools/lib/WlctPciAcss/PciPluginThreadXFace.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "Thread.h"
+
+class CPciDeviceAccess;
+
+class IWlctPluginThread : public CWlctThread
+{
+public:
+ IWlctPluginThread(CPciDeviceAccess *pciDeviceAccess)
+ : CWlctThread(GlobalPluginThreadMain, this), pAccess(pciDeviceAccess)
+ {
+
+ }
+ virtual ~IWlctPluginThread() {;}
+
+ virtual void PluginThreadMain() = 0;
+
+protected:
+ CPciDeviceAccess *pAccess;
+
+ static void GlobalPluginThreadMain(void *p);
+};
diff --git a/debug-tools/lib/WlctPciAcss/Util.h b/debug-tools/lib/WlctPciAcss/Util.h
new file mode 100644
index 0000000..88a6fa4
--- /dev/null
+++ b/debug-tools/lib/WlctPciAcss/Util.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "wlct_os.h"
+
+class Util
+{
+public:
+ static bool getFileVersionInfo(const TCHAR *fileNameFillPath, int &mjr, int &mnr, int &mnt, int &build);
+ static BOOL IsNumeric(LPCTSTR pszString, BOOL bIgnoreColon);
+ static DWORD ReadRegistrySettings(LPCTSTR lpszRegistryPath, LPCTSTR valName);
+ static DWORD WriteRegistrySettings(LPCTSTR lpszRegistryPath, LPCTSTR valName, DWORD val);
+ static int IsWlctDevicePlugin();
+// static bool Util::GetWlstPluggedInDevice();
+ static bool ICHDisableEnable();
+ static bool GetPciControllerDevicePath(TCHAR* devicePath);
+
+ // perfrom atomic change value, to acquire resource!
+ // if VAR != FLAG_VALUE, then set VAR to FLAG_VALUE.
+ // loop until timeout (milisec). return success in acheiving resource
+ // Assumes that FLAG_VALUE should be diffrent then current value stored in VAR
+ // turn keepWaiting on to wait infinite
+
+ static BOOL timedResourceInterLockExchange ( LONG* var, LONG flag_value, int timeout, bool keepWaiting );
+
+ static BOOL Is64BitWindows();
+
+private:
+ Util(void);
+ ~Util(void);
+};
+
+#ifdef _WINDOWS
+#include <setupapi.h>
+#include <cfgmgr32.h>
+
+typedef HKEY (__stdcall SETUPDIOPENDEVREGKEY)(HDEVINFO, PSP_DEVINFO_DATA, DWORD, DWORD, DWORD, REGSAM);
+typedef BOOL (__stdcall SETUPDICLASSGUIDSFROMNAME)(LPCTSTR, LPGUID, DWORD, PDWORD);
+typedef BOOL (__stdcall SETUPDIDESTROYDEVICEINFOLIST)(HDEVINFO);
+typedef BOOL (__stdcall SETUPDIENUMDEVICEINFO)(HDEVINFO, DWORD, PSP_DEVINFO_DATA);
+typedef HDEVINFO (__stdcall SETUPDIGETCLASSDEVS)(LPGUID, LPCTSTR, HWND, DWORD);
+typedef BOOL (__stdcall SETUPDIGETDEVICEREGISTRYPROPERTY)(HDEVINFO, PSP_DEVINFO_DATA, DWORD, PDWORD, PBYTE, DWORD, PDWORD);
+typedef DWORD (__stdcall CM_GET_DEVICE_ID)(DEVINST, PTCHAR, ULONG, ULONG);
+#endif
diff --git a/debug-tools/lib/WlctPciAcss/WlctPciAcss.cpp b/debug-tools/lib/WlctPciAcss/WlctPciAcss.cpp
new file mode 100644
index 0000000..49740b3
--- /dev/null
+++ b/debug-tools/lib/WlctPciAcss/WlctPciAcss.cpp
@@ -0,0 +1,1544 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include "WlctPciAcss.h"
+#include "WlctPciAcssHelper.h"
+#include "wlct_os.h"
+#include "DeviceAccess.h"
+#include "PciDeviceAccess.h"
+#ifdef _WINDOWS
+#include "JtagDeviceAccess.h"
+#include "SerialDeviceAccess.h"
+#endif
+#include "MemoryAccess.h"
+#include "Util.h"
+
+#ifdef _WINDOWS
+#define WIGIG_REGISTRY_PATH _T("Software\\QualcommAtheros\\WIGIG")
+#endif
+
+using namespace std;
+
+#define WLCT_IFACE_NAME_LEN 256
+#define BL_READY_TIMEOUT_MS 1000
+#define BL_READY_WAIT_INTERVAL_MS 20
+
+WLCTPCIACSS_API int GetMyVersion(WLCT_DLL_VERSION *pVer)
+{
+ return GetPciAcssVersion(pVer);
+}
+
+WLCTPCIACSS_API bool wPciDisableEnable()
+{
+ return Util::ICHDisableEnable();
+}
+
+// return 0 for success
+WLCTPCIACSS_API int GetInterfaces(INTERFACE_LIST* ifList, int* ReturnItems)
+{
+ *ReturnItems = 0;
+// int ret = 0;
+#ifdef _WINDOWS
+#ifndef NO_JTAG
+ if (!jtagLoaded) {
+ if (!load_jtag_dll()) {
+ printf("jTag DLL were not found, skipping jTag interfaces...\n");
+ }
+ }
+#endif
+#endif
+
+ for (int i = 0; i < MAX_INTERFACES; i++)
+ {
+ memset(ifList->list[i].ifName, 0, MAX_IF_NAME_LENGTH);
+ }
+
+#ifdef _WINDOWS
+ LOG_MESSAGE_INFO(_T("Checking registry for SkipSerialInterfaces register"));
+ DWORD dwSkip = Util::ReadRegistrySettings(WIGIG_REGISTRY_PATH, _T("SkipSerialInterfaces"));
+ if (dwSkip == (DWORD)-1)
+ {
+ LOG_MESSAGE_INFO(_T("SkipSerialInterfaces not found, adding registry key with default set to skip serial interfaces scan"));
+ dwSkip = 0;
+ Util::WriteRegistrySettings(WIGIG_REGISTRY_PATH, _T("SkipSerialInterfaces"), dwSkip);
+ }
+ else if (dwSkip == 0)
+ {
+ LOG_MESSAGE_INFO(_T("Get Interfaces for Serial"));
+ GetSerialInterfaces(ifList, ReturnItems);
+ }
+ else
+ {
+ LOG_MESSAGE_INFO(_T("SkipSerialInterfaces registry key found, skipping serial interface scan"));
+ }
+#endif
+
+ LOG_MESSAGE_INFO(_T("Get Interfaces for PCI"));
+ GetPciInterfaces(ifList, ReturnItems);
+
+#ifdef _WINDOWS
+#ifndef NO_JTAG
+ if (jtagLoaded)
+ {
+ LOG_MESSAGE_INFO(_T("Get Interfaces for jTag"));
+ GetJtagInterfaces(ifList, ReturnItems);
+ }
+#endif
+
+#ifndef NO_SERIAL
+ //GetSerialInterfaces(ifList, ReturnItems);
+#endif
+
+#endif
+
+ printf("Found %d interfaces \n",*ReturnItems);
+
+ return 0;
+}
+
+WLCTPCIACSS_API int StrGetInterfaces(char* ifListStr, int capacity)
+{
+ INTERFACE_LIST ifList;
+ int ReturnItems;
+ int ret = GetInterfaces(&ifList, &ReturnItems);
+ WLCT_UNREFERENCED_PARAM(ret);
+
+ std::ostringstream ifListBuilder;
+
+ for (int item = 0; item < ReturnItems; item++)
+ {
+ ifListBuilder << ifList.list[item].ifName << ' ';
+ }
+
+ int ifListActualLength = _snprintf(ifListStr, capacity, "%s", ifListBuilder.str().c_str());
+ if (ifListActualLength >= capacity)
+ {
+ LOG_MESSAGE_ERROR(
+ _T("Error filling interface list: %S, insufficient buffer capacity: %d\n"),
+ ifListBuilder.str().c_str(), capacity);
+ return 1;
+ }
+
+ LOG_MESSAGE_INFO(_T("Interfaces returned: %S"), ifListStr);
+ return 0;
+}
+
+// NAME OF FUNCTION: CreateDeviceAccessHandler
+// CREDIT:
+// PURPOSE:
+// The function will create and will initialize an access of read and write
+// to Wilocity hardware. According to tchDeviceName it will interpret the
+// access type (COM port, PCIe driver or Jtag)
+//
+// PARAMETERS:
+// name type value/reference description
+// ---------------------------------------------------------------------
+// tchDeviceName TCHAR* reference the name of the access interface
+// devType int value the hardware type (MARLON)
+//
+// RETURN VALUE:
+// name type description
+// handle / pointer to the access object.
+//
+// NOTE:
+// After calling this
+// ---------------------------------------------------------------------
+// func return void* the overall total enrollment for the university
+//
+// CALLS TO: This is a factory method. According to the device name it interprets
+// the right interface and create a new object.
+//
+// CALLED FROM: main
+//
+// METHOD: The following is a factory.
+
+WLCTPCIACSS_API int CreateDeviceAccessHandler(const char* deviceName, DType devType, void** pDeviceAccess)
+{
+ LOG_STACK_ENTER;
+ IDeviceAccess* pIDeviceAccss = NULL;
+ const TCHAR* const delimit = _T("!");
+
+ TCHAR *tchDeviceName;
+
+ TCHAR *next_token = NULL;
+ DType devTypeFromInterface = devType;
+ TCHAR tchInterfaceName[WLCT_IFACE_NAME_LEN];
+ TCHAR tchOriginalInterfaceName[WLCT_IFACE_NAME_LEN];
+
+ // tchInterfaceName may be not null-terminated after calling _tcscpy_s()
+ _tcscpy_s(tchInterfaceName, WLCT_IFACE_NAME_LEN, TSTR_ARG(deviceName));
+ tchInterfaceName[WLCT_IFACE_NAME_LEN - 1] = '\0';
+
+ _tcscpy_s(tchOriginalInterfaceName, WLCT_IFACE_NAME_LEN, TSTR_ARG(deviceName));
+ //tchOriginalInterfaceName[WLCT_IFACE_NAME_LEN - 1] = '\0';
+
+ LOG_MESSAGE_INFO(_T("CreateDeviceAccessHandler for interface named: %s"), tchInterfaceName);
+
+ tchDeviceName = _tcstok_s( tchInterfaceName, delimit, &next_token);
+
+ if (!tchDeviceName)
+ {
+ LOG_MESSAGE_ERROR(_T("No device name found"));
+ return WLCT_OS_ERROR_NOT_SUPPORTED;
+ }
+
+ if (_tcsstr(tchDeviceName, _T("wPci")) == tchDeviceName ||
+ _tcsstr(tchDeviceName, _T("wpci")) == tchDeviceName)
+ {
+ if (devTypeFromInterface != devType)
+ {
+ return WLCT_OS_ERROR_NOT_SUPPORTED;
+ }
+ LOG_MESSAGE_INFO(_T("wPci Interface detected"));
+ pIDeviceAccss = new CPciDeviceAccess(tchDeviceName, devType);
+ }
+ else if (_tcsstr(tchDeviceName, _T("wMp")) == tchDeviceName ||
+ _tcsstr(tchDeviceName, _T("wmp")) == tchDeviceName)
+ {
+ if (devTypeFromInterface != devType)
+ {
+ return WLCT_OS_ERROR_NOT_SUPPORTED;
+ }
+ LOG_MESSAGE_INFO(_T("wMp Interface detected"));
+ pIDeviceAccss = new CPciDeviceAccess(tchDeviceName, devType);
+ }
+ else if (_tcsstr(tchDeviceName, _T("wEP")) == tchDeviceName ||
+ _tcsstr(tchDeviceName, _T("wep")) == tchDeviceName)
+ {
+ LOG_MESSAGE_INFO(_T("wEP Interface detected"));
+ pIDeviceAccss = new CPciDeviceAccess(tchOriginalInterfaceName, devType);
+ }
+ else if (_tcsstr(tchDeviceName, _T("wController")) == tchDeviceName ||
+ _tcsstr(tchDeviceName, _T("wcontroller")) == tchDeviceName)
+ {
+ if (devTypeFromInterface != devType)
+ {
+ return WLCT_OS_ERROR_NOT_SUPPORTED;
+ }
+ LOG_MESSAGE_INFO(_T("wController Interface detected"));
+ pIDeviceAccss = new CPciDeviceAccess(tchDeviceName, devType);
+ } // acceptable format is: com3, COM3
+ else if (_tcsstr(tchDeviceName, _T("COM")) == tchDeviceName ||
+ _tcsstr(tchDeviceName, _T("com")) == tchDeviceName)
+ {
+ if (devTypeFromInterface != devType)
+ {
+ return WLCT_OS_ERROR_NOT_SUPPORTED;
+ }
+
+#ifdef _WINDOWS
+ pIDeviceAccss = new CSerialDeviceAccess(tchDeviceName, devType);
+ pIDeviceAccss->SetLastError(0);
+#else
+ return WLCT_OS_ERROR_NOT_SUPPORTED;
+#endif
+ }
+ else /*if (_tcsicmp(tchDeviceName, _T("wjtag")) == 0)*/
+ {
+ if (devTypeFromInterface != devType)
+ {
+ return WLCT_OS_ERROR_NOT_SUPPORTED;
+ }
+#ifdef _WINDOWS
+#ifndef NO_JTAG
+ pIDeviceAccss = new CJtagDeviceAccess(tchDeviceName, devType);
+ if (pIDeviceAccss->lastError == WLCT_OS_ERROR_OPEN_FAILED)
+ {
+ printf("JTAG CJtagDeviceAccess creation failed!\n");
+ return WLCT_OS_ERROR_NOT_SUPPORTED;
+ }
+#endif
+#else
+ return WLCT_OS_ERROR_NOT_SUPPORTED;
+#endif
+ }
+
+ // Sanity check - pIDeviceAccss should be set according to the access type in the above block
+ if (!pIDeviceAccss)
+ {
+ LOG_MESSAGE_ERROR(_T("No device access handler is set"));
+ return WLCT_OS_ERROR_NOT_SUPPORTED;
+ }
+
+ // assume device type = unknown and search for correct device type
+ pIDeviceAccss->SetDeviceStep(STEP_NONE);
+
+ DWORD rev_id_address = 0x880B34;
+ DWORD dft_signature_address = 0x800C;
+ DWORD val = 0;
+
+ int ret = WlctAccssRead(pIDeviceAccss, rev_id_address, val);
+ LOG_MESSAGE_INFO(_T("RevID on [%S] is [0x%X]"),deviceName,val);
+ if (ret == 0 && val != 0xFFFFFFFF)
+ {
+ if (devType == MST_MARLON)
+ {
+ if (val == 0x612072F)
+ {
+ pIDeviceAccss->SetDeviceStep(MARLON_STEP_B0);
+ LOG_MESSAGE_INFO(_T("MARLON STEP B0"));
+ }
+
+ /* This is not really Marlon, it is a DFT device and it should have
+ been a different gateway (not a step inside Marlon) */
+ else if (val == 0x0) // DFT
+ {
+ int ret = WlctAccssRead(pIDeviceAccss, dft_signature_address, val);
+ if (ret == 0 && val == 0xCE4)
+ {
+ pIDeviceAccss->SetDeviceStep(DFT_STEP);
+ LOG_MESSAGE_INFO(_T("DFT STEP"));
+ }
+ }
+ else
+ {
+
+ //for now always use marlon as B0
+
+ // Device doesn't match the device type MST_MARLON
+ LOG_MESSAGE_INFO(_T("NOT Marlon, RevID = [0x%X], closing handler.."),val);
+ pIDeviceAccss->CloseDevice();
+ return WLCT_OS_ERROR_NOT_SUPPORTED;
+ }
+ }
+ else if (devType == MST_SPARROW)
+ {
+ if (val == 0x0632072F)
+ {
+ pIDeviceAccss->SetDeviceStep(SPARROW_STEP_A0);
+ LOG_MESSAGE_INFO(_T("SPARROW STEP A0"));
+ }
+ else if(val == 0x1632072F)
+ {
+ pIDeviceAccss->SetDeviceStep(SPARROW_STEP_A1);
+ LOG_MESSAGE_INFO(_T("SPARROW STEP A1"));
+ }
+ else if (val == 0x2632072F)
+ {
+ pIDeviceAccss->SetDeviceStep(SPARROW_STEP_B0);
+ LOG_MESSAGE_INFO(_T("SPARROW STEP B0"));
+ }
+ else
+ {
+ LOG_MESSAGE_INFO(_T("Unknown RevID = [0x%X] "),val);
+ // This case is for future unrecognized devices, for example, MST_NONE
+ pIDeviceAccss->SetDeviceStep(STEP_NONE);
+ LOG_MESSAGE_INFO(_T("UNKNOWN DEVICE found, assuming it is Sparrow's next step"));
+ //pIDeviceAccss->CloseDevice();
+ //return WLCT_OS_ERROR_NOT_SUPPORTED;
+ }
+ }
+ }
+ else
+ {
+ pIDeviceAccss->SetLastError(-1);
+ }
+
+ *pDeviceAccess = (void*)pIDeviceAccss;
+ return pIDeviceAccss->GetLastError();
+}
+
+WLCTPCIACSS_API int CloseDeviceAccessHandler(void* pDeviceAccss)
+{
+ int res = 0;
+ IDeviceAccess* pIDevice = (IDeviceAccess*)pDeviceAccss;
+ if (pIDevice != NULL)
+ {
+ __TRY
+ {
+ pIDevice->CloseDevice();
+ #ifdef _WINDOWS
+ delete pIDevice;
+ #else
+ pIDevice = NULL;
+ #endif
+ }
+ __EXCEPT(EXCEPTION_ACCESS_VIOLATION == GetExceptionCode())
+ {
+ LOG_MESSAGE_ERROR(_T("got exception"));
+ res = -1;
+ }
+ }
+ return res;
+}
+
+#ifdef _WINDOWS
+WLCTPCIACSS_API int WlctAccssSetDriverMode(void* pDeviceAccss, int newState, int & oldState, int &payloadResult){
+ if(pDeviceAccss == NULL){
+ return -1;
+ }
+ int res = 0;
+ int got_resource;
+
+ // Get Resource
+ got_resource = Util::timedResourceInterLockExchange( &((((IDeviceAccess*)pDeviceAccss)->m_flag_busy)), true, 1000, false);
+ if (!got_resource)
+ {
+ LOG_MESSAGE_ERROR(_T("Could not get lock for PCI access"));
+ return -1;
+ }
+
+ __TRY
+ {
+ if (((IDeviceAccess*)pDeviceAccss)->GetType() == IDeviceAccess::ETypePCI)
+ res = ((CPciDeviceAccess*)pDeviceAccss)->SetDriverMode(newState, oldState, payloadResult);
+ else
+ res = -1;
+
+ }
+ __EXCEPT(EXCEPTION_ACCESS_VIOLATION == GetExceptionCode())
+ {
+ LOG_MESSAGE_ERROR(_T("got exception on Mode Change"));
+ res = -1;
+ oldState = -1;
+ ((IDeviceAccess*)pDeviceAccss)->m_flag_busy = false;
+ }
+ ((IDeviceAccess*)pDeviceAccss)->m_flag_busy = false;
+ return res;
+}
+
+WLCTPCIACSS_API int WlctAccssGetDriverMode(void* pDeviceAccss, int & oldState){
+ if(pDeviceAccss == NULL){
+ return -1;
+ }
+ int res = 0;
+ int got_resource;
+ // Get Resource
+ got_resource = Util::timedResourceInterLockExchange( &((((IDeviceAccess*)pDeviceAccss)->m_flag_busy)), true, 1000, false);
+ if (!got_resource)
+ {
+ LOG_MESSAGE_ERROR(_T("Could not get lock for PCI access"));
+ return -1;
+ }
+ __TRY
+ {
+ if (((IDeviceAccess*)pDeviceAccss)->GetType() == IDeviceAccess::ETypePCI)
+ res = ((CPciDeviceAccess*)pDeviceAccss)->GetDriverMode(oldState);
+ else
+ res = -1;
+
+ }
+ __EXCEPT(EXCEPTION_ACCESS_VIOLATION == GetExceptionCode())
+ {
+ LOG_MESSAGE_ERROR(_T("got exception on Mode Change"));
+ res = -1;
+ oldState = -1;
+ ((IDeviceAccess*)pDeviceAccss)->m_flag_busy = false;
+ }
+ ((IDeviceAccess*)pDeviceAccss)->m_flag_busy = false;
+ return res;
+}
+#endif //_WINDOWS
+
+WLCTPCIACSS_API int WlctAccssRead(void* pDeviceAccss, DWORD addr, DWORD & val)
+{
+ if (pDeviceAccss == NULL)
+ return -1;
+
+ if (addr == BAUD_RATE_REGISTER)
+ if (((IDeviceAccess*)pDeviceAccss)->GetDeviceStep() == DFT_STEP)
+ {
+ DWORD baud_rate = 350; // expected baud rate value from DFT
+ val = baud_rate;
+ return 0;
+ }
+
+ int res = 0;
+ int got_resource;
+
+ // Get Resource
+ got_resource = Util::timedResourceInterLockExchange( &((((IDeviceAccess*)pDeviceAccss)->m_flag_busy)), true, 1000, false);
+ if (!got_resource)
+ {
+ return res;
+ }
+
+ __TRY
+ {
+ res = accssRead(pDeviceAccss, addr, val);
+ }
+ __EXCEPT(EXCEPTION_ACCESS_VIOLATION == GetExceptionCode())
+ {
+ LOG_MESSAGE_ERROR(_T("got exception"));
+ res = -1;
+ ((IDeviceAccess*)pDeviceAccss)->m_flag_busy = false;
+ }
+
+ ((IDeviceAccess*)pDeviceAccss)->m_flag_busy = false;
+ LOG_MESSAGE_DEBUG(_T("%S [addr 0x%X] [val %d]"), __FUNCTION__, addr, val);
+ return res;
+}
+
+WLCTPCIACSS_API int accssRead(void* pDeviceAccss, DWORD addr, DWORD & val) {
+
+ return ((IDeviceAccess*)pDeviceAccss)->r32(addr, val);
+}
+
+
+WLCTPCIACSS_API int WlctAccssAllocPmc(void* pDeviceAccss, DWORD size, DWORD numOfDescriptors)
+{
+ if (pDeviceAccss == NULL)
+ {
+ LOG_MESSAGE_ERROR(_T("Cannot allocate PMC descriptors - No device access handler"));
+ return -1;
+ }
+
+ // Get Resource
+ int got_resource = Util::timedResourceInterLockExchange( &((((IDeviceAccess*)pDeviceAccss)->m_flag_busy)), true, 1000, false);
+ if (!got_resource)
+ {
+ LOG_MESSAGE_ERROR(_T("Cannot allocated PMC descriptors - Cannot obtain a lock"));
+ return -1;
+ }
+
+ int res = 0;
+ __TRY
+ {
+ res = ((IDeviceAccess*)pDeviceAccss)->alloc_pmc(size, numOfDescriptors);
+ }
+ __EXCEPT(EXCEPTION_ACCESS_VIOLATION == GetExceptionCode())
+ {
+ LOG_MESSAGE_ERROR(_T("Cannot allocated PMC descriptors - Got exception"));
+ res = -1;
+ ((IDeviceAccess*)pDeviceAccss)->m_flag_busy = false;
+ }
+
+ ((IDeviceAccess*)pDeviceAccss)->m_flag_busy = false;
+ LOG_MESSAGE_DEBUG(_T("Allocated PMC descriptors. status: %d"), res);
+ return res;
+}
+
+WLCTPCIACSS_API int SwReset(void* pDeviceAccss)
+{
+ UINT32 bootLoadReady;
+ UINT i, maxIterations;
+ USER_RGF_BL_INFO_VER_0 blInfo;
+
+ DWORD readVal;
+ int res = 0;
+
+ LOG_MESSAGE_INFO(_T("SwReset Initiated..."));
+
+ /* Clear MAC link up */
+ accssSet32(pDeviceAccss, USER_RGF_HP_CTRL, BIT(15));
+ accssSet32(pDeviceAccss, USER_RGF_CLKS_CTL_SW_RST_MASK_0, BIT(6)); /* hpal_perst_from_pad_src_n_mask */
+ accssSet32(pDeviceAccss, USER_RGF_CLKS_CTL_SW_RST_MASK_0, BIT(7)); /* car_perst_rst_src_n_mask */
+
+ /* Halt CPU */
+ accssWrite(pDeviceAccss, USER_RGF_USER_CPU_0, BIT(1));
+ accssWrite(pDeviceAccss, USER_RGF_MAC_CPU_0, BIT(1));
+
+
+ /* clear all boot loader "ready" bits */
+ accssWrite(pDeviceAccss, USER_RGF_BL_READY, 0); //USER_RGF_BL_READY
+
+ /* Clear Fw Download notification */
+ accssClear32(pDeviceAccss, USER_RGF_USAGE_6, BIT(0)); //USER_RGF_USAGE_6)
+
+ // Sparrow only register configuration
+ accssSet32(pDeviceAccss, USER_RGF_CAF_OSC_CONTROL, BIT_CAF_OSC_XTAL_EN); //USER_RGF_CAF_OSC_CONTROL
+
+
+
+ LOG_MESSAGE_INFO(_T("Sleep: waiting for XTAL stabilization..."));
+ /* XTAL stabilization should take about 3ms */
+ sleep_ms(XTAL_STABLE_WAIT_MS);
+ LOG_MESSAGE_INFO(_T("Sleep done: Checking XTAL stabilization..."));
+ res = accssRead(pDeviceAccss, USER_RGF_CAF_PLL_LOCK_STATUS, readVal); //USER_RGF_CAF_PLL_LOCK_STATUS
+
+ if (!(readVal & BIT_CAF_OSC_DIG_XTAL_STABLE)) { //BIT_CAF_OSC_DIG_XTAL_STABLE
+ LOG_MESSAGE_ERROR(_T("%s: BIT_CAF_OSC_DIG_XTAL_STABLE=0x%x\n"), __FUNCTION__, BIT_CAF_OSC_DIG_XTAL_STABLE);
+ LOG_MESSAGE_ERROR(_T("%s: Xtal stabilization timeout USER_RGF_CAF_PLL_LOCK_STATUS val=0x%x\n"), __FUNCTION__, readVal);
+ return -1;
+ }
+
+ /* switch 10k to XTAL*/
+ accssClear32(pDeviceAccss, USER_RGF_SPARROW_M_4, BIT_SPARROW_M_4_SEL_SLEEP_OR_REF); //USER_RGF_SPARROW_M_4
+
+ /* 40 MHz */
+ accssClear32(pDeviceAccss, USER_RGF_CLKS_CTL_0, BIT_USER_CLKS_CAR_AHB_SW_SEL); //USER_RGF_CLKS_CTL_0
+
+
+ accssWrite(pDeviceAccss, USER_RGF_CLKS_CTL_EXT_SW_RST_VEC_0, 0x3ff81f); //USER_RGF_CLKS_CTL_EXT_SW_RST_VEC_0
+ accssWrite(pDeviceAccss, USER_RGF_CLKS_CTL_EXT_SW_RST_VEC_1, 0xf); //USER_RGF_CLKS_CTL_EXT_SW_RST_VEC_1
+
+ accssWrite(pDeviceAccss, USER_RGF_CLKS_CTL_SW_RST_VEC_2, 0xFE000000); //USER_RGF_CLKS_CTL_SW_RST_VEC_2
+ accssWrite(pDeviceAccss, USER_RGF_CLKS_CTL_SW_RST_VEC_1, 0x0000003F); //USER_RGF_CLKS_CTL_SW_RST_VEC_1
+ accssWrite(pDeviceAccss, USER_RGF_CLKS_CTL_SW_RST_VEC_3, 0x000000f0); //USER_RGF_CLKS_CTL_SW_RST_VEC_3
+ accssWrite(pDeviceAccss, USER_RGF_CLKS_CTL_SW_RST_VEC_0, 0xFFE7FC00); //USER_RGF_CLKS_CTL_SW_RST_VEC_0
+
+ /* Sparrow Exit SW Reset */
+ accssWrite(pDeviceAccss, USER_RGF_CLKS_CTL_EXT_SW_RST_VEC_0, 0x0); //USER_RGF_CLKS_CTL_EXT_SW_RST_VEC_0
+ accssWrite(pDeviceAccss, USER_RGF_CLKS_CTL_EXT_SW_RST_VEC_1, 0x0); //USER_RGF_CLKS_CTL_EXT_SW_RST_VEC_1
+
+
+ accssWrite(pDeviceAccss, USER_RGF_CLKS_CTL_SW_RST_VEC_2, 0); //USER_RGF_CLKS_CTL_SW_RST_VEC_2
+ accssWrite(pDeviceAccss, USER_RGF_CLKS_CTL_SW_RST_VEC_1, 0); //USER_RGF_CLKS_CTL_SW_RST_VEC_1
+ accssWrite(pDeviceAccss, USER_RGF_CLKS_CTL_SW_RST_VEC_3, 0); //USER_RGF_CLKS_CTL_SW_RST_VEC_3
+ accssWrite(pDeviceAccss, USER_RGF_CLKS_CTL_SW_RST_VEC_0, 0); //USER_RGF_CLKS_CTL_SW_RST_VEC_0
+
+ accssWrite(pDeviceAccss, USER_RGF_CLKS_CTL_SW_RST_VEC_3, 0x00000003); //USER_RGF_CLKS_CTL_SW_RST_VEC_3
+ /* reset A2 PCIE AHB */
+ accssWrite(pDeviceAccss, USER_RGF_CLKS_CTL_SW_RST_VEC_2, 0x00008000); //USER_RGF_CLKS_CTL_SW_RST_VEC_2
+
+ /* TODO: check order here!!! Erez code is different */
+ accssWrite(pDeviceAccss, USER_RGF_CLKS_CTL_SW_RST_VEC_0, 0x0); //USER_RGF_CLKS_CTL_SW_RST_VEC_0
+
+ // Now wait for device ready, use HW_MACHINE register for this
+ maxIterations = BL_READY_TIMEOUT_MS / BL_READY_WAIT_INTERVAL_MS;
+
+
+ LOG_MESSAGE_INFO(_T("Checking bootloader..."));
+
+ for (i = maxIterations; i; --i)
+ {
+
+ //First wait to let the register have the stabilization time it needs
+ sleep_ms(BL_READY_WAIT_INTERVAL_MS);
+
+ bootLoadReady = accssRead(pDeviceAccss, USER_RGF_BL_READY, readVal); //USER_RGF_BL_READY
+ (void)bootLoadReady;
+
+ if (readVal == BL_BIT_READY)//BL_BIT_READY
+ {
+ break;
+ }
+ }
+
+ LOG_MESSAGE_INFO(_T("Wait on register USER_RGF_BL_READY for %d msec\n"), (maxIterations - i)*BL_READY_WAIT_INTERVAL_MS);
+
+ // check for long wait
+ if (0 == i)
+ {
+ LOG_MESSAGE_ERROR(_T("%s: timeout on register USER_RGF_BL_READY\n"), __FUNCTION__);
+ return -1;
+ }
+
+ // read info from BL
+ hwCopyFromIO(&blInfo, pDeviceAccss, USER_RGF_BL_START_OFFSET, sizeof(USER_RGF_BL_INFO_VER_0));
+
+
+ LOG_MESSAGE_INFO(_T("Boot loader information: Ready=0x%x, StructVersion=0x%x, RfType=0x%x BaseBandType=0x%x\n"),
+ blInfo.Ready, blInfo.StructVersion, blInfo.RfType, blInfo.BaseBandType);
+
+ LOG_MESSAGE_INFO(_T("Boot loader macaddr=%02x:%02x:%02x:%02x:%02x:%02x\n"),
+ blInfo.MacAddr[0], blInfo.MacAddr[1], blInfo.MacAddr[2],
+ blInfo.MacAddr[3], blInfo.MacAddr[4], blInfo.MacAddr[5]);
+
+ accssClear32(pDeviceAccss, USER_RGF_CLKS_CTL_0, BIT_USER_CLKS_RST_PWGD); //USER_RGF_CLKS_CTL_0
+
+
+ if (blInfo.StructVersion > 0)
+ {
+ USER_RGF_BL_INFO_VER_1 blInfoVer1;
+ // print the BL version
+ hwCopyFromIO(&blInfoVer1, pDeviceAccss, USER_RGF_BL_START_OFFSET, sizeof(USER_RGF_BL_INFO_VER_1));
+
+ LOG_MESSAGE_INFO(_T("Boot Loader build %d.%d.%d.%d\n"),
+ blInfoVer1.VersionMajor, blInfoVer1.VersionMinor,
+ blInfoVer1.VersionSubminor, blInfoVer1.VersionBuild);
+ }
+
+ LOG_MESSAGE_INFO(_T("SwReset Done..."));
+
+ return res;
+}
+
+WLCTPCIACSS_API int InterfaceReset(void* pDeviceAccss)
+{
+ if (pDeviceAccss == NULL)
+ return -1;
+
+ int res = 0;
+ int got_resource;
+
+ // Get Resource
+ got_resource = Util::timedResourceInterLockExchange( &((((IDeviceAccess*)pDeviceAccss)->m_flag_busy)), true, 1000, false);
+ if (!got_resource)
+ {
+ return res;
+ }
+
+ __TRY
+ {
+ res = ((IDeviceAccess*)pDeviceAccss)->do_interface_reset();
+ }
+ __EXCEPT(EXCEPTION_ACCESS_VIOLATION == GetExceptionCode())
+ {
+ LOG_MESSAGE_ERROR(_T("got exception"));
+ res = -1;
+ ((IDeviceAccess*)pDeviceAccss)->m_flag_busy = false;
+ }
+
+ ((IDeviceAccess*)pDeviceAccss)->m_flag_busy = false;
+ LOG_MESSAGE_DEBUG(_T("Interface Reset flow end"));
+ return res;
+}
+
+/* helper function copied and modified from the driver
+ we can use this to read info from the boot loader
+*/
+WLCTPCIACSS_API void hwCopyFromIO( void* dst, void* pDeviceAccss, DWORD src, UINT32 len)
+{
+ UINT32 i, regCount;
+ DWORD readVal;
+
+ regCount = (UINT64)(ALIGN_UP_BY(len, 4)) / 4;
+
+ for (i = 0; i < regCount; ++i)
+ {
+ //*((PUINT32)dst + i) = READ32((PUINT32)src + i);
+ int res = ((IDeviceAccess*)pDeviceAccss)->r32(src + i, readVal);
+ (void)res;
+ *((PUINT32)dst + i) = readVal;
+ }
+}
+
+WLCTPCIACSS_API int WlctAccssWrite(void* pDeviceAccss, DWORD addr, DWORD val)
+{
+ int res = 0;
+ int got_resource;
+
+ if (pDeviceAccss == NULL)
+ return -1;
+
+ // Get Resource
+ got_resource = Util::timedResourceInterLockExchange( &((((IDeviceAccess*)pDeviceAccss)->m_flag_busy)), true, 1000, false);
+ if (!got_resource)
+ {
+ return -1;
+ }
+
+ __TRY
+ {
+ res = accssWrite(pDeviceAccss,addr,val);
+ }
+ __EXCEPT(EXCEPTION_ACCESS_VIOLATION == GetExceptionCode())
+ {
+ LOG_MESSAGE_ERROR(_T("got exception"));
+ res = -1;
+ ((IDeviceAccess*)pDeviceAccss)->m_flag_busy = false;
+ }
+
+ ((IDeviceAccess*)pDeviceAccss)->m_flag_busy = false;
+ LOG_MESSAGE_DEBUG(_T("%S [addr 0x%X] [val %d]"), __FUNCTION__, addr, val);
+ return res;
+}
+
+WLCTPCIACSS_API int accssWrite(void* pDeviceAccss, DWORD addr, DWORD val)
+{
+
+ return ((IDeviceAccess*)pDeviceAccss)->w32((addr), val);
+
+}
+
+/* accssSet32 is a modifiled write function based on logic from the driver
+ First read from the addr
+ Set the readVal to the desired val with |= val
+ Write readVal back into addr
+*/
+WLCTPCIACSS_API int accssSet32(void* pDeviceAccss, DWORD addr, DWORD val) {
+ int res = 0;
+ DWORD readVal;
+
+ res = accssRead(pDeviceAccss, addr, readVal);
+ readVal |= val;
+ res = accssWrite(pDeviceAccss, addr, readVal);
+
+ return res;
+}
+
+/* accssClear32 is a modifiled write function based on logic from the driver
+ First read from the addr
+ Clear the readVal to the desired val with &= ~val
+ Write readVal back into addr
+*/
+WLCTPCIACSS_API int accssClear32(void* pDeviceAccss, DWORD addr, DWORD val) {
+ int res = 0;
+ DWORD readVal;
+
+ res = accssRead(pDeviceAccss, addr, readVal);
+ readVal &= ~val;
+ res = accssWrite(pDeviceAccss, addr, readVal);
+
+ return res;
+}
+
+WLCTPCIACSS_API bool isInit(void* pDeviceAccss)
+{
+ if (pDeviceAccss == NULL)
+ return false;
+
+ bool res = 0;
+ __TRY
+ {
+ res = ((IDeviceAccess*)pDeviceAccss)->isInitialized();
+ }
+ __EXCEPT(EXCEPTION_ACCESS_VIOLATION == GetExceptionCode())
+ {
+ LOG_MESSAGE_ERROR(_T("got exception"));
+ res = false;
+ }
+ return res;
+}
+
+WLCTPCIACSS_API int writeBlock(void* pDeviceAccss, DWORD addr, DWORD blockSize, const char *arrBlock)
+{
+ int got_resource;
+
+ if (pDeviceAccss == NULL)
+ return -1;
+
+ // Get Resource
+ got_resource = Util::timedResourceInterLockExchange( &((((IDeviceAccess*)pDeviceAccss)->m_flag_busy)), true, 1000, false);
+ if (!got_resource)
+ {
+ return -1;
+ }
+
+
+ int res = 0;
+ __TRY
+ {
+ LOG_MESSAGE_DEBUG(_T("start running"));
+ res = ((IDeviceAccess*)pDeviceAccss)->wb(addr, blockSize, arrBlock);
+ LOG_MESSAGE_DEBUG(_T("Leaving"));
+ }
+ __EXCEPT(EXCEPTION_ACCESS_VIOLATION == GetExceptionCode())
+ {
+ LOG_MESSAGE_ERROR(_T("got exception"));
+ res = -1;
+ ((IDeviceAccess*)pDeviceAccss)->m_flag_busy = false;
+ }
+
+ ((IDeviceAccess*)pDeviceAccss)->m_flag_busy = false;
+ return res;
+}
+
+WLCTPCIACSS_API int readBlock(void* pDeviceAccss, DWORD addr, DWORD blockSize, char *arrBlock)
+{
+ int got_resource;
+
+ if (pDeviceAccss == NULL)
+ return -1;
+
+ // Get Resource
+ got_resource = Util::timedResourceInterLockExchange( &((((IDeviceAccess*)pDeviceAccss)->m_flag_busy)), true, 1000, false);
+ if (!got_resource)
+ {
+ return -1;
+ }
+
+
+ int res = 0;
+ __TRY
+ {
+
+ LOG_MESSAGE_DEBUG(_T("start running"));
+
+ res = ((IDeviceAccess*)pDeviceAccss)->rb(addr, blockSize, arrBlock);
+ LOG_MESSAGE_DEBUG(_T("Leaving"));
+ }
+ __EXCEPT(EXCEPTION_ACCESS_VIOLATION == GetExceptionCode())
+ {
+ LOG_MESSAGE_ERROR(_T("got exception"));
+ res = -1;
+ ((IDeviceAccess*)pDeviceAccss)->m_flag_busy = false;
+ }
+
+ ((IDeviceAccess*)pDeviceAccss)->m_flag_busy = false;
+ return res;
+}
+
+//
+// read repeat - will read from the same address num_repeat times
+// the result will store in arrBlock. arrBlock is an array of shorts with at least num_repeat entries.
+//
+WLCTPCIACSS_API int readRepeat(void* pDeviceAccss, DWORD addr, DWORD num_repeat, DWORD *arrBlock)
+{
+ int got_resource;
+
+ if (pDeviceAccss == NULL)
+ return -1;
+
+ // Get Resource
+ got_resource = Util::timedResourceInterLockExchange( &((((IDeviceAccess*)pDeviceAccss)->m_flag_busy)), true, 1000, false);
+ if (!got_resource)
+ {
+ return -1;
+ }
+
+
+ int res = 0;
+ __TRY
+ {
+ LOG_MESSAGE_DEBUG(_T("start running"));
+ res = ((IDeviceAccess*)pDeviceAccss)->rr(addr, USHORT(num_repeat), arrBlock);
+ LOG_MESSAGE_DEBUG(_T("Leaving"));
+ }
+ __EXCEPT(EXCEPTION_ACCESS_VIOLATION == GetExceptionCode())
+ {
+ LOG_MESSAGE_ERROR(_T("got exception"));
+ res = -1;
+ ((IDeviceAccess*)pDeviceAccss)->m_flag_busy = false;
+ }
+
+ ((IDeviceAccess*)pDeviceAccss)->m_flag_busy = false;
+ return res;
+}
+
+WLCTPCIACSS_API DType getDeviceType(void* pDeviceAccss)
+{
+ return ((IDeviceAccess*)pDeviceAccss)->GetDeviceType();
+}
+
+WLCTPCIACSS_API int getDbgMsg(void* pDeviceAccss, FW_DBG_MSG** pMsg)
+{
+ if (pDeviceAccss == NULL)
+ return -1;
+
+ int res = 0;
+ __TRY
+ {
+ res = ((IDeviceAccess*)pDeviceAccss)->getFwDbgMsg(pMsg);
+ }
+ __EXCEPT(EXCEPTION_ACCESS_VIOLATION == GetExceptionCode())
+ {
+ LOG_MESSAGE_ERROR(_T("got exception"));
+ res = -1;
+ }
+ return res;
+}
+
+WLCTPCIACSS_API int clearAllFwDbgMsg(void* pDeviceAccss)
+{
+ if (pDeviceAccss == NULL)
+ return -1;
+
+ int res = 0;
+ __TRY
+ {
+ ((IDeviceAccess*)pDeviceAccss)->clearAllFwDbgMsg();
+ }
+ __EXCEPT(EXCEPTION_ACCESS_VIOLATION == GetExceptionCode())
+ {
+ LOG_MESSAGE_ERROR(_T("got exception"));
+ res = -1;
+ }
+ return res;
+}
+
+WLCTPCIACSS_API int card_reset(void* pDeviceAccss)
+{
+ if (pDeviceAccss == NULL)
+ return -1;
+
+ int res = 0;
+ __TRY
+ {
+ ((IDeviceAccess*)pDeviceAccss)->do_reset();
+ }
+ __EXCEPT(EXCEPTION_ACCESS_VIOLATION == GetExceptionCode())
+ {
+ LOG_MESSAGE_ERROR(_T("got exception"));
+ res = -1;
+ }
+ return res;
+}
+
+WLCTPCIACSS_API int startSampling(void* pDeviceAccss, DWORD* pRegsArr, DWORD regArrSize, DWORD interval, DWORD maxSampling, DWORD transferMethod)
+{
+ if (pDeviceAccss == NULL)
+ return -1;
+
+ int res = 0;
+ __TRY
+ {
+ ((IDeviceAccess*)pDeviceAccss)->startSampling(pRegsArr, regArrSize, interval, maxSampling, transferMethod);
+ }
+ __EXCEPT(EXCEPTION_ACCESS_VIOLATION == GetExceptionCode())
+ {
+ LOG_MESSAGE_ERROR(_T("got exception"));
+ res = -1;
+ }
+ return res;
+}
+
+WLCTPCIACSS_API int stopSampling(void* pDeviceAccss)
+{
+ if (pDeviceAccss == NULL)
+ return -1;
+
+ int res = 0;
+ __TRY
+ {
+ ((IDeviceAccess*)pDeviceAccss)->stopSampling();
+ }
+ __EXCEPT(EXCEPTION_ACCESS_VIOLATION == GetExceptionCode())
+ {
+ LOG_MESSAGE_ERROR(_T("got exception"));
+ res = -1;
+ }
+ return res;
+}
+
+WLCTPCIACSS_API int getSamplingData(void* pDeviceAccss, DWORD** pDataSamples)
+{
+ if (pDeviceAccss == NULL)
+ return -1;
+
+ int res = 0;
+ __TRY
+ {
+ res = ((IDeviceAccess*)pDeviceAccss)->getSamplingData(pDataSamples);
+ }
+ __EXCEPT(EXCEPTION_ACCESS_VIOLATION == GetExceptionCode())
+ {
+ LOG_MESSAGE_ERROR(_T("got exception"));
+ res = -1;
+ }
+ return res;
+}
+
+WLCTPCIACSS_API TCHAR* getInterfaceName(void* pDeviceAccss)
+{
+ if (pDeviceAccss == NULL)
+ return NULL;
+
+ TCHAR* szInfName = NULL;
+ __TRY
+ {
+ szInfName = ((IDeviceAccess*)pDeviceAccss)->GetInterfaceName();
+ }
+ __EXCEPT(EXCEPTION_ACCESS_VIOLATION == GetExceptionCode())
+ {
+ LOG_MESSAGE_ERROR(_T("got exception"));
+ }
+ return szInfName;
+}
+
+#ifdef _WINDOWS
+#ifndef NO_JTAG
+WLCTPCIACSS_API int WlctAccssJtagSendDR(void* pDeviceAccss, DWORD num_bits, BYTE *arr_in, BYTE *arr_out)
+{
+ if (pDeviceAccss == NULL)
+ return -1;
+
+ int res = 0;
+ int got_resource;
+
+ // Get Resource
+ got_resource = Util::timedResourceInterLockExchange( &((((IDeviceAccess*)pDeviceAccss)->m_flag_busy)), true, 1000, false);
+ if (!got_resource)
+ {
+ return res;
+ }
+
+ __TRY
+ {
+ if (isInit(pDeviceAccss))
+ {
+ if (((IDeviceAccess*)pDeviceAccss)->GetType() == IDeviceAccess::ETypeJTAG)
+ {
+ if (((IDeviceAccess*)pDeviceAccss)->GetDeviceType() == MST_MARLON)
+ {
+ res = ((CJtagDeviceAccess*)pDeviceAccss)->jtag_set_dr(arr_in, arr_out, num_bits);
+ }
+ }
+ }
+ }
+ __EXCEPT(EXCEPTION_ACCESS_VIOLATION == GetExceptionCode())
+ {
+ LOG_MESSAGE_ERROR(_T("got exception"));
+ res = -1;
+ ((IDeviceAccess*)pDeviceAccss)->m_flag_busy = false;
+ }
+
+ ((IDeviceAccess*)pDeviceAccss)->m_flag_busy = false;
+ // LOG_MESSAGE_DEBUG(_T("%S [addr 0x%X] [val %d]"), __FUNCTION__, addr, val);
+ return res;
+}
+
+WLCTPCIACSS_API int WlctAccssJtagSendIR(void* pDeviceAccss, DWORD num_bits, BYTE *arr_in)
+{
+ if (pDeviceAccss == NULL)
+ return -1;
+
+ int res = 0;
+ int got_resource;
+
+ // Get Resource
+ got_resource = Util::timedResourceInterLockExchange( &((((IDeviceAccess*)pDeviceAccss)->m_flag_busy)), true, 1000, false);
+ if (!got_resource)
+ {
+ return res;
+ }
+
+ __TRY
+ {
+ if (isInit(pDeviceAccss))
+ {
+ if (((IDeviceAccess*)pDeviceAccss)->GetType() == IDeviceAccess::ETypeJTAG)
+ {
+ if (((IDeviceAccess*)pDeviceAccss)->GetDeviceType() == MST_MARLON)
+ {
+ res = ((CJtagDeviceAccess*)pDeviceAccss)->jtag_set_ir(num_bits, arr_in);
+ }
+ }
+ }
+ }
+ __EXCEPT(EXCEPTION_ACCESS_VIOLATION == GetExceptionCode())
+ {
+ LOG_MESSAGE_ERROR(_T("got exception"));
+ res = -1;
+ ((IDeviceAccess*)pDeviceAccss)->m_flag_busy = false;
+ }
+
+ ((IDeviceAccess*)pDeviceAccss)->m_flag_busy = false;
+// LOG_MESSAGE_DEBUG(_T("%S [addr 0x%X] [val %d]"), __FUNCTION__, addr, val);
+ return res;
+}
+
+WLCTPCIACSS_API int JtagSetClockSpeed(void* pDeviceAccss, DWORD requestedFreq, DWORD* frqSet)
+{
+ if (pDeviceAccss == NULL)
+ return -1;
+
+ int res = 0;
+ __TRY
+ {
+ ((CJtagDeviceAccess*)pDeviceAccss)->set_speed(requestedFreq, frqSet);
+ }
+ __EXCEPT(EXCEPTION_ACCESS_VIOLATION == GetExceptionCode())
+ {
+ LOG_MESSAGE_ERROR(_T("got exception"));
+ res = -1;
+ }
+ return res;
+}
+
+WLCTPCIACSS_API int JtagPutTmsTdiBits(void* pDeviceAccss, BYTE *tms, BYTE *tdi, BYTE* tdo, UINT length)
+{
+ if (pDeviceAccss == NULL)
+ return -1;
+
+ int res = 0;
+ __TRY
+ {
+ ((CJtagDeviceAccess*)pDeviceAccss)->direct_control(tms, tdi, tdo, length);
+ }
+ __EXCEPT(EXCEPTION_ACCESS_VIOLATION == GetExceptionCode())
+ {
+ LOG_MESSAGE_ERROR(_T("got exception"));
+ res = -1;
+ }
+ return res;
+}
+
+WLCTPCIACSS_API int JtagTmsShiftToReset(void* pDeviceAccss)
+{
+ if (pDeviceAccss == NULL)
+ return -1;
+
+ int res = 0;
+ int got_resource;
+
+ // Get Resource
+ got_resource = Util::timedResourceInterLockExchange( &((((IDeviceAccess*)pDeviceAccss)->m_flag_busy)), true, 1000, false);
+ if (!got_resource)
+ {
+ return res;
+ }
+
+ __TRY
+ {
+ if (isInit(pDeviceAccss))
+ {
+ if (((IDeviceAccess*)pDeviceAccss)->GetType() == IDeviceAccess::ETypeJTAG)
+ {
+ if (((IDeviceAccess*)pDeviceAccss)->GetDeviceType() == MST_MARLON)
+ {
+ res = ((CJtagDeviceAccess*)pDeviceAccss)->jtag_reset();
+ }
+
+ if (((IDeviceAccess*)pDeviceAccss)->GetDeviceType() == MST_SPARROW)
+ {
+ res = ((CJtagDeviceAccess*)pDeviceAccss)->jtag_reset();
+ }
+ }
+ }
+ }
+ __EXCEPT(EXCEPTION_ACCESS_VIOLATION == GetExceptionCode())
+ {
+ LOG_MESSAGE_ERROR(_T("got exception"));
+ res = -1;
+ ((IDeviceAccess*)pDeviceAccss)->m_flag_busy = false;
+ }
+
+ ((IDeviceAccess*)pDeviceAccss)->m_flag_busy = false;
+ // LOG_MESSAGE_DEBUG(_T("%S [addr 0x%X] [val %d]"), __FUNCTION__, addr, val);
+ return res;
+}
+#else // JTAG
+
+WLCTPCIACSS_API int JtagSetClockSpeed(void* pDeviceAccss, DWORD requestedFreq, DWORD* frqSet)
+{
+ return -1;
+}
+
+WLCTPCIACSS_API int JtagPutTmsTdiBits(void* pDeviceAccss, BYTE *tms, BYTE *tdi, BYTE* tdo, UINT length)
+{
+ return -1;
+}
+
+WLCTPCIACSS_API int JtagTmsShiftToReset(void* pDeviceAccss)
+{
+ return -1;
+}
+
+#endif // ifndef NO_JTAG
+#endif /* _WINDOWS */
+
+#ifdef _WINDOWS
+WLCTPCIACSS_API int WlctAccssSendWmiCmd(void* pDeviceAccss, SEND_RECEIVE_WMI* wmi)
+{
+ LOG_MESSAGE_INFO(_T("WlctAccssSendWmiCmd: 0x%X"), (*wmi).uCmdId);
+
+ if (pDeviceAccss == NULL)
+ return -1;
+
+ int res = 0;
+ int got_resource;
+
+ // Get Resource
+ got_resource = Util::timedResourceInterLockExchange( &((((IDeviceAccess*)pDeviceAccss)->m_flag_busy)), true, 1000, false);
+ if (!got_resource)
+ {
+ return res;
+ }
+
+ __TRY
+ {
+ if (((IDeviceAccess*)pDeviceAccss)->GetType() == IDeviceAccess::ETypePCI)
+ res = ((CPciDeviceAccess*)pDeviceAccss)->send_wmi_cmd(wmi);
+ else
+ res = -1;
+ }
+ __EXCEPT(EXCEPTION_ACCESS_VIOLATION == GetExceptionCode())
+ {
+ LOG_MESSAGE_ERROR(_T("got exception"));
+ res = -1;
+ ((IDeviceAccess*)pDeviceAccss)->m_flag_busy = false;
+ }
+
+ ((IDeviceAccess*)pDeviceAccss)->m_flag_busy = false;
+ return res;
+}
+
+WLCTPCIACSS_API int WlctAccssRecieveWmiEvent(void* pDeviceAccss, SEND_RECEIVE_WMI* evt)
+{
+ LOG_MESSAGE_INFO(_T("WlctAccssRecieveWmiEvent"));
+
+ if (pDeviceAccss == NULL)
+ return -1;
+
+ int res = 0;
+ int got_resource;
+
+ // Get Resource
+ got_resource = Util::timedResourceInterLockExchange( &((((IDeviceAccess*)pDeviceAccss)->m_flag_busy)), true, 1000, false);
+ if (!got_resource)
+ {
+ return res;
+ }
+
+ __TRY
+ {
+ if (((IDeviceAccess*)pDeviceAccss)->GetType() == IDeviceAccess::ETypePCI)
+ res = ((CPciDeviceAccess*)pDeviceAccss)->recieve_wmi_event(evt);
+ else
+ res = -1;
+ }
+ __EXCEPT(EXCEPTION_ACCESS_VIOLATION == GetExceptionCode())
+ {
+ LOG_MESSAGE_ERROR(_T("got exception"));
+ res = -1;
+ ((IDeviceAccess*)pDeviceAccss)->m_flag_busy = false;
+ }
+
+ ((IDeviceAccess*)pDeviceAccss)->m_flag_busy = false;
+ return res;
+}
+
+WLCTPCIACSS_API int WlctAccssMpSetDriverLogLevels(void* pDeviceAccss, ULONG logModulesEnableMsk, ULONG logModuleLevelsMsk[WILO_DRV_NUM_LOG_COMPS])
+{
+ LOG_MESSAGE_INFO(_T("WlctAccssMpDriverLogLevels"));
+
+ if (pDeviceAccss == NULL)
+ return -1;
+
+ int res = 0;
+ int got_resource;
+
+ // Get Resource
+ got_resource = Util::timedResourceInterLockExchange( &((((IDeviceAccess*)pDeviceAccss)->m_flag_busy)), true, 1000, false);
+ if (!got_resource)
+ {
+ return res;
+ }
+
+ __TRY
+ {
+ if (((IDeviceAccess*)pDeviceAccss)->GetType() == IDeviceAccess::ETypePCI)
+ res = ((CPciDeviceAccess*)pDeviceAccss)->setMpDriverLogLevels(logModulesEnableMsk, logModuleLevelsMsk);
+ else
+ res = -1;
+ }
+ __EXCEPT(EXCEPTION_ACCESS_VIOLATION == GetExceptionCode())
+ {
+ LOG_MESSAGE_ERROR(_T("got exception"));
+ res = -1;
+ ((IDeviceAccess*)pDeviceAccss)->m_flag_busy = false;
+ }
+
+ ((IDeviceAccess*)pDeviceAccss)->m_flag_busy = false;
+ return res;
+}
+
+#endif
+
+WLCTPCIACSS_API int WlctAccssRegisterDriverMailboxEvents(void* pDeviceAccss, HANDLE* pMailboxEventHandle )
+{
+ LOG_MESSAGE_INFO(_T("WlctAccssRegisterDriverMailboxEvents"));
+
+ if (pDeviceAccss == NULL)
+ return -1;
+
+ int res = 0;
+ int got_resource;
+
+ // Get Resource
+ got_resource = Util::timedResourceInterLockExchange( &((((IDeviceAccess*)pDeviceAccss)->m_flag_busy)), true, 1000, false);
+ if (!got_resource)
+ {
+ return res;
+ }
+
+ __TRY
+ {
+ if (((IDeviceAccess*)pDeviceAccss)->GetType() == IDeviceAccess::ETypePCI)
+ res = ((CPciDeviceAccess*)pDeviceAccss)->register_driver_mailbox_event(pMailboxEventHandle);
+ else
+ res = -1;
+ }
+ __EXCEPT(EXCEPTION_ACCESS_VIOLATION == GetExceptionCode())
+ {
+ LOG_MESSAGE_ERROR(_T("got exception"));
+ res = -1;
+ ((IDeviceAccess*)pDeviceAccss)->m_flag_busy = false;
+ }
+
+ ((IDeviceAccess*)pDeviceAccss)->m_flag_busy = false;
+ return res;
+}
+
+
+
+WLCTPCIACSS_API int WlctAccssRegisterDriverDeviceEvents(void* pDeviceAccss, INT_PTR hDnEvent, INT_PTR hUpEvent, INT_PTR hUnplugEvent, INT_PTR hSysAssertEvent )
+{
+ LOG_MESSAGE_INFO(_T("WlctAccssRegisterDriverDeviceEvents"));
+
+ if (pDeviceAccss == NULL)
+ return -1;
+
+ int res = 0;
+ int got_resource;
+
+ // Get Resource
+ got_resource = Util::timedResourceInterLockExchange( &((((IDeviceAccess*)pDeviceAccss)->m_flag_busy)), true, 1000, false);
+ if (!got_resource)
+ {
+ return res;
+ }
+
+ __TRY
+ {
+ if (((IDeviceAccess*)pDeviceAccss)->GetType() == IDeviceAccess::ETypePCI)
+ res = ((CPciDeviceAccess*)pDeviceAccss)->register_driver_device_events (hDnEvent, hUpEvent, hUnplugEvent, hSysAssertEvent);
+ else
+ res = -1;
+ }
+ __EXCEPT(EXCEPTION_ACCESS_VIOLATION == GetExceptionCode())
+ {
+ LOG_MESSAGE_ERROR(_T("got exception"));
+ res = -1;
+ ((IDeviceAccess*)pDeviceAccss)->m_flag_busy = false;
+ }
+
+ ((IDeviceAccess*)pDeviceAccss)->m_flag_busy = false;
+ return res;
+}
+
+WLCTPCIACSS_API int WlctAccssUnregisterDriverDeviceEvents(void* pDeviceAccss){
+ LOG_MESSAGE_INFO(_T("WlctAccssUnregisterDriverDeviceEvents"));
+
+ if (pDeviceAccss == NULL)
+ return -1;
+
+ int res = 0;
+ int got_resource;
+
+ // Get Resource
+ got_resource = Util::timedResourceInterLockExchange( &((((IDeviceAccess*)pDeviceAccss)->m_flag_busy)), true, 1000, false);
+ if (!got_resource)
+ {
+ return res;
+ }
+
+ __TRY
+ {
+ if (((IDeviceAccess*)pDeviceAccss)->GetType() == IDeviceAccess::ETypePCI)
+ res = ((CPciDeviceAccess*)pDeviceAccss)->unregister_driver_device_events();
+ else
+ res = -1;
+ }
+ __EXCEPT(EXCEPTION_ACCESS_VIOLATION == GetExceptionCode())
+ {
+ LOG_MESSAGE_ERROR(_T("got exception"));
+ res = -1;
+ ((IDeviceAccess*)pDeviceAccss)->m_flag_busy = false;
+ }
+
+ ((IDeviceAccess*)pDeviceAccss)->m_flag_busy = false;
+ return res;
+}
+WLCTPCIACSS_API int WlctAccssRegisterDriverEvent(void* pDeviceAccss, INT_PTR event_ptr, int eventId, int appId)
+{
+ LOG_MESSAGE_INFO(_T("WlctAccssRegisterDriverDeviceEvent"));
+
+ if (pDeviceAccss == NULL)
+ return -1;
+
+ int res = 0;
+ int got_resource;
+
+ // Get Resource
+ got_resource = Util::timedResourceInterLockExchange( &((((IDeviceAccess*)pDeviceAccss)->m_flag_busy)), true, 1000, false);
+ if (!got_resource)
+ {
+ return res;
+ }
+
+ __TRY
+ {
+ if (((IDeviceAccess*)pDeviceAccss)->GetType() == IDeviceAccess::ETypePCI)
+ res = ((CPciDeviceAccess*)pDeviceAccss)->register_driver_device_event (event_ptr, appId, eventId);
+ else
+ res = -1;
+ }
+ __EXCEPT(EXCEPTION_ACCESS_VIOLATION == GetExceptionCode())
+ {
+ LOG_MESSAGE_ERROR(_T("got exception"));
+ res = -1;
+ ((IDeviceAccess*)pDeviceAccss)->m_flag_busy = false;
+ }
+
+ ((IDeviceAccess*)pDeviceAccss)->m_flag_busy = false;
+ return res;
+
+}
+
+
+WLCTPCIACSS_API int WlctAccssRegisterDeviceForUnplug2Event(void* pDeviceAccss, INT_PTR event_ptr)
+{
+
+ LOG_MESSAGE_INFO(_T("WlctAccssRegisterDeviceForUnplug2Event"));
+
+ if (pDeviceAccss == NULL)
+ return -1;
+
+ int res = 0;
+ int got_resource;
+
+ // Get Resource
+ got_resource = Util::timedResourceInterLockExchange( &((((IDeviceAccess*)pDeviceAccss)->m_flag_busy)), true, 1000, false);
+ if (!got_resource)
+ {
+ return res;
+ }
+
+ __TRY
+ {
+ res = ((CPciDeviceAccess*)pDeviceAccss)->register_device_unplug2 (event_ptr);
+ }
+ __EXCEPT(EXCEPTION_ACCESS_VIOLATION == GetExceptionCode())
+ {
+ LOG_MESSAGE_ERROR(_T("got exception"));
+ res = -1;
+ ((IDeviceAccess*)pDeviceAccss)->m_flag_busy = false;
+ }
+
+ ((IDeviceAccess*)pDeviceAccss)->m_flag_busy = false;
+ return res;
+}
+
+WLCTPCIACSS_API int WlctAccssUnregisterDeviceForUnplug2Event(void* pDeviceAccss)
+{
+
+ LOG_MESSAGE_INFO(_T("WlctAccssUnregisterDeviceForUnplug2Event"));
+
+ if (pDeviceAccss == NULL)
+ return -1;
+
+ int res = 0;
+ int got_resource;
+
+ // Get Resource
+ got_resource = Util::timedResourceInterLockExchange( &((((IDeviceAccess*)pDeviceAccss)->m_flag_busy)), true, 1000, false);
+ if (!got_resource)
+ {
+ return res;
+ }
+
+ __TRY
+ {
+ res = ((CPciDeviceAccess*)pDeviceAccss)->unregister_device_unplug2 ();
+ }
+ __EXCEPT(EXCEPTION_ACCESS_VIOLATION == GetExceptionCode())
+ {
+ LOG_MESSAGE_ERROR(_T("got exception"));
+ res = -1;
+ ((IDeviceAccess*)pDeviceAccss)->m_flag_busy = false;
+ }
+
+ ((IDeviceAccess*)pDeviceAccss)->m_flag_busy = false;
+ return res;
+}
+
diff --git a/debug-tools/lib/WlctPciAcss/WlctPciAcss.h b/debug-tools/lib/WlctPciAcss/WlctPciAcss.h
new file mode 100644
index 0000000..f25467a
--- /dev/null
+++ b/debug-tools/lib/WlctPciAcss/WlctPciAcss.h
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <list>
+#include <queue>
+#include "wlct_os.h"
+#include "WlctPciAcssWmi.h"
+#include "public.h"
+
+#ifdef _WINDOWS
+#include "ioctl_if.h"
+typedef struct _FW_DBG_MSG
+{
+ std::string msg;
+ SYSTEMTIME timeStamp;
+}FW_DBG_MSG;
+#else
+#define FW_DBG_MSG int
+#endif
+
+typedef struct _SAMPLING_REGS
+{
+ DWORD timeStamp; // GetTickCount
+ DWORD regArr[0];
+}SAMPLING_REGS;
+
+#define MAX_DEVICE_TYPE_SUPPORTED 2
+typedef enum DType_t
+{
+ MST_NONE,
+ MST_SPARROW, // added here to keep backward compatibility. some tools assume MARLON == 2, we don't brake this assumption
+ MST_MARLON,
+ MST_TALYN,
+ MST_LAST
+} DType;
+
+typedef enum DEVICE_STEP_t
+{
+ STEP_NONE,
+ MARLON_STEP_A0,
+ MARLON_STEP_B0,
+ SPARROW_STEP_A0,
+ SPARROW_STEP_A1,
+ SPARROW_STEP_B0,
+ DFT_STEP,
+ STEP_LAST
+} DEVICE_STEP;
+
+#define BAUD_RATE_REGISTER 0x880050
+
+#define MAX_IF_NAME_LENGTH 32
+typedef struct _INTERFACE_NAME
+{
+ char ifName[MAX_IF_NAME_LENGTH];
+}INTERFACE_NAME;
+
+
+#define MAX_INTERFACES 32
+typedef struct _INTERFACE_LIST
+{
+ INTERFACE_NAME list[MAX_INTERFACES];
+}INTERFACE_LIST;
+
+typedef struct _WLCT_DLL_VERSION
+{
+ int major;
+ int minor;
+ int maintenance;
+ int build;
+
+}WLCT_DLL_VERSION;
+
+// The following ifdef block is the standard way of creating macros which make exporting
+// from a DLL simpler. All files within this DLL are compiled with the WLCTPCIACSS_EXPORTS
+// symbol defined on the command line. this symbol should not be defined on any project
+// that uses this DLL. This way any other project whose source files include this file see
+// WLCTPCIACSS_API functions as being imported from a DLL, whereas this DLL sees symbols
+// defined with this macro as being exported.
+
+#ifdef _WINDOWS
+#ifdef WLCTPCIACSS_EXPORTS
+#define WLCTPCIACSS_API __declspec(dllexport)
+#else
+#define WLCTPCIACSS_API __declspec(dllimport)
+#endif
+#endif
+
+#if defined(__GNUC__)
+#if defined(__i386)
+#define WLCTPCIACSS_API extern "C" __attribute__((cdecl))
+#else
+#define WLCTPCIACSS_API extern "C"
+#endif
+#endif
+
+// These are needed for wlanapi.h for pre-vista targets
+
+typedef UCHAR DOT11_MAC_ADDRESS[6];
+typedef DOT11_MAC_ADDRESS * PDOT11_MAC_ADDRESS;
+
+typedef struct
+{
+ UINT32 Ready;
+ UINT32 StructVersion;
+ UINT32 RfType;
+ UINT32 BaseBandType;
+ DOT11_MAC_ADDRESS MacAddr;
+ UINT8 Padding[2];
+}USER_RGF_BL_INFO_VER_0;
+
+typedef struct
+{
+ UINT32 Ready;
+ UINT32 StructVersion;
+ UINT32 RfType;
+ UINT32 BaseBandType;
+ DOT11_MAC_ADDRESS MacAddr;
+ UINT8 VersionMajor; // 0x880A52 BL ver. major
+ UINT8 VersionMinor; // 0x880A53 BL ver. minor
+ UINT16 VersionSubminor; // 0x880A54 BL ver. subminor
+ UINT16 VersionBuild; // 0x880A56 BL ver. build
+ // valid only for version 2 and above
+ UINT16 AssertCode; // 0x880A58 BL Assert code
+ UINT16 AssertBlink; // 0x880A5C BL Assert Branch
+ UINT16 Reserved[22]; // 0x880A60 - 0x880AB4
+ UINT16 MagicNumber; // 0x880AB8 BL Magic number
+}USER_RGF_BL_INFO_VER_1;
+
+#define BIT(x) (1 << (x))
+
+// Register definitions - taken from the REG files. addresses are from FW point of view
+#define USER_RGF_USAGE_6 0x880018
+
+// Boot loader registers
+#define USER_RGF_BL_START_OFFSET 0x880A3C
+#define USER_RGF_BL_READY USER_RGF_BL_START_OFFSET
+#define BL_BIT_READY BIT(0)
+
+// reset sequence related
+#define USER_RGF_HP_CTRL 0x88265c
+#define USER_RGF_FW_DEDICATED_REG_REV_ID 0x880a8c
+#define PCIE_RGF_MAC_HW_ID_DB1 0x1
+#define PCIE_RGF_MAC_HW_ID_DB2 0x2
+#define USER_RGF_CLKS_CTL_SW_RST_MASK_0 0x880b14
+#define USER_RGF_MAC_CPU_0 0x8801fc
+#define USER_RGF_USER_CPU_0 0x8801e0
+#define USER_RGF_CLKS_CTL_SW_RST_VEC_0 0x880b04
+#define USER_RGF_CLKS_CTL_SW_RST_VEC_1 0x880b08
+#define USER_RGF_CLKS_CTL_SW_RST_VEC_2 0x880b0c
+#define USER_RGF_CLKS_CTL_SW_RST_VEC_3 0x880b10
+#define USER_RGF_LOS_COUNTER_CTL 0x882dc4
+#define USER_RGF_SERIAL_BAUD_RATE 0x880050
+#define USER_RGF_SERIAL_BAUD_RATE_READY 0x15e
+#define USER_RGF_PLL_CLR_LOS_COUNTER_CTL 0x882dc4
+#define USER_RGF_HW_MACHINE_STATE 0x8801dc
+#define HW_MACHINE_BOOT_DONE 0x3FFFFFD
+#define USER_RGF_CLKS_CTL_0 0x880abc
+#define BIT_USER_CLKS_CAR_AHB_SW_SEL BIT(1) /* ref clk/PLL */
+#define BIT_USER_CLKS_RST_PWGD BIT(11)
+
+#define USER_RGF_JTAG_DEVICE_TYPE 0x880B34
+#define USER_RGF_JTAG_DEVICE_SPARROW_A0 0x0632072F
+#define USER_RGF_JTAG_DEVICE_SPARROW_A1 0x1632072F
+#define USER_RGF_JTAG_DEVICE_SPARROW_B0 0x2632072F
+#define USER_RGF_CLKS_CTL_EXT_SW_RST_VEC_0 (0x880c18)
+#define USER_RGF_CLKS_CTL_EXT_SW_RST_VEC_1 (0x880c2c)
+#define USER_RGF_SPARROW_M_4 (0x880c50) /* Sparrow */
+#define BIT_SPARROW_M_4_SEL_SLEEP_OR_REF BIT(2)
+
+#define USER_RGF_CAF_ICR 0x88946c /* struct RGF_ICR */
+#define RGF_CAF_ICR_ICR (USER_RGF_CAF_ICR+4)
+#define RGF_CAF_ICR_IMV (USER_RGF_CAF_ICR+16)
+#define USER_RGF_CAF_OSC_CONTROL 0x88afa4
+#define BIT_CAF_OSC_XTAL_EN BIT(0)
+#define USER_RGF_CAF_PLL_LOCK_STATUS 0x88afec
+#define BIT_CAF_OSC_DIG_XTAL_STABLE BIT(0)
+
+#define XTAL_STABLE_WAIT_MS 0x7
+
+#define ALIGN_DOWN_BY(length, alignment) \
+ (length & ~(alignment - 1))
+
+#define ALIGN_UP_BY(length, alignment) \
+ (ALIGN_DOWN_BY((length + alignment - 1), alignment))
+
+WLCTPCIACSS_API int GetMyVersion(WLCT_DLL_VERSION *pVer);
+WLCTPCIACSS_API bool wPciDisableEnable();
+WLCTPCIACSS_API int GetInterfaces(INTERFACE_LIST* ifList, int* ReturnItems);
+WLCTPCIACSS_API int StrGetInterfaces(char* ifListStr, int capacity);
+WLCTPCIACSS_API int CreateDeviceAccessHandler(const char* deviceName, DType devType, void** pDeviceAccess);
+WLCTPCIACSS_API int CloseDeviceAccessHandler(void* pDeviceAccss);
+WLCTPCIACSS_API int SwReset(void* pDeviceAccss);
+WLCTPCIACSS_API int InterfaceReset(void* pDeviceAccss);
+WLCTPCIACSS_API int WlctAccssRead(void* pDeviceAccss, DWORD addr, DWORD & val);
+WLCTPCIACSS_API int WlctAccssWrite(void* pDeviceAccss, DWORD addr, DWORD val);
+WLCTPCIACSS_API bool isInit(void* pDeviceAccss);
+WLCTPCIACSS_API int writeBlock(void* pDeviceAccss, DWORD addr, DWORD blockSize, const char *arrBlock);
+WLCTPCIACSS_API int readBlock(void* pDeviceAccss, DWORD addr, DWORD blockSize, char *arrBlock);
+WLCTPCIACSS_API int readRepeat(void* pDeviceAccss, DWORD addr, DWORD num_repeat, DWORD *arrBlock);
+WLCTPCIACSS_API int getDbgMsg(void* pDeviceAccss, FW_DBG_MSG** pMsg);
+WLCTPCIACSS_API int clearAllFwDbgMsg(void* pDeviceAccss);
+WLCTPCIACSS_API int card_reset(void* pDeviceAccss);
+WLCTPCIACSS_API TCHAR* getInterfaceName(void* pDeviceAccss);
+WLCTPCIACSS_API DType getDeviceType(void* pDeviceAccss);
+WLCTPCIACSS_API int startSampling(void* pDeviceAccss, DWORD* pRegsArr, DWORD regArrSize, DWORD interval, DWORD maxSampling, DWORD transferMethod);
+WLCTPCIACSS_API int stopSampling(void* pDeviceAccss);
+WLCTPCIACSS_API int getSamplingData(void* pDeviceAccss, DWORD** pDataSamples);
+WLCTPCIACSS_API int SetMachineSpeed(void* pComDeviceAccss, DWORD baud_rate_target);
+#ifndef _ANDROID
+WLCTPCIACSS_API int WlctAccssJtagSendDR(void* pDeviceAccss, DWORD num_bits, BYTE *arr_in, BYTE *arr_out);
+WLCTPCIACSS_API int WlctAccssJtagSendIR(void* pDeviceAccss, DWORD num_bits, BYTE *arr_in);
+WLCTPCIACSS_API int JtagTmsShiftToReset(void* pDeviceAccss);
+WLCTPCIACSS_API int JtagPutTmsTdiBits(void* pDeviceAccss, BYTE *tms, BYTE *tdi, BYTE* tdo, UINT length);
+WLCTPCIACSS_API int JtagSetClockSpeed(void* pDeviceAccss, DWORD requestedFreq, DWORD* frqSet);
+#endif
+#ifdef _WINDOWS
+WLCTPCIACSS_API int WlctAccssSendWmiCmd(void* pDeviceAccss, SEND_RECEIVE_WMI* wmi);
+WLCTPCIACSS_API int WlctAccssRecieveWmiEvent(void* pDeviceAccss, SEND_RECEIVE_WMI* evt);
+WLCTPCIACSS_API int WlctAccssMpSetDriverLogLevels(void* pDeviceAccss, ULONG logModulesEnableMsk, ULONG logModuleLevelsMsk[WILO_DRV_NUM_LOG_COMPS]);
+#endif
+WLCTPCIACSS_API int WlctAccssRegisterDriverMailboxEvents(void* pDeviceAccss, HANDLE* pMailboxEventHandle );
+WLCTPCIACSS_API int WlctAccssUnregisterDriverMailboxEvents(void* pDeviceAccss);
+WLCTPCIACSS_API int WlctAccssRegisterDriverEvent(void* pDeviceAccss, INT_PTR event_ptr, int eventId, int appId);
+WLCTPCIACSS_API int WlctAccssRegisterDeviceForUnplug2Event(void* pDeviceAccss, INT_PTR event_ptr);
+
+WLCTPCIACSS_API int WlctAccssAllocPmc(void* pDeviceAccss, DWORD size, DWORD numOfDescriptors);
+WLCTPCIACSS_API int WlctAccssRegisterDriverDeviceEvents(void* pDeviceAccss, INT_PTR hDnEvent, INT_PTR hUpEvent, INT_PTR hUnplugEvent, INT_PTR hSysAssertEvent );
+
+
+WLCTPCIACSS_API int accssRead(void* pDeviceAccss, DWORD addr, DWORD & val);
+WLCTPCIACSS_API int accssWrite(void* pDeviceAccss, DWORD addr, DWORD val);
+WLCTPCIACSS_API int accssClear32(void* pDeviceAccss, DWORD addr, DWORD val);
+WLCTPCIACSS_API int accssSet32(void* pDeviceAccss, DWORD addr, DWORD val);
+
+WLCTPCIACSS_API void hwCopyFromIO(void* dst, void* pDeviceAccss, DWORD src, UINT32 len);
diff --git a/debug-tools/lib/WlctPciAcss/WlctPciAcssHelper.h b/debug-tools/lib/WlctPciAcss/WlctPciAcssHelper.h
new file mode 100644
index 0000000..163d76c
--- /dev/null
+++ b/debug-tools/lib/WlctPciAcss/WlctPciAcssHelper.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "WlctPciAcss.h"
+
+int GetSimulatorInterfaces(INTERFACE_LIST* ifList, int* ReturnItems);
+int GetPciInterfaces(INTERFACE_LIST* ifList, int* ReturnItems);
+#ifndef _ANDROID_
+int GetJtagInterfaces(INTERFACE_LIST* ifList, int* ReturnItems);
+int GetSerialInterfaces(INTERFACE_LIST* ifList, int* ReturnItems);
+#endif
+
+class CComPortDeviceAccess;
+
+void ComSetParameters(CComPortDeviceAccess* pComDeviceAccss, DType devType);
+int SetMachineSpeed(void* pDeviceAccss, DWORD baud_rate_target);
+
+uint64_t GetTimeStampMs();
+
+int GetPciAcssVersion(WLCT_DLL_VERSION *pVer);
diff --git a/debug-tools/lib/WlctPciAcss/WlctPciAcssWmi.h b/debug-tools/lib/WlctPciAcss/WlctPciAcssWmi.h
new file mode 100644
index 0000000..0ed10b7
--- /dev/null
+++ b/debug-tools/lib/WlctPciAcss/WlctPciAcssWmi.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#define PREPACK
+#define POSTPACK
+#pragma pack(1)
+#include "wmi.h" // definition of all WMI command structures
+#pragma pack()
+
+
+/* used by IOCTL_REGISTER_WMI_RX_EVENT and IOCTL_REGISTER_DEVICE_EVENT */
+typedef struct
+{
+ HANDLE hEvent; /* use INVALID_HANDLE_VALUE to de-register */
+} REGISTER_EVENT;
+
+
+/* used by IOCTL_OPEN_USER_MODE_EVENT */
+/*
+ original structure inside the driver is as follows:
+ typedef struct _SHARED_EVENT
+ {
+ HANDLE hDnEvent;
+ HANDLE hUpEvent;
+ HANDLE unplugEvent;
+ HANDLE sysAssertEvent;
+
+ } SHARED_EVENT, *PSHARED_EVENT;
+
+ The HANDLE type inside the driver is platform speciefic, and
+ can be either 32bit or 64bit!
+ Since our DLL is assumed to be always compiled for 32bit platforms,
+ it is a problem.
+
+ Until the HANDLE types in the driver are changed to ULONG,
+ or until this DLL will have two diffrent barnches for 32bit and 64bit platforms,
+ the following Workarround is implemented:
+ 1. Diffrent structs for 32bit and 64bit platforms.
+ 2. when sending the IOCTL_OPEN_USER_MODE_EVENT, dynamically descide which struct to use.
+*/
+
+
+//those structs are deprecated
+typedef struct _SHARED_EVENT_64BIT
+{
+ INT_PTR hDnEvent_l;
+ INT_PTR hDnEvent_h;
+
+ INT_PTR hUpEvent_l;
+ INT_PTR hUpEvent_h;
+
+ INT_PTR unplugEvent_l;
+ INT_PTR unplugEvent_h;
+
+ INT_PTR sysAssertEvent_l;
+ INT_PTR sysAssertEvent_h;
+
+} SHARED_EVENT_64BIT, *PSHARED_EVENT_64BIT;
+
+typedef struct _SHARED_EVENT_32BIT
+{
+ INT_PTR hDnEvent;
+ INT_PTR hUpEvent;
+ INT_PTR unplugEvent;
+ INT_PTR sysAssertEvent;
+
+} SHARED_EVENT_32BIT, *PSHARED_EVENT_32BIT;
\ No newline at end of file
diff --git a/debug-tools/lib/WlctPciAcss/linux/CommDeviceAccess.cpp b/debug-tools/lib/WlctPciAcss/linux/CommDeviceAccess.cpp
new file mode 100644
index 0000000..d92ebc7
--- /dev/null
+++ b/debug-tools/lib/WlctPciAcss/linux/CommDeviceAccess.cpp
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "CommDeviceAccess.h"
+
+CComPortDeviceAccess::CComPortDeviceAccess(const TCHAR* tchDeviceName, DType devType)
+{
+ //do something with params
+ (void)tchDeviceName;
+ (void)devType;
+ LOG_MESSAGE_ERROR(_T("Not Supported\n"));
+}
+
+int CComPortDeviceAccess::InitDevice()
+{
+ LOG_MESSAGE_ERROR(_T("Not Supported\n"));
+ return 0;
+}
+
+CComPortDeviceAccess::~CComPortDeviceAccess()
+{
+ LOG_MESSAGE_ERROR(_T("Not Supported\n"));
+}
+
+int CComPortDeviceAccess::GetType()
+{
+ LOG_MESSAGE_ERROR(_T("Not Supported\n"));
+ return 0;
+}
+
+int CComPortDeviceAccess::CloseDevice()
+{
+ LOG_MESSAGE_ERROR(_T("Not Supported\n"));
+ return 0;
+}
+
+int CComPortDeviceAccess::r2(DWORD addr, DWORD & val)
+{
+ //do something with params
+ (void)addr;
+ (void)val;
+ LOG_MESSAGE_ERROR(_T("Not Supported\n"));
+ return 0;
+}
+
+int CComPortDeviceAccess::w2(DWORD addr, DWORD val)
+{
+ //do something with params
+ (void)addr;
+ (void)val;
+ LOG_MESSAGE_ERROR(_T("Not Supported\n"));
+ return 0;
+}
+
+int CComPortDeviceAccess::w32(DWORD addr, DWORD val)
+{
+ //do something with params
+ (void)addr;
+ (void)val;
+ LOG_MESSAGE_ERROR(_T("Not Supported\n"));
+ return 0;
+}
+
+int CComPortDeviceAccess::rb(DWORD addr, DWORD blockSize, char *arrBlock)
+{
+ //do something with params
+ (void)addr;
+ (void)blockSize;
+ (void)arrBlock;
+
+ LOG_MESSAGE_ERROR(_T("Not Supported\n"));
+ return 0;
+}
+
+int CComPortDeviceAccess::wb(DWORD addr, DWORD blockSize, const char *arrBlock)
+{
+ //do something with params
+ (void)addr;
+ (void)blockSize;
+ (void)arrBlock;
+
+ LOG_MESSAGE_ERROR(_T("Not Supported\n"));
+ return 0;
+}
+
+int CComPortDeviceAccess::rr(DWORD addr, DWORD num_repeat, DWORD *arrBlock)
+{
+ //do something with params
+ (void)addr;
+ (void)num_repeat;
+ (void)arrBlock;
+
+ LOG_MESSAGE_ERROR(_T("Not Supported\n"));
+ return 0;
+}
+
+int CComPortDeviceAccess::getFwDbgMsg(FW_DBG_MSG** pMsg)
+{
+ //do something with params
+ (void)pMsg;
+
+ LOG_MESSAGE_ERROR(_T("Not Supported\n"));
+ return 0;
+}
+
+int CComPortDeviceAccess::clearAllFwDbgMsg()
+{
+ LOG_MESSAGE_ERROR(_T("Not Supported\n"));
+ return 0;
+}
+
+int CComPortDeviceAccess::do_reset(BOOL bFirstTime)
+{
+ //do something with params
+ (void)bFirstTime;
+
+ LOG_MESSAGE_ERROR(_T("Not Supported\n"));
+ return 0;
+}
+
+int CComPortDeviceAccess::do_sw_reset()
+{
+ LOG_MESSAGE_ERROR(_T("Not Supported\n"));
+ return 0;
+}
+
+
+int CComPortDeviceAccess::r32(DWORD addr, DWORD & val)
+{
+ //do something with params
+ (void)addr;
+ (void)val;
+ LOG_MESSAGE_ERROR(_T("Not Supported\n"));
+ return 0;
+}
+
+int CComPortDeviceAccess::r4(DWORD addr, DWORD & val)
+{
+ //do something with params
+ (void)addr;
+ (void)val;
+ LOG_MESSAGE_ERROR(_T("Not Supported\n"));
+ return 0;
+}
+
+
+
diff --git a/debug-tools/lib/WlctPciAcss/linux/CommDeviceAccess.h b/debug-tools/lib/WlctPciAcss/linux/CommDeviceAccess.h
new file mode 100644
index 0000000..cd804f1
--- /dev/null
+++ b/debug-tools/lib/WlctPciAcss/linux/CommDeviceAccess.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+//using namespace std;
+
+#include "DeviceAccess.h"
+
+class CComPortDeviceAccess : public IDeviceAccess
+{
+public:
+ CComPortDeviceAccess(const TCHAR* tchDeviceName, DType devType);
+ ~CComPortDeviceAccess(void);
+
+ virtual int CloseDevice();
+ virtual int GetType();
+ virtual int r2(DWORD addr, DWORD & val);
+ virtual int r4(DWORD addr, DWORD & val);
+ virtual int w2(DWORD addr, DWORD val);
+
+ virtual int r32(DWORD addr, DWORD & val);
+ virtual int w32(DWORD addr, DWORD val);
+
+ // read block
+ virtual int rb(DWORD addr, DWORD blockSize, char *arrBlock);
+ // write block
+ virtual int wb(DWORD addr, DWORD blockSize, const char *arrBlock);
+ // read repeat
+ virtual int rr(DWORD addr, DWORD num_repeat, DWORD *arrBlock);
+
+ virtual int getFwDbgMsg(FW_DBG_MSG** pMsg);
+ virtual int clearAllFwDbgMsg();
+ virtual int do_reset(BOOL bFirstTime = TRUE);
+ virtual int do_sw_reset();
+
+ int InitDevice();
+};
diff --git a/debug-tools/lib/WlctPciAcss/linux/IoctlDev.cpp b/debug-tools/lib/WlctPciAcss/linux/IoctlDev.cpp
new file mode 100644
index 0000000..4473315
--- /dev/null
+++ b/debug-tools/lib/WlctPciAcss/linux/IoctlDev.cpp
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "IoctlDev.h"
+#include "wlct_procfs.h"
+#include "public.h"
+#include "LoggerSupport.h"
+#include <iostream>
+#include <fstream>
+
+#include <algorithm>
+
+#define PROC_MODULES_PATH "/proc/modules"
+#define DRIVER_KEYWORD "wil6210"
+
+void CIoctlDev::FormatCDevFName(void)
+{
+ int sres = snprintf(cdevFileName, sizeof(cdevFileName),
+ "/tmp/%s", WLCT_CDEV_NAME);
+
+ WLCT_ASSERT((size_t)sres < sizeof(cdevFileName));
+ (void)sres;
+}
+
+CIoctlDev::CIoctlDev(const TCHAR *tchDeviceName)
+ : IIoctlDev(tchDeviceName)
+{
+ if( strstr(szInterfaceName, "wEP") != NULL || strstr(szInterfaceName, "wep") != NULL ){
+ cdevFile = new CWlctCDevSocket();
+ } else{
+ cdevFile = new CWlctCDevFile();
+ }
+ // Name in format WLCT_PCI_LDEVNAME_FMT/WLCT_PCI_RDEVNAME_FMT
+ FormatCDevFName();
+}
+
+CIoctlDev::~CIoctlDev()
+{
+ delete cdevFile;
+ Close();
+}
+
+bool CIoctlDev::IsOpened(void)
+{
+ return cdevFile->IsOpened();
+}
+
+wlct_os_err_t CIoctlDev::DebugFS(char *FileName, void *dataBuf, DWORD dataBufLen, DWORD DebugFSFlags)
+{
+ return cdevFile->DebugFS(FileName, dataBuf, dataBufLen, DebugFSFlags);
+}
+
+bool WilDriverExistForEP(TCHAR *szInterfaceName)
+{
+
+ if( strstr(szInterfaceName, "wEP") != NULL || strstr(szInterfaceName, "wep") != NULL ){
+ ifstream ifs(PROC_MODULES_PATH);
+ string DriverKey = DRIVER_KEYWORD;
+ string line;
+ while(getline(ifs, line)) {
+ if (line.find(DriverKey, 0) != string::npos) {
+ LOG_MESSAGE_INFO(_T("Found WIGIG interface [wEP0!MARLON]"));
+ return true;
+ }
+ }
+ }
+ return false;
+}
+wlct_os_err_t CIoctlDev::Open()
+{
+ wlct_os_err_t res = WLCT_OS_ERROR_GEN_FAILURE;
+
+ WLCT_ASSERT(!IsOpened());
+
+ bOldIoctls = TRUE;
+
+ if (WilDriverExistForEP(szInterfaceName))
+ {
+ // Bug fix
+ char tempInterfaceName[INTERFACE_NAME_LENGTH];
+ snprintf(tempInterfaceName, INTERFACE_NAME_LENGTH, "%s", szInterfaceName);
+
+ LOG_MESSAGE_DEBUG("Tokenizing: %s\n", tempInterfaceName);
+
+ res = cdevFile->Open(cdevFileName, tempInterfaceName);
+ if (res == WLCT_OS_ERROR_SUCCESS)
+ {
+ LOG_MESSAGE_DEBUG("Cdev file '%s' opened (uid=%u)",
+ cdevFileName, uID);
+ }
+ else
+ {
+ LOG_MESSAGE_ERROR("Cdev file '%s' (uid=%u) opening failed (%d)",
+ cdevFileName, uID, res);
+ }
+ }
+ else
+ {
+ LOG_MESSAGE_ERROR("Cannot get UID by PciDevName (%s)",
+ szInterfaceName);
+ res = WLCT_OS_ERROR_NO_SUCH_ENTRY;
+ }
+
+ return res;
+}
+
+void CIoctlDev::Close()
+{
+ if (IsOpened())
+ {
+ cdevFile->Close();
+ }
+}
+
+wlct_os_err_t CIoctlDev::Ioctl(uint32_t Id,
+ const void *inBuf, uint32_t inBufSize,
+ void *outBuf, uint32_t outBufSize)
+{
+ wlct_os_err_t res = WLCT_OS_ERROR_GEN_FAILURE;
+ wlct_ioctl_hdr_t *ioctlHdr = NULL;
+ uint32_t ioctlBufSize = 0;
+
+ WLCT_ASSERT(IsOpened());
+
+ if (!inBuf || !inBufSize)
+ {
+ inBuf = NULL;
+ inBufSize = 0;
+ }
+
+ if (!outBuf || !outBufSize)
+ {
+ outBuf = NULL;
+ outBufSize = 0;
+ }
+
+ ioctlBufSize = sizeof(wlct_ioctl_hdr_t) + inBufSize + outBufSize;
+
+ ioctlHdr = (wlct_ioctl_hdr_t *)malloc(ioctlBufSize);
+ if (ioctlHdr)
+ {
+ uint32_t offset = 0;
+ uint32_t ioctlFlags = 0;
+
+ memset(ioctlHdr, 0, ioctlBufSize);
+
+ ioctlHdr->deviceUID = uID;
+ ioctlHdr->commandID = Id;
+ ioctlHdr->dataSize = inBufSize + outBufSize;
+ if (inBufSize)
+ {
+ ioctlHdr->inBufOffset = offset;
+ ioctlHdr->inBufSize = inBufSize;
+ ioctlFlags |= WLCT_IOCTL_FLAG_SET;
+
+ memcpy(wlct_ioctl_data_in(ioctlHdr), inBuf, inBufSize);
+
+ offset += inBufSize;
+ }
+
+ if (outBufSize)
+ {
+ ioctlHdr->outBufOffset = offset;
+ ioctlHdr->outBufSize = outBufSize;
+ ioctlFlags |= WLCT_IOCTL_FLAG_GET;
+
+ offset += outBufSize;
+ }
+
+ res = cdevFile->Ioctl(ioctlHdr, ioctlBufSize, ioctlFlags);
+
+ if (res != WLCT_OS_ERROR_SUCCESS)
+ {
+ LOG_MESSAGE_ERROR("IOCTL failed with error %u (id=%u)",
+ res, Id);
+ }
+ else if (outBufSize)
+ {
+ memcpy(outBuf, wlct_ioctl_data_out(ioctlHdr), outBufSize);
+ }
+
+ free(ioctlHdr);
+ }
+ else
+ {
+ LOG_MESSAGE_ERROR("Cannot allocate IOCTL buffer of %u bytes (id=%u)",
+ ioctlBufSize, Id);
+
+ res = WLCT_OS_ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+
+ return res;
+}
diff --git a/debug-tools/lib/WlctPciAcss/linux/IoctlDev.h b/debug-tools/lib/WlctPciAcss/linux/IoctlDev.h
new file mode 100644
index 0000000..98c5ac5
--- /dev/null
+++ b/debug-tools/lib/WlctPciAcss/linux/IoctlDev.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "IoctlDevXFace.h"
+#include "WlctCDevFile.h"
+#include "WlctCDevSocket.h"
+
+using namespace std;
+#include <string>
+
+typedef enum{
+ local = 0,
+ remote,
+ endPoint,
+}DEVICE_TYPES;
+
+class CIoctlDev : public IIoctlDev
+{
+public:
+ CIoctlDev(const TCHAR *tchDeviceName);
+ virtual ~CIoctlDev();
+
+ virtual bool IsOpened(void);
+ virtual wlct_os_err_t DebugFS(char *FileName, void *dataBuf, DWORD dataBufLen, DWORD DebugFSFlags);
+
+ virtual wlct_os_err_t Open();
+ virtual wlct_os_err_t Ioctl(uint32_t Id,
+ const void *inBuf, uint32_t inBufSize,
+ void *outBuf, uint32_t outBufSize);
+ virtual void Close();
+
+ bool bOldIoctls;
+
+protected:
+ void FormatCDevFName(void);
+
+ char cdevFileName[128];
+ CWlctCDevFile* cdevFile;
+ uint32_t uID;
+};
diff --git a/debug-tools/lib/WlctPciAcss/linux/Util.cpp b/debug-tools/lib/WlctPciAcss/linux/Util.cpp
new file mode 100644
index 0000000..4ad5d69
--- /dev/null
+++ b/debug-tools/lib/WlctPciAcss/linux/Util.cpp
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "Util.h"
+
+#ifdef NO_GCC_ATOMIC
+#error "Platform doesn't support GCC atomic built-ins"
+#endif
+
+#define InterlockedExchange __sync_lock_test_and_set
+
+BOOL Util::timedResourceInterLockExchange ( LONG* var, LONG flag_value, int timeout, bool keepWaiting )
+{
+ // perform atomic change value, to acquire resource!
+ // if VAR != FLAG_VALUE, then set VAR to FLAG_VALUE.
+ // loop until timeout (millisecond). return success in achieving resource
+ // Assumes that FLAG_VALUE should be different then current value stored in VAR
+ // turn keepWaiting on to wait infinite
+
+ LONG original_value;
+
+ int i = 0;
+ do
+ {
+ original_value = InterlockedExchange(var, flag_value);
+ if (original_value != flag_value)
+ {
+ return true;
+ }
+ if (timeout > 0 )
+ {
+ sleep_ms(1);
+ }
+ i++;
+ } while ((i < timeout) || (keepWaiting));
+
+ return false;
+}
+
+bool Util::ICHDisableEnable()
+{
+ return false;
+}
+
+DWORD Util::ReadRegistrySettings(LPCTSTR lpszRegistryPath, LPCTSTR valName)
+{
+ //do something with params
+ (void)lpszRegistryPath;
+ (void)valName;
+
+ return -1;
+}
+
+DWORD Util::WriteRegistrySettings(LPCTSTR lpszRegistryPath, LPCTSTR valName, DWORD val)
+{
+ //do something with params
+ (void)lpszRegistryPath;
+ (void)valName;
+ (void)val;
+
+ return -1;
+}
diff --git a/debug-tools/lib/WlctPciAcss/linux/WlctPciAcssHelper.cpp b/debug-tools/lib/WlctPciAcss/linux/WlctPciAcssHelper.cpp
new file mode 100644
index 0000000..646be85
--- /dev/null
+++ b/debug-tools/lib/WlctPciAcss/linux/WlctPciAcssHelper.cpp
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "WlctPciAcssHelper.h"
+#include "PciDeviceAccess.h"
+#include <iostream>
+#include <fstream>
+#include <string>
+
+#ifdef _WINDOWS
+#include "JtagDeviceAccess.h"
+#endif
+
+#include <sys/time.h>
+
+#define WLCT_MS_PER_S 1000
+#define WLCT_US_PER_MS 1000
+#define PROC_MODULES_PATH "/proc/modules"
+#define DRIVER_KEYWORD "wil6210"
+
+#define END_POINT_RESULT_MAX_SIZE 1000
+
+using namespace std;
+
+void CreatePciInterface(const char* interfaceName, DType devType, INTERFACE_LIST* ifList, int* ReturnItems);
+void CreateMultipleInterfaces(const char* interfaceName, DType devType, INTERFACE_LIST* ifList, int* ReturnItems);
+bool GetInterfaceNameFromEP(const char* pciEndPoint, char* interfaceName);
+int GetNumberOfInterfaces();
+
+int GetSimulatorInterfaces(INTERFACE_LIST* ifList, int* ReturnItems)
+{
+ // Not supported in Linux
+ WLCT_UNREFERENCED_PARAM(ifList);
+
+ return *ReturnItems;
+}
+bool WilDriverExist()
+{
+ ifstream ifs(PROC_MODULES_PATH);
+ string DriverKey = DRIVER_KEYWORD;
+ string line;
+ while(getline(ifs, line)) {
+ if (line.find(DriverKey, 0) != string::npos) {
+ LOG_MESSAGE_INFO(_T("Found WIGIG interface [wEP0!MARLON]"));
+ return true;
+ }
+ }
+
+ return false;
+}
+
+int GetPciInterfaces(INTERFACE_LIST* ifList, int* ReturnItems)
+{
+ CreateMultipleInterfaces("wEP0L!SPARROW", MST_SPARROW, ifList, ReturnItems);
+
+ return *ReturnItems;
+}
+
+void CreateMultipleInterfaces(const char* interfaceName, DType devType, INTERFACE_LIST* ifList, int* ReturnItems)
+{
+ //do something with params
+ (void)devType;
+ // Holds the console ouput containing the current End Point
+ char pciEndPoints[END_POINT_RESULT_MAX_SIZE];
+
+ // This command retrieves the PCI endpoints enumerated
+ const char* szCmdPattern = "ls /sys/module/wil6210/drivers/pci\\:wil6210 | grep :";
+
+ FILE* pIoStream = popen(szCmdPattern, "r");
+ if (!pIoStream)
+ {
+ LOG_MESSAGE_ERROR("Failed to run command to detect End Points\n" );
+ return;
+ }
+
+ LOG_MESSAGE_DEBUG("Searching for PCI end points: %s", szCmdPattern);
+
+ while (fgets(pciEndPoints, END_POINT_RESULT_MAX_SIZE, pIoStream) != NULL)
+ {
+ // The command output contains a newline character that should be removed
+ pciEndPoints[strcspn(pciEndPoints, "\r\n")] = '\0';
+ LOG_MESSAGE_DEBUG("PCI End Point Found: %s", pciEndPoints);
+
+ // Get interface name from End Point
+ char networkInterfaceName[IFNAMSIZ] = {0};
+ GetInterfaceNameFromEP(pciEndPoints, networkInterfaceName);
+
+ // Append driver interface name
+ std::string ifName = interfaceName;
+ ifName += "!";
+ ifName += networkInterfaceName;
+
+ LOG_MESSAGE_DEBUG("Attempting to create interface named: %s", ifName.c_str());
+
+ CreatePciInterface(ifName.c_str(), MST_SPARROW, ifList, ReturnItems);
+ }
+
+ pclose(pIoStream);
+}
+
+
+bool GetInterfaceNameFromEP(const char* pciEndPoint, char* interfaceName)
+{
+ char szInterfaceCmdPattern[END_POINT_RESULT_MAX_SIZE];
+
+ // This command translates the End Point to the interface name
+ snprintf(szInterfaceCmdPattern, END_POINT_RESULT_MAX_SIZE, "ls /sys/module/wil6210/drivers/pci:wil6210/%s/net", pciEndPoint);
+
+ LOG_MESSAGE_DEBUG("Running command: %s", szInterfaceCmdPattern);
+
+ FILE* pIoStream = popen(szInterfaceCmdPattern, "r");
+ if (!pIoStream)
+ {
+ LOG_MESSAGE_ERROR("Failed to run command to detect End Points\n" );
+ return false;
+ }
+
+ while (fgets(interfaceName, IFNAMSIZ, pIoStream) != NULL)
+ {
+ // The command output contains a newline character that should be removed
+ interfaceName[strcspn(interfaceName, "\r\n")] = '\0';
+ LOG_MESSAGE_DEBUG("PCI interface found: %s", interfaceName);
+
+ return true;
+ }
+
+ pclose(pIoStream);
+ return false;
+}
+
+
+void CreatePciInterface(const char* interfaceName, DType devType, INTERFACE_LIST* ifList, int* ReturnItems)
+{
+ void* res = NULL;
+ void** tempAccess = &res;
+
+ if(!CreateDeviceAccessHandler(interfaceName, devType, tempAccess))
+ {
+ snprintf(ifList->list[(*ReturnItems)].ifName, MAX_IF_NAME_LENGTH, "%s", interfaceName);
+ (*ReturnItems) += 1;
+ LOG_MESSAGE_INFO(_T("Found WIGIG interface"));
+ if(res)
+ {
+ CloseDeviceAccessHandler(*tempAccess);
+ }
+ }
+}
+
+int GetSerialInterfaces(INTERFACE_LIST* ifList, int* ReturnItems)
+{
+ // Not supported in Linux
+ WLCT_UNREFERENCED_PARAM(ifList);
+
+ return *ReturnItems;
+}
+
+int GetJtagInterfaces(INTERFACE_LIST* ifList, int* ReturnItems)
+{
+
+#ifdef _WINDOWS
+ DType devType;
+ void* handler = NULL;
+ DWORD err;
+ uint32_t addr;
+ uint32_t val;
+ int ret = 0;
+
+ char ifName[MAX_IF_NAME_LENGTH];
+
+ //////////////////////////////////////////////////////////////////////////
+ // find all jtag channels that connect to a WIGIG card
+ //////////////////////////////////////////////////////////////////////////
+ devType = MST_MARLON;
+ addr = BAUD_RATE_REGISTER;
+
+ int cdvc = 0;
+ DVC dvc;
+ char infoSet[28];
+
+ LOG_MESSAGE_INFO(_T("scan jtag devices"));
+
+ if (!funcDmgrEnumDevices(&cdvc)) {
+ LOG_MESSAGE_INFO(_T("Error enumerating JTAG devices"));
+ cdvc = 0;
+ }
+
+ for (int idvc = 0; idvc < cdvc; idvc++) {
+
+ // DMGR API Call: funcDmgrGetDvc
+ if (!funcDmgrGetDvc(idvc, &dvc)) {
+ LOG_MESSAGE_INFO(_T("Error getting device info"));
+ break;
+ }
+ DINFO dinfo = dinfoUsrName;
+ BOOL bRes;
+ snprintf(infoSet, sizeof(infoSet), "wjtag%d", idvc);
+ bRes = funcDmgrSetInfo(&dvc, dinfo, (void*)infoSet);
+
+ WLCT_UNREFERENCED_PARAM(bRes);
+
+ snprintf(ifName, MAX_IF_NAME_LENGTH, "%s!MARLON", infoSet);
+ err = CreateDeviceAccessHandler(ifName, devType, &handler);
+ if (err == 0 && isInit(handler))
+ {
+ ret = WlctAccssRead(handler, addr, val);
+ if (ret == 0 && val > 0 && val < 0xFFFF)
+ {
+ snprintf(ifList->list[(*ReturnItems)++].ifName, MAX_IF_NAME_LENGTH, "%s", ifName);
+ LOG_MESSAGE_INFO(_T("Found JTAG WIGIG interface [%s]"),
+ ifName);
+ }
+ CloseDeviceAccessHandler(handler);
+ handler = NULL;
+ }
+ }
+
+ /* Clean up and get out */
+ // DMGR API Call: DmgrFreeDvcEnum
+ funcDmgrFreeDvcEnum();
+
+#endif
+//do something with params
+ WLCT_UNREFERENCED_PARAM(ifList);
+ return *ReturnItems;
+}
+
+void ComSetParameters(CComPortDeviceAccess* pComDeviceAccss, DType devType)
+{
+ // Not supported in Linux
+ WLCT_UNREFERENCED_PARAM(pComDeviceAccss);
+ WLCT_UNREFERENCED_PARAM(devType);
+}
+
+int SetMachineSpeed(void* pDeviceAccss, DWORD baud_rate_target)
+{
+ // Not supported in Linux
+ WLCT_UNREFERENCED_PARAM(pDeviceAccss);
+ WLCT_UNREFERENCED_PARAM(baud_rate_target);
+
+ return -1;
+}
+
+uint64_t GetTimeStampMs()
+{
+ struct timeval tv = {0,0};
+ if (gettimeofday(&tv, NULL) == 0)
+ {
+ return tv.tv_sec * WLCT_MS_PER_S + tv.tv_usec / WLCT_US_PER_MS;
+ }
+
+ return 0;
+}
+
+int GetPciAcssVersion(WLCT_DLL_VERSION *pVer)
+{
+ WLCT_ASSERT(pVer != NULL);
+ pVer->major = 0;
+ pVer->minor = 0;
+ pVer->maintenance = 0;
+ pVer->build = 0;
+ return 0;
+}
+
diff --git a/debug-tools/lib/inc/basic_types.h b/debug-tools/lib/inc/basic_types.h
new file mode 100644
index 0000000..1145107
--- /dev/null
+++ b/debug-tools/lib/inc/basic_types.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef BASIC_TYPES_H_
+#define BASIC_TYPES_H_
+#define EMPTY_ARRAY_SIZE
+
+#ifdef _WINDOWS
+
+#else
+typedef signed char INT8;
+typedef signed short INT16;
+typedef signed int INT32;
+typedef signed long INT64;
+typedef unsigned char UINT8;
+typedef unsigned short UINT16;
+typedef unsigned int UINT32;
+typedef UINT32* PUINT32;
+typedef unsigned long UINT64;
+typedef UINT64 INT_PTR;
+#endif
+
+typedef UINT64 u64;
+typedef UINT32 u32;
+typedef UINT16 u16;
+typedef UINT8 u8;
+typedef INT64 s64;
+typedef INT32 s32;
+typedef INT16 s16;
+typedef INT8 s8;
+
+
+typedef u8 U08;
+typedef u16 U16;
+typedef u32 U32;
+typedef s32 S32;
+typedef s8 S08;
+typedef u8* PU08;
+typedef u16* PU16;
+
+#endif //BASIC_TYPES_H_
diff --git a/debug-tools/lib/inc/ioctl_if.h b/debug-tools/lib/inc/ioctl_if.h
new file mode 100644
index 0000000..3bfbbb9
--- /dev/null
+++ b/debug-tools/lib/inc/ioctl_if.h
@@ -0,0 +1,251 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "wmi.h"
+
+#define WBE_DRIVER_NAME L"wmp0"
+
+// use INVALID_HANDLE_VALUE to de-register the event
+#define INVALID_HANDLE_VALUE_LEGACY ((ULONG)(LONG_PTR)-1)
+#define INVALID_HANDLE_VALUE ((HANDLE)(LONG_PTR)-1)
+
+// max value of the device id (user-mode application identifier) - related to WMI_DEVICE_ID
+#define IOCTL_DEVICE_ID_MAX 0xFF
+#define IOCTL_DEVICE_ID_WBE_OLD 0x00
+
+#define WILOCITY_DEVICE_TYPE FILE_DEVICE_UNKNOWN
+#define WILOCITY_IOCTL(_code_) CTL_CODE (WILOCITY_DEVICE_TYPE, _code_, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
+
+#define WILOCITY_IOCTL_DEVICE_STATUS_EVENT WILOCITY_IOCTL (0x208) // API for Monitoring tool
+#define WILOCITY_IOCTL_INDIRECT_READ WILOCITY_IOCTL (0x210)
+#define WILOCITY_IOCTL_INDIRECT_WRITE WILOCITY_IOCTL (0x211)
+#define WILOCITY_IOCTL_INDIRECT_READ_BLOCK WILOCITY_IOCTL (0x212)
+#define WILOCITY_IOCTL_INDIRECT_WRITE_BLOCK WILOCITY_IOCTL (0x214)
+#define WILOCITY_IOCTL_SEND_WMI WILOCITY_IOCTL (0x800)
+#define WILOCITY_IOCTL_REGISTER_EVENT_NEW WILOCITY_IOCTL (0x850)
+#define WILOCITY_IOCTL_UNREGISTER_EVENTS WILOCITY_IOCTL (0x851)
+#define WILOCITY_IOCTL_RECEIVE_WMI_NEW WILOCITY_IOCTL (0x852) // New API Not implemented yet by WBE APP
+#define WILOCITY_IOCTL_DEVICE_RESET WILOCITY_IOCTL (0x807)
+#define WILOCITY_IOCTL_SET_MODE_NEW WILOCITY_IOCTL (0x808) // New API for Concurrent mode controlling (Docking/Networking/hotspot), IOCTL_EVENT_SET_MODE_COMPLETE will be sent to UI on success
+#define WILOCITY_IOCTL_GET_MODE_NEW WILOCITY_IOCTL (0x809) // API for UI to extract driver mode (example: after set mode fail, not event will be sent to UI)
+
+// Deprecated API
+#define WILOCITY_IOCTL_RECEIVE_WMI WILOCITY_IOCTL (0x801)
+// registration for indication of incoming WMI command.
+// Following that, client will use IOCTL_RECEIVE_WMI to get the incoming WMI command
+#define WILOCITY_IOCTL_REGISTER_WMI_RX WILOCITY_IOCTL (0x803)
+// Registration for driver down event
+#define WILOCITY_IOCTL_REGISTER_DEVICE WILOCITY_IOCTL (0x804)
+
+/**
+* WILOCITY_IOCTL_DEVICE_STATUS_EVENT
+**/
+#pragma pack(1)
+typedef struct _DEVICE_STATUS_EVENT
+{
+ HANDLE hDnEvent; // Link Down
+ HANDLE hUpEvent; // Link up
+ HANDLE unplugEvent; // Surprise removal
+ HANDLE sysAssertEvent; // Device Fatal Error
+} DEVICE_STATUS_EVENT, *PDEVICE_STATUS_EVENT;
+#pragma pack()
+
+/**
+* WILOCITY_IOCTL_INDIRECT_READ
+**/
+#pragma pack(1)
+typedef struct _DRIVER_READ_DWORD
+{
+ ULONG address; // Word output will be returned in IOCTL output buffer that was allocated by application
+} DRIVER_READ_DWORD, *PDRIVER_READ_DWORD;
+#pragma pack()
+
+/**
+* WILOCITY_IOCTL_INDIRECT_WRITE
+**/
+#pragma pack(1)
+typedef struct _DRIVER_WRITE_DWORD
+{
+ ULONG address;
+ ULONG data;
+} DRIVER_WRITE_DWORD, *PDRIVER_WRITE_DWORD;
+#pragma pack()
+
+/**
+* WILOCITY_IOCTL_INDIRECT_WRITE_BLOCK
+**/
+#pragma pack(1)
+typedef struct _DRIVER_WRITE_BLOCK
+{
+ ULONG address;
+ ULONG size; // in bytes
+ ULONG buffer[EMPTY_ARRAY_SIZE]; // buffer's data will be allocated by user-mode app right to the end of struct
+} DRIVER_WRITE_BLOCK, *PDRIVER_WRITE_BLOCK;
+#pragma pack()
+
+/**
+* WILOCITY_IOCTL_INDIRECT_READ_BLOCK
+**/
+#pragma pack(1)
+typedef struct _DRIVER_READ_BLOCK
+{
+ ULONG address; // Size is taken from IOCTL output buffer size
+} DRIVER_READ_BLOCK, *PDRIVER_READ_BLOCK;
+#pragma pack()
+
+/**
+* WILOCITY_IOCTL_REGISTER_EVENT_NEW
+**/
+typedef enum _NOTIFY_EVENT {
+ IOCTL_EVENT_PCI_LINK_UP,
+ IOCTL_EVENT_PCI_PRE_LINK_DOWN,
+ IOCTL_EVENT_PCI_LINK_DOWN,
+ IOCTL_EVENT_DEVICE_READY,
+ IOCTL_EVENT_MAILBOX_MSG,
+ IOCTL_EVENT_DEBUG_MAILBOX_MSG,
+ IOCTL_EVENT_SYSASSERT,
+ IOCTL_EVENT_DRIVER_DISABLE,
+ IOCTL_EVENT_SET_MODE_COMPLETE,
+ IOCTL_EVENT_DEVICE_UNPLUG,
+ IOCTL_EVENT_ORACLE_START,
+ IOCTL_EVENT_ORACLE_STOP,
+
+ // !!!do not define any event below MAX_EVENT!!!
+ IOCTL_EVENT_MAX,
+} NOTIFY_EVENT, *PNOTIFY_EVENT;
+
+#pragma pack(1)
+typedef struct _DRIVER_REGISTER_EVENT_NEW
+{
+ ULONG DeviceId; // The application identifier from type WMI_DEVICE_ID
+ NOTIFY_EVENT EventId;
+ HANDLE UserEventHandle; // The application CB to be called on event
+
+} DRIVER_REGISTER_EVENT_NEW, *PDRIVER_REGISTER_EVENT_NEW;
+#pragma pack()
+
+/**
+* WILOCITY_IOCTL_UNREGISTER_EVENTS
+**/
+#pragma pack(1)
+typedef struct _DRIVER_UNREGISTER_EVENTS
+{
+ ULONG DeviceId; // of type WMI_DEVICE_ID, driver will unregistered all APP events
+
+} DRIVER_UNREGISTER_EVENTS, *PDRIVER_UNREGISTER_EVENTS;
+#pragma pack()
+
+/**
+* WILOCITY_IOCTL_REGISTER_WMI_RX_EVENT // Used for WMI event registration
+* WILOCITY_IOCTL_REGISTER_DEVICE // USed for driver unload event registration
+**/
+#pragma pack(1)
+typedef struct _DRIVER_REGISTER_EVENT
+{
+ ULONG UserEventHandle; // The application CB to be called on event
+
+} DRIVER_REGISTER_EVENT, *PDRIVER_REGISTER_EVENT;
+#pragma pack()
+
+/**
+* WILOCITY_IOCTL_SEND_WMI
+**/
+#pragma pack(1)
+/* used by IOCTL_SEND_WMI and IOCTL_RECEIVE_WMI */
+typedef struct SEND_RECEIVE_WMI_S
+{
+ enum WMI_COMMAND_ID uCmdId;
+ U16 uContext;
+ U08 uDevId;
+ U16 uBufLen;
+ U08 uBuf[EMPTY_ARRAY_SIZE];
+} SEND_RECEIVE_WMI, *PSEND_RECEIVE_WMI;
+#pragma pack()
+
+/**
+* WILOCITY_IOCTL_RECEIVE_WMI_NEW
+**/
+#pragma pack(1)
+typedef struct RECEIVE_WMI_NEW_S
+{
+ ULONG DeviceId; // The application identifier from type WMI_DEVICE_ID
+ U08 IsFilterAccordingToMyDeviceId; // Input param. If should pass all events (=FALSE) or only events with BCASD id or my id (=TRUE)
+ U08 Reserved[3];
+ U32 OutputBuffSize; // Output param. Number of bytes written to output buffer
+ union {
+ struct {
+ U16 StartSequenceNumber;
+ U16 StartRepCount;
+ };
+ U32 Counter; // Input param. 32 bit counter build from 16 bit FW sequence numbers and 16 bit driver's wrap counter
+ // To request first event, set counter to 0x0
+ };
+ U32 NumEventsToRead; // Input/Output param.
+ // Input: max number of events to read. Driver reads from the currently available events (does not block if requested more than available)
+ // Output: number of events written to output buffer
+} RECEIVE_WMI_NEW, *PRECEIVE_WMI_NEW;
+#pragma pack()
+
+/**
+* WILOCITY_IOCTL_SET_MODE_NEW
+* input buffer contains SET_MODE_CMD_INPUT
+* output buffer contains SET_MODE_CMD_OUTPUT
+* WILOCITY_IOCTL_GET_MODE_NEW
+* output buffer contains GET_MODE_CMD_OUTPUT
+**/
+typedef enum _DRIVER_MODE {
+ IOCTL_WBE_MODE,
+ IOCTL_WIFI_STA_MODE,
+ IOCTL_WIFI_SOFTAP_MODE,
+ IOCTL_CONCURRENT_MODE, // This mode is for a full concurrent implementation (not required mode switch between WBE/WIFI/SOFTAP)
+ IOCTL_SAFE_MODE, // A safe mode required for driver for protected flows like upgrade and crash dump...
+} DRIVER_MODE, *PDRIVER_MODE;
+
+#pragma pack(1)
+typedef struct _SET_MODE_CMD_INPUT
+{
+ DRIVER_MODE mode;
+} SET_MODE_CMD_INPUT, *PSET_MODE_CMD_INPUT;
+
+typedef struct _SET_MODE_CMD_OUTPUT
+{
+ BOOLEAN result;
+ DRIVER_MODE previousMode; // relevant only if result is TRUE
+} SET_MODE_CMD_OUTPUT, *PSET_MODE_CMD_OUTPUT;
+
+typedef struct _GET_MODE_CMD_OUTPUT
+{
+ DRIVER_MODE currentMode;
+} GET_MODE_CMD_OUTPUT, *PGET_MODE_CMD_OUTPUT;
+#pragma pack()
+
+
+
diff --git a/debug-tools/lib/inc/linux/wlct_cdev_shared.h b/debug-tools/lib/inc/linux/wlct_cdev_shared.h
new file mode 100644
index 0000000..c86aa06
--- /dev/null
+++ b/debug-tools/lib/inc/linux/wlct_cdev_shared.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __WLCT_CDEV_SHARED_H__
+#define __WLCT_CDEV_SHARED_H__
+
+#include "wlct_os.h"
+
+#define WLCT_IOCTL_MAGIC 0x59076456
+
+#define WLCT_IOCTL_FLAG_SET 0x1
+#define WLCT_IOCTL_FLAG_GET 0x2
+
+typedef struct {
+ uint32_t magic;
+ uint32_t len;
+ uint32_t flags;
+} wlct_cdev_ioctl_hdr_t;
+
+#endif
+
diff --git a/debug-tools/lib/inc/linux/wlct_procfs.h b/debug-tools/lib/inc/linux/wlct_procfs.h
new file mode 100644
index 0000000..4267a1e
--- /dev/null
+++ b/debug-tools/lib/inc/linux/wlct_procfs.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __WLCT_PROCFS_H__
+#define __WLCT_PROCFS_H__
+
+/******************************************************************
+ * Linux Proc FS related definitions
+ ******************************************************************/
+
+/* CDev file name*/
+#define WLCT_CDEV_NAME "wilocity"
+
+/* Root ProcFS dir name*/
+#define WLCT_PROCFS_DNAME "wilocity"
+
+/* ProcFS topology file name*/
+#define WLCT_PROCFS_TOPOLOGY_FNAME "topology"
+
+/* ProcFS topology INI file root section definitions */
+#define WLCT_TOPOLOGY_INI_ROOT_SEC "root"
+#define WLCT_TOPOLOGY_INI_ROOT_CDEVNAME_KEY "cdev"
+#define WLCT_TOPOLOGY_INI_ROOT_MAJOR_KEY "major"
+#define WLCT_TOPOLOGY_INI_ROOT_NOF_DEVS_KEY "nof_devs"
+
+/* ProcFS topology INI file device specific section definitions */
+#define WLCT_TOPOLOGY_INI_DEV_SEC_PREFIX "dev"
+#define WLCT_TOPOLOGY_INI_DEV_UID_KEY "uid"
+#define WLCT_TOPOLOGY_INI_DEV_BUS_NO_KEY "bus_no"
+#define WLCT_TOPOLOGY_INI_DEV_NAME_KEY "name"
+
+#endif /* __WLCT_PROCFS_H__ */
diff --git a/debug-tools/lib/inc/public.h b/debug-tools/lib/inc/public.h
new file mode 100644
index 0000000..19db8ff
--- /dev/null
+++ b/debug-tools/lib/inc/public.h
@@ -0,0 +1,279 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __PUBLIC_H
+#define __PUBLIC_H
+
+#ifdef _WINDOWS
+#include <initguid.h>
+#define INITGUID
+
+
+#define FSCTL_FILTER_BASE FILE_DEVICE_UNKNOWN
+
+#define _FILTER_CTL_CODE(_Function, _Method, _Access) \
+ CTL_CODE(FSCTL_FILTER_BASE, _Function, _Method, _Access)
+
+#define WCLT_SAMPLING_TO_FILE_IS_SUPPORTED
+#else
+typedef unsigned long ULONG;
+#define _FILTER_CTL_CODE(_Function, _Method, _Access) (_Function)
+
+typedef struct
+{
+ DWORD deviceUID;
+ DWORD commandID;
+ DWORD dataSize; /* inBufSize + outBufSize */
+ DWORD inBufOffset;
+ DWORD inBufSize;
+ DWORD outBufOffset;
+ DWORD outBufSize;
+} wlct_ioctl_hdr_t;
+
+static __INLINE BYTE *
+wlct_ioctl_data_in(wlct_ioctl_hdr_t *h)
+{
+ return ((BYTE*)&h[1]) + h->inBufOffset;
+}
+
+static __INLINE BYTE *
+wlct_ioctl_data_out(wlct_ioctl_hdr_t *h)
+{
+ return ((BYTE*)&h[1]) + h->outBufOffset;
+}
+#endif
+
+#ifdef _WINDOWS
+// Main Driver GUID
+DEFINE_GUID (GUID_DEVINTERFACE_wDrvEp, 0x23d1c0df,0x48f9,0x4c38,0x97,0xa2,0x4a,0xba,0x44,0x97,0x36,0xd1);
+// {23D1C0DF-48F9-4C38-97A2-4ABA449736D1}
+#endif
+
+//-----------------------------------------------------------------------------------
+// Old IOCTLS
+//-----------------------------------------------------------------------------------
+#define IOCTL_FILTER_GET_CFG \
+ _FILTER_CTL_CODE(0x202, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
+
+#define IOCTL_FILTER_SET_CFG \
+ _FILTER_CTL_CODE(0x203, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
+
+#define IOCTL_FILTER_CLOSE_LOCAL_DEVICE \
+ _FILTER_CTL_CODE(0x204, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
+
+#define IOCTL_FILTER_CLOSE_REMOTE_DEVICE \
+ _FILTER_CTL_CODE(0x205, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
+
+#define IOCTL_FILTER_OPEN_LOCAL_DEVICE \
+ _FILTER_CTL_CODE(0x206, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
+
+#define IOCTL_FILTER_OPEN_REMOTE_DEVICE \
+ _FILTER_CTL_CODE(0x207, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
+
+#define IOCTL_OPEN_USER_MODE_EVENT \
+ _FILTER_CTL_CODE(0x208, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
+
+#define IOCTL_CLOSE_USER_MODE_EVENT \
+ _FILTER_CTL_CODE(0x209, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
+
+#define IOCTL_FILTER_GET_INTERRUPT_MODE \
+ _FILTER_CTL_CODE(0x20A, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
+
+#define IOCTL_FILTER_SET_INTERRUPT_MODE \
+ _FILTER_CTL_CODE(0x20B, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
+
+#define IOCTL_INDIRECT_READ_OLD \
+ _FILTER_CTL_CODE(0x210, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
+
+#define IOCTL_INDIRECT_WRITE_OLD \
+ _FILTER_CTL_CODE(0x211, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
+
+#define IOCTL_INDIRECT_READ_BLOCK \
+ _FILTER_CTL_CODE(0x212, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
+
+#define IOCTL_INDIRECT_READ_REPEAT \
+ _FILTER_CTL_CODE(0x213, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
+
+#define IOCTL_INDIRECT_WRITE_BLOCK \
+ _FILTER_CTL_CODE(0x214, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
+
+
+//-----------------------------------------------------------------------------------
+// New IOCTLS
+//-----------------------------------------------------------------------------------
+#ifdef _WINDOWS
+#define WILOCITY_DEVICE_TYPE FILE_DEVICE_UNKNOWN
+#define WILOCITY_IOCTL(_code_) CTL_CODE (WILOCITY_DEVICE_TYPE, _code_, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
+#else
+#define WILOCITY_IOCTL(_code_) _FILTER_CTL_CODE (_code_, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
+#define ERROR_SUCCESS 0L
+#endif
+
+
+/* send WMI command to device.
+ The content of pBuf is the WMI message itself. It doesn't include WMI header
+ and Marlon MBOX header. */
+#define WILOCITY_IOCTL_SEND_WMI WILOCITY_IOCTL (0x800)
+
+/* receive WMI command from device.
+ upon return, pBuf contains the WMI message itself. It doesn't include WMI header
+ and Marlon MBOX header.
+ This IOCTL should return with error code if there is no pending Rx command */
+#define WILOCITY_IOCTL_RECEIVE_WMI WILOCITY_IOCTL (0x801)
+
+/* registration for indication of incoming WMI command.
+ Following that, client will use IOCTL_RECEIVE_WMI to get the incoming WMI command */
+#define WILOCITY_IOCTL_REGISTER_WMI_RX_EVENT WILOCITY_IOCTL (0x803)
+
+/* registration for user mode evnts from Driver. all events besides WMI RX Events */
+#define WILOCITY_IOCTL_REGISTER_DEVICE_EVENT WILOCITY_IOCTL (0x804)
+#define WILOCITY_IOCTL_GET_DEVICE_EVENT WILOCITY_IOCTL (0x805)
+#define WILOCITY_IOCTL_REGISTER_EVENT WILOCITY_IOCTL (0x850)
+
+/* Special IOCTLS */
+#define WILOCITY_IOCTL_DEVICE_SW_RESET WILOCITY_IOCTL (0x807)
+
+/* MiniPort driver only */
+#define WILOCITY_IOCTL_DRIVER_LOG_LEVELS_CFG WILOCITY_IOCTL(0x900)
+
+
+
+//-----------------------------------------------------------------------------------
+// Other Definitions
+//-----------------------------------------------------------------------------------
+
+#define BASE_ADDRESS 0x880000
+
+// used to transfer address to the driver (input parameter)
+// or value from the driver (output parameter)
+// for example read register
+typedef struct _FILTER_1_ULONG_PARAM
+{
+ DWORD param;
+
+} FILTER_1_ULONG_PARAM, *PFILTER_1_ULONG_PARAM;
+
+// used to transfer address and value to the driver (input parameter)
+// for example write register
+typedef struct _FILTER_2_ULONG_PARAMS
+{
+ DWORD param1;
+ DWORD param2;
+
+} FILTER_2_ULONG_PARAM, *PFILTER_2_ULONG_PARAM;
+
+#ifdef _WINDOWS
+#pragma warning( disable : 4200 ) //suppress warning
+#endif
+typedef struct _FILTER_WRITE_BLOCK
+{
+ DWORD address;
+ DWORD size; // of 32 bits
+ DWORD buffer[0];
+
+} FILTER_WRITE_BLOCK, *PFILTER_WRITE_BLOCK;
+
+typedef struct _FILTER_INTERRUPT_MODE
+{
+ BYTE interruptMode; // 0 - Interrupt, 1 - MSI enable
+
+} FILTER_INTERRUPT_MODE, *PFILTER_INTERRUPT_MODE;
+
+
+//
+// Structure to go with IOCTL_FILTE_OPEN_DEVICE.
+//
+typedef struct _FILTER_MAP_DEVICE
+{
+ BYTE *userCRSAddress;
+ size_t userCRSSize;
+
+} FILTER_MAP_DEVICE, *PFILTER_MAP_DEVICE;
+
+
+typedef struct _FILTER_GET_CFG
+{
+ DWORD offset;
+ DWORD value;
+
+} FILTER_GET_CFG, *PFILTER_GET_CFG;
+
+
+typedef struct _FILTER_SET_CFG
+{
+ DWORD offset;
+ DWORD value;
+
+} FILTER_SET_CFG, *PFILTER_SET_CFG;
+
+
+typedef struct _FILTER_OPEN_DEVICE
+{
+
+ DWORD reserved;
+} FILTER_OPEN_DEVICE, *PFILTER_OPEN_DEVICE;
+
+enum{
+ PCI,
+ CONF
+};
+
+
+
+/**
+* WILOCITY_IOCTL_DRIVER_LOG_LEVELS_CFG
+**/
+enum {WILO_DRV_NUM_LOG_COMPS = 32};
+
+typedef struct _DRIVER_LOGS_CFG
+{
+ ULONG logModulesEnableMsk;
+ ULONG logModuleLevelsMsk[WILO_DRV_NUM_LOG_COMPS];
+} DRIVER_LOGS_CFG, *P_DRIVER_LOGS_CFG;
+
+#ifdef _WINDOWS
+typedef struct _EVENT_HANDLE_64BIT
+{
+ ULONG DeviceId;
+ int EventId;
+ INT_PTR hEvent_l;
+ INT_PTR hEvent_h;
+
+} EVENT_HANDLE_64BIT, *PEVENT_HANDLE_64BIT;
+
+typedef struct _EVENT_HANDLE_32BIT
+{
+ ULONG DeviceId;
+ int EventId;
+ INT_PTR hEvent;
+} EVENT_HANDLE_32BIT, *PEVENT_HANDLE_32BIT;
+#endif //_WINDOWS
+
+#endif
+
diff --git a/debug-tools/lib/inc/wlct_os.h b/debug-tools/lib/inc/wlct_os.h
new file mode 100644
index 0000000..3c21ae0
--- /dev/null
+++ b/debug-tools/lib/inc/wlct_os.h
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#ifdef _WINDOWS
+
+#include <windows.h>
+#include <atlbase.h>
+#include <atlstr.h>
+#include <assert.h>
+
+typedef unsigned __int8 u_int8_t;
+typedef unsigned __int16 u_int16_t;
+typedef unsigned __int32 u_int32_t;
+typedef unsigned __int64 u_int64_t;
+#if (defined(_MSC_VER) && (_MSC_VER < 1900))
+typedef __int8 int8_t;
+#endif
+typedef __int16 int16_t;
+typedef __int32 int32_t;
+typedef __int64 int64_t;
+typedef unsigned __int8 uint8_t;
+typedef unsigned __int16 uint16_t;
+typedef unsigned __int32 uint32_t;
+typedef unsigned __int64 uint64_t;
+
+typedef DWORD wlct_os_err_t;
+
+#define WLCT_OS_ERROR_SUCCESS ERROR_SUCCESS
+#define WLCT_OS_ERROR_NOT_SUPPORTED ERROR_NOT_SUPPORTED
+#define WLCT_OS_ERROR_CALL_NOT_IMPLEMENTED ERROR_CALL_NOT_IMPLEMENTED
+#define WLCT_OS_ERROR_GEN_FAILURE ERROR_GEN_FAILURE
+#define WLCT_OS_ERROR_NOT_ENOUGH_MEMORY ERROR_NOT_ENOUGH_MEMORY
+#define WLCT_OS_ERROR_NO_SUCH_ENTRY ERROR_FILE_NOT_FOUND
+#define WLCT_OS_ERROR_OPEN_FAILED ERROR_OPEN_FAILED
+
+#define WLCT_ASSERT assert
+
+#define __TRY __try
+
+#define __EXCEPT __except
+
+#define sleep_ms Sleep
+
+#define WlctGetLastError GetLastError
+
+#else
+
+#include <stdint.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include <string>
+
+#define WLCT_ASSERT assert
+
+#define __INLINE __inline
+
+typedef uint8_t BYTE;
+typedef uint16_t WORD;
+typedef uint32_t DWORD;
+
+typedef unsigned char UCHAR;
+typedef unsigned int UINT;
+typedef char CHAR;
+typedef long LONG;
+typedef unsigned short USHORT;
+typedef unsigned long ULONG;
+typedef ULONG* ULONG_PTR;
+
+typedef char TCHAR;
+
+typedef uint8_t u_int8_t;
+typedef uint16_t u_int16_t;
+typedef uint32_t u_int32_t;
+typedef uint64_t u_int64_t;
+
+typedef const TCHAR *LPCTSTR;
+typedef TCHAR *LPTSTR;
+typedef CHAR *LPSTR;
+typedef const CHAR *LPCSTR;
+
+typedef DWORD HANDLE;
+
+typedef int BOOL;
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#include <errno.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <strings.h>
+
+typedef int wlct_os_err_t;
+
+#define WLCT_OS_ERROR_SUCCESS 0
+#define WLCT_OS_ERROR_NOT_SUPPORTED -ENOTSUP
+#define WLCT_OS_ERROR_CALL_NOT_IMPLEMENTED -ENOSYS
+#define WLCT_OS_ERROR_GEN_FAILURE -EINVAL
+#define WLCT_OS_ERROR_NOT_ENOUGH_MEMORY -ENOMEM
+#define WLCT_OS_ERROR_NO_SUCH_ENTRY -ENOENT
+#define WLCT_OS_ERROR_OPEN_FAILED -EBADF
+
+#define _T(x) (x)
+
+#define __TRY if (1)
+#define __EXCEPT(ignore) else if (0)
+
+#define WLCT_MSEC_IN_SEC 1000
+
+#define sleep_ms(msec) usleep(msec * WLCT_MSEC_IN_SEC)
+
+#define USES_CONVERSION
+
+#define T2A(x) (x)
+
+#define _tcscpy_s(x, y, z) snprintf((x), (y), "%s", (z))
+#define _tcslen strlen
+#define _stprintf_s snprintf
+#define _snprintf snprintf
+//#define sprintf_s sprintf
+//#define _stprintf sprintf
+#define sscanf_s sscanf
+#define _tcstok_s strtok_r
+#define _tcsstr strstr
+#define _tcsicmp strcasecmp
+#define _vsntprintf vsnprintf
+#define _tfopen fopen
+
+#define WlctGetLastError() errno
+
+#endif
+
+#include "StlChar.h"
+
+
+#define WLCT_UNREFERENCED_PARAM(x) ((x) = (x))
diff --git a/debug-tools/lib/inc/wmi.h b/debug-tools/lib/inc/wmi.h
new file mode 100644
index 0000000..9896a3a
--- /dev/null
+++ b/debug-tools/lib/inc/wmi.h
@@ -0,0 +1,1184 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef MARLON_WMI_H_
+#define MARLON_WMI_H_
+
+#include "basic_types.h"
+
+#if defined(_MSC_VER) // Microsoft
+#pragma pack (push, marlon_wmi, 1) /* set alignment to 1 byte boundary */
+#endif
+
+
+
+/**
+ * **********************************************************************************************************************************
+ * General
+ * **********************************************************************************************************************************
+ */
+
+#define WMI_CONTROL_MSG_MAX_LEN 256
+#define WMI_MAC_LEN 6 /* length of mac in bytes */
+#define WMI_PROX_RANGE_NUM 3
+
+
+ enum wmi_phy_capability_e {
+ WMI_11A_CAPABILITY = 1,
+ WMI_11G_CAPABILITY = 2,
+ WMI_11AG_CAPABILITY = 3,
+ WMI_11NA_CAPABILITY = 4,
+ WMI_11NG_CAPABILITY = 5,
+ WMI_11NAG_CAPABILITY = 6,
+ WMI_11AD_CAPABILITY = 7,
+ // END CAPABILITY
+ WMI_11N_CAPABILITY_OFFSET = (WMI_11NA_CAPABILITY - WMI_11A_CAPABILITY),
+} ;
+
+/**
+ * Marlon Mailbox interface
+ * used for commands and events
+ */
+#define WMI_GET_DEVICE_ID(info1) ((info1) & 0xF)
+typedef struct {
+ U16 padding;
+ U16 commandId;
+/*
+ * info1 - 16 bits
+ * b03:b00 - id
+ * b15:b04 - unused
+ */
+ U16 info1;
+ U16 reserved; /* For alignment */
+} WMI_CMD_HDR;
+
+
+
+/**
+ * **********************************************************************************************************************************
+ * WMI Commands
+ * **********************************************************************************************************************************
+ */
+
+/*
+ * List of Commands
+ */
+typedef enum {
+ WMI_CONNECT_CMDID = 0x0001,
+ WMI_DISCONNECT_CMDID = 0x0003,
+ WMI_START_SCAN_CMDID = 0x0007,
+ WMI_SET_BSS_FILTER_CMDID = 0x0009,
+ WMI_SET_PROBED_SSID_CMDID = 0x000a,
+ WMI_SET_LISTEN_INT_CMDID = 0x000b,
+ WMI_BCON_CTRL_CMDID = 0x000f,
+ WMI_ADD_CIPHER_KEY_CMDID = 0x0016,
+ WMI_DELETE_CIPHER_KEY_CMDID = 0x0017,
+ WMI_SET_APPIE_CMDID = 0x003f,
+ WMI_GET_APPIE_CMDID = 0x0040,
+ WMI_SET_WSC_STATUS_CMDID = 0x0041,
+ WMI_PXMT_RANGE_CFG_CMDID = 0x0042,
+ WMI_PXMT_SNR2_RANGE_CFG_CMDID = 0x0043,
+ WMI_FAST_MEM_ACC_MODE_CMDID = 0x0300,
+ WMI_MEM_READ_CMDID = 0x0800,
+ WMI_MEM_WR_CMDID = 0x0801,
+ WMI_ECHO_CMDID = 0x0803,
+ WMI_DEEP_ECHO_CMDID = 0x0804,
+ WMI_CONFIG_MAC_CMDID = 0x0805,
+ WMI_CONFIG_PHY_DEBUG_CMDID = 0x0806,
+ WMI_ADD_STATION_CMDID = 0x0807,
+ WMI_ADD_DEBUG_TX_PCKT_CMDID = 0x0808,
+ WMI_PHY_GET_STATISTICS_CMDID = 0x0809,
+ WMI_FS_TUNE_CMDID = 0x080A,
+ WMI_CORR_MEASURE_CMDID = 0x080B,
+ WMI_TEMP_SENSE_CMDID = 0x080E,
+ WMI_DC_CALIB_CMDID = 0x080F,
+ WMI_SEND_TONE_CMDID = 0x0810,
+ WMI_IQ_TX_CALIB_CMDID = 0x0811,
+ WMI_IQ_RX_CALIB_CMDID = 0x0812,
+ WMI_SET_UCODE_IDLE_CMDID = 0x0813,
+ WMI_SET_WORK_MODE_CMDID = 0x0815,
+ WMI_LO_LEAKAGE_CALIB_CMDID = 0x0816,
+ WMI_MARLON_R_ACTIVATE_CMDID = 0x0817,
+ WMI_MARLON_R_READ_CMDID = 0x0818,
+ WMI_MARLON_R_WRITE_CMDID = 0x0819,
+ WMI_MARLON_R_TXRX_SEL_CMDID = 0x081A,
+ MAC_IO_STATIC_PARAMS_CMDID = 0x081B,
+ MAC_IO_DYNAMIC_PARAMS_CMDID = 0x081C,
+ WMI_SILENT_RSSI_CALIB_CMDID = 0x081D,
+ WMI_CFG_RX_CHAIN_CMDID = 0x0820,
+ WMI_VRING_CFG_CMDID = 0x0821,
+ WMI_RX_ON_CMDID = 0x0822,
+ WMI_VRING_BA_EN_CMDID = 0x0823,
+ WMI_VRING_BA_DIS_CMDID = 0x0824,
+ WMI_RCP_ADDBA_RESP_CMDID = 0x0825,
+ WMI_RCP_DELBA_CMDID = 0x0826,
+ WMI_SET_SSID_CMDID = 0x0827,
+ WMI_GET_SSID_CMDID = 0x0828,
+ WMI_SET_PCP_CHANNEL_CMDID = 0x0829,
+ WMI_GET_PCP_CHANNEL_CMDID = 0x082a,
+ WMI_SW_TX_REQ_CMDID = 0x082b,
+ WMI_READ_MAC_RXQ_CMDID = 0x0830,
+ WMI_READ_MAC_TXQ_CMDID = 0x0831,
+ WMI_WRITE_MAC_RXQ_CMDID = 0x0832,
+ WMI_WRITE_MAC_TXQ_CMDID = 0x0833,
+ WMI_WRITE_MAC_XQ_FIELD_CMDID = 0x0834,
+ WMI_MLME_PUSH_CMDID = 0x0835,
+ WMI_BEAMFORMING_MGMT_CMDID = 0x0836,
+ WMI_BF_TXSS_MGMT_CMDID = 0x0837,
+ WMI_BF_SM_MGMT_CMDID = 0x0838,
+ WMI_BF_RXSS_MGMT_CMDID = 0x0839,
+ WMI_SET_SECTORS_CMDID = 0x0849,
+ WMI_MAINTAIN_PAUSE_CMDID = 0x0850,
+ WMI_MAINTAIN_RESUME_CMDID = 0x0851,
+ WMI_RS_MGMT_CMDID = 0x0852,
+ WMI_RF_MGMT_CMDID = 0x0853,
+ /* Performance monitoring commands */
+ WMI_BF_CTRL_CMDID = 0x0862,
+ WMI_NOTIFY_REQ_CMDID = 0x0863,
+ WMI_GET_STATUS_CMDID = 0x0864,
+ WMI_UNIT_TEST_CMDID = 0x0900,
+ WMI_HICCUP_CMDID = 0x0901,
+ WMI_FLASH_READ_CMDID = 0x0902,
+ WMI_FLASH_WRITE_CMDID = 0x0903,
+ WMI_SECURITY_UNIT_TEST_CMDID = 0x0904,
+
+ WMI_SET_MAC_ADDRESS_CMDID = 0xF003,
+ WMI_ABORT_SCAN_CMDID = 0xF007,
+ WMI_SET_PMK_CMDID = 0xF028,
+
+ WMI_SET_PROMISCUOUS_MODE_CMDID = 0xF041,
+ WMI_GET_PMK_CMDID = 0xF048,
+ WMI_SET_PASSPHRASE_CMDID = 0xF049,
+ WMI_SEND_ASSOC_RES_CMDID = 0xF04a,
+ WMI_SET_ASSOC_REQ_RELAY_CMDID = 0xF04b,
+ WMI_EAPOL_TX_CMDID = 0xF04c,
+ WMI_MAC_ADDR_REQ_CMDID = 0xF04d,
+ WMI_FW_VER_CMDID = 0xF04e,
+} WMI_COMMAND_ID;
+
+
+
+/*******************************************************************************************************************
+ * Commands data structures
+ *******************************************************************************************************************/
+
+/*
+ * Frame Types
+ */
+ enum wmi_mgmt_frame_type_e {
+ WMI_FRAME_BEACON = 0,
+ WMI_FRAME_PROBE_REQ,
+ WMI_FRAME_PROBE_RESP,
+ WMI_FRAME_ASSOC_REQ,
+ WMI_FRAME_ASSOC_RESP,
+ WMI_NUM_MGMT_FRAME
+} ;
+
+/*
+ * WMI_CONNECT_CMDID
+ */
+ enum wmi_network_type_e {
+ INFRA_NETWORK = 0x01,
+ ADHOC_NETWORK = 0x02,
+ ADHOC_CREATOR = 0x04,
+ AP_NETWORK = 0x10,
+ P2P_NETWORK = 0x20,
+ WBE_NETWORK = 0x40,
+} ;
+
+ enum wmi_dot11_auth_mode_e {
+ OPEN_AUTH = 0x01,
+ SHARED_AUTH = 0x02,
+ LEAP_AUTH = 0x04,
+ WSC_AUTH = 0x08
+} ;
+
+ enum wmi_auth_mode_e {
+ NONE_AUTH = 0x01,
+ WPA_AUTH = 0x02,
+ WPA2_AUTH = 0x04,
+ WPA_PSK_AUTH = 0x08,
+ WPA2_PSK_AUTH = 0x10,
+ WPA_AUTH_CCKM = 0x20,
+ WPA2_AUTH_CCKM = 0x40,
+} ;
+
+ enum wmi_crypto_type_e {
+ NONE_CRYPT = 0x01,
+ WEP_CRYPT = 0x02,
+ TKIP_CRYPT = 0x04,
+ AES_CRYPT = 0x08,
+ AES_GCMP_CRYPT = 0x20
+} ;
+
+
+ enum wmi_connect_ctrl_flag_bits_e {
+ CONNECT_ASSOC_POLICY_USER = 0x0001,
+ CONNECT_SEND_REASSOC = 0x0002,
+ CONNECT_IGNORE_WPAx_GROUP_CIPHER = 0x0004,
+ CONNECT_PROFILE_MATCH_DONE = 0x0008,
+ CONNECT_IGNORE_AAC_BEACON = 0x0010,
+ CONNECT_CSA_FOLLOW_BSS = 0x0020,
+ CONNECT_DO_WPA_OFFLOAD = 0x0040,
+ CONNECT_DO_NOT_DEAUTH = 0x0080,
+} ;
+
+#define WMI_MAX_SSID_LEN 32
+
+ typedef PREPACK struct {
+ U08 networkType;
+ U08 dot11AuthMode;
+ U08 authMode;
+ U08 pairwiseCryptoType;
+ U08 pairwiseCryptoLen;
+ U08 groupCryptoType;
+ U08 groupCryptoLen;
+ U08 ssidLength;
+ U08 ssid[WMI_MAX_SSID_LEN];
+ U16 channel;
+ U08 bssid[WMI_MAC_LEN];
+ U32 ctrl_flags;
+ U08 destMacAddr[WMI_MAC_LEN];
+ U16 reserved;
+} POSTPACK WMI_CONNECT_CMD;
+
+
+/*
+ * WMI_RECONNECT_CMDID
+ */
+ typedef PREPACK struct {
+ U16 channel; /* hint */
+ U08 bssid[WMI_MAC_LEN]; /* mandatory if set */
+} POSTPACK WMI_RECONNECT_CMD;
+
+
+/*
+ * WMI_SET_PMK_CMDID
+ */
+
+#define WMI_MIN_KEY_INDEX 0
+#define WMI_MAX_KEY_INDEX 3
+#define WMI_MAX_KEY_LEN 32
+#define WMI_PASSPHRASE_LEN 64
+#define WMI_PMK_LEN 32
+
+typedef PREPACK struct {
+ U08 pmk[WMI_PMK_LEN];
+} POSTPACK WMI_SET_PMK_CMD;
+
+
+/*
+ * WMI_SET_PASSPHRASE_CMDID
+ */
+ typedef PREPACK struct {
+ U08 ssid[WMI_MAX_SSID_LEN];
+ U08 passphrase[WMI_PASSPHRASE_LEN];
+ U08 ssid_len;
+ U08 passphrase_len;
+} POSTPACK WMI_SET_PASSPHRASE_CMD;
+
+/*
+ * WMI_ADD_CIPHER_KEY_CMDID
+ */
+enum wmi_connect_key_usage_e {
+ PAIRWISE_USAGE = 0x00,
+ GROUP_USAGE = 0x01,
+ TX_USAGE = 0x02, /* default Tx Key - Static WEP only */
+} ;
+
+ typedef PREPACK struct {
+ U08 keyIndex;
+ U08 keyType;
+ U08 keyUsage; /* wmi_connect_key_usage_e */
+ U08 keyLength;
+ U08 keyRSC[8]; /* key replay sequence counter */
+ U08 key[WMI_MAX_KEY_LEN];
+ U08 key_op_ctrl; /* Additional Key Control information */
+ U08 key_macaddr[WMI_MAC_LEN];
+} POSTPACK WMI_ADD_CIPHER_KEY_CMD;
+
+/*
+ * WMI_DELETE_CIPHER_KEY_CMDID
+ */
+ typedef PREPACK struct {
+ U08 keyIndex;
+ U08 key_macaddr[WMI_MAC_LEN];
+} POSTPACK WMI_DELETE_CIPHER_KEY_CMD;
+
+
+/*
+ * WMI_START_SCAN_CMD
+ */
+ enum wmi_scan_type_e {
+ WMI_LONG_SCAN = 0,
+ WMI_SHORT_SCAN = 1,
+ WMI_PBC_SCAN = 2
+} ;
+
+ typedef PREPACK struct {
+ S32 forceFgScan;
+ S32 isLegacy; /* For Legacy Cisco AP compatibility */
+ U32 homeDwellTime; /* Maximum duration in the home channel(milliseconds) */
+ U32 forceScanInterval; /* Time interval between scans (milliseconds)*/
+ U08 scanType; /* wmi_scan_type_e */
+ U08 numChannels; /* how many channels follow */
+ U16 channelList[4]; /* channels in Mhz */
+} POSTPACK WMI_START_SCAN_CMD;
+
+/*
+ * WMI_SET_PROBED_SSID_CMDID
+ */
+#define MAX_PROBED_SSID_INDEX 15
+
+ enum wmi_ssid_flag_e {
+ DISABLE_SSID_FLAG = 0, /* disables entry */
+ SPECIFIC_SSID_FLAG = 0x01, /* probes specified ssid */
+ ANY_SSID_FLAG = 0x02, /* probes for any ssid */
+} ;
+
+ typedef PREPACK struct {
+ U08 entryIndex; /* 0 to MAX_PROBED_SSID_INDEX */
+ U08 flag; /* wmi_ssid_flag_e */
+ U08 ssidLength;
+ U08 ssid[WMI_MAX_SSID_LEN];
+} POSTPACK WMI_PROBED_SSID_CMD;
+
+
+/*
+ * Add Application specified IE to a management frame
+ */
+#define WMI_MAX_IE_LEN 255
+
+#ifdef _WINDOWS
+#pragma warning( disable : 4200 ) //suppress warning
+#endif
+typedef PREPACK struct {
+ U08 mgmtFrmType; /* one of wmi_mgmt_frame_type_e */
+ U08 ieLen; /* Length of the IE that should be added to the MGMT frame */
+ U08 ieInfo[EMPTY_ARRAY_SIZE];
+} POSTPACK WMI_SET_APPIE_CMD;
+
+
+typedef PREPACK struct {
+ U08 destMacAddr[WMI_MAC_LEN];
+ U16 range;
+} POSTPACK WMI_PXMT_RANGE_CFG_CMD;
+
+typedef PREPACK struct {
+ S08 snr2range_arr[WMI_PROX_RANGE_NUM-1];
+} POSTPACK WMI_PXMT_SNR2_RANGE_CFG_CMD;
+
+/*
+ * WMI_RF_MGMT_CMDID
+ */
+typedef enum wmi_rf_mgmt_type_e {
+ WMI_RF_MGMT_W_DISABLE = 0x0,
+ WMI_RF_MGMT_W_ENABLE = 0x1,
+ WMI_RF_MGMT_GET_STATUS = 0x2
+} WMI_RF_MGMT_TYPE;
+
+ typedef PREPACK struct {
+ U32 rf_mgmt_type;
+} POSTPACK WMI_RF_MGMT_CMD;
+
+
+/*
+ * WMI_SET_SSID_CMDID
+ */
+ typedef PREPACK struct {
+ U32 ssid_len;
+ U08 ssid[WMI_MAX_SSID_LEN];
+} POSTPACK WMI_SET_SSID_CMD;
+
+/*
+ * WMI_SET_PCP_CHANNEL_CMDID
+ */
+ typedef PREPACK struct {
+ U08 channel_index;
+ U08 reserved[3];
+} POSTPACK WMI_SET_PCP_CHANNEL_CMD;
+
+
+/*
+ * WMI_BCON_CTRL_CMDID
+ */
+ typedef PREPACK struct {
+ U16 bcon_interval;
+ U16 frag_num;
+ U32 ss_mask_low;
+ U32 ss_mask_high;
+ U16 network_type;
+ U08 disable_sec_offload;
+ U08 disable_sec;
+} POSTPACK WMI_BCON_CTRL_CMD;
+
+/*
+ * WMI_SW_TX_REQ_CMDID
+ */
+typedef PREPACK struct {
+ U08 destMacAddr[WMI_MAC_LEN];
+ U16 length;
+} POSTPACK WMI_SW_TX_REQ_CMD;
+
+/*
+ * WMI_VRING_CFG_CMDID
+ */
+
+ typedef PREPACK struct {
+ U32 ring_mem_base_l;
+ U16 ring_mem_base_h;
+ U16 reserved0;
+ U16 ring_size;
+ U16 max_mpdu_size;
+} POSTPACK wmi_sw_ring_cfg_s;
+
+
+
+enum wmi_vring_cfg_schd_params_priority_e {
+ REGULAR = 0x0,
+ HIGH = 0x1,
+};
+
+typedef PREPACK struct {
+ U16 priority;
+ U16 timeslot_us;
+} POSTPACK wmi_vring_cfg_schd_s;
+
+enum wmi_vring_cfg_encap_trans_type_e {
+ ENC_TYPE_802_3 = 0x0,
+ ENC_TYPE_NATIVE_WIFI = 0x1
+};
+
+enum wmi_vring_cfg_ds_cfg_e {
+ DS_PBSS_MODE = 0x0,
+ DS_STA_MODE = 0x1,
+ DS_AP_MODE = 0x2,
+ DS_ADDR4_MODE = 0x3
+};
+
+enum wmi_vring_cfg_nwifi_ds_trans_type_e {
+ NWIFI_TX_NO_TRANS_MODE = 0x0,
+ NWIFI_TX_AP2PBSS_TRANS_MODE = 0x1,
+ NWIFI_TX_STA2PBSS_TRANS_MODE = 0x2
+};
+
+typedef PREPACK struct {
+ wmi_sw_ring_cfg_s tx_sw_ring;
+ U08 ringid; /* 0-23 vrings */
+
+ #define CIDXTID_CID_POS 0
+ #define CIDXTID_CID_LEN 4
+ #define CIDXTID_CID_MSK 0xF
+ #define CIDXTID_TID_POS 4
+ #define CIDXTID_TID_LEN 4
+ #define CIDXTID_TID_MSK 0xF0
+ U08 cidxtid_byte;
+
+ U08 encap_trans_type;
+ U08 ds_cfg; /* 802.3 DS cfg */
+ U08 nwifi_ds_trans_type;
+
+ #define VRING_CFG_MAC_CTRL_LIFETIME_EN_POS 0
+ #define VRING_CFG_MAC_CTRL_LIFETIME_EN_LEN 1
+ #define VRING_CFG_MAC_CTRL_LIFETIME_EN_MSK 0x1
+ #define VRING_CFG_MAC_CTRL_AGGR_EN_POS 1
+ #define VRING_CFG_MAC_CTRL_AGGR_EN_LEN 1
+ #define VRING_CFG_MAC_CTRL_AGGR_EN_MSK 0x2
+ U08 mac_ctrl_byte;
+
+ #define VRING_CFG_TO_RESOLUTION_VALUE_POS 0
+ #define VRING_CFG_TO_RESOLUTION_VALUE_LEN 6
+ #define VRING_CFG_TO_RESOLUTION_VALUE_MSK 0x3F
+ U08 to_resolution_byte;
+ U08 agg_max_wsize;
+ wmi_vring_cfg_schd_s schd_params;
+} POSTPACK wmi_vring_cfg_s;
+
+
+enum wmi_vring_cfg_cmd_action_e {
+ ADD_VRING = 0x0,
+ MODIFY_VRING = 0x1,
+ DELETE_VRING = 0x2
+};
+
+ typedef PREPACK struct {
+ U32 action;
+ wmi_vring_cfg_s vring_cfg;
+} POSTPACK WMI_VRING_CFG_CMD;
+
+
+/*
+ * WMI_VRING_BA_EN_CMDID
+ */
+ typedef PREPACK struct {
+ U08 ringid;
+ U08 agg_max_wsize;
+ U16 ba_timeout;
+} POSTPACK WMI_VRING_BA_EN_CMD;
+
+
+/*
+ * WMI_VRING_BA_DIS_CMDID
+ */
+ typedef PREPACK struct {
+ U08 ringid;
+ U08 reserved0;
+ U16 reason;
+} POSTPACK WMI_VRING_BA_DIS_CMD;
+
+/*
+ * WMI_START_SCAN_CMDID
+ */
+enum wmi_scan_ctrl_cmd_scan_mode_e {
+ ACTIVE_SCAN = 0x0,
+ PASSIV_SCAN = 0x1,
+ NO_SCAN = 0x2
+};
+
+ typedef PREPACK struct {
+ U16 in_channel_interval;
+ U16 num_of_channels;
+ U16 channel_list;
+ U16 scan_param;
+ U32 scan_mode;
+} POSTPACK WMI_SCAN_CTRL_CMD;
+
+/*
+ * WMI_NOTIFY_REQ_CMDID
+ */
+ typedef PREPACK struct {
+ U32 cid;
+ U32 interval_usec;
+} POSTPACK WMI_NOTIFY_REQ_CMD;
+
+/*
+ * WMI_CFG_RX_CHAIN_CMDID
+ */
+enum wmi_sniffer_cfg_mode_e {
+ SNIFFER_OFF = 0x0,
+ SNIFFER_ON = 0x1
+};
+enum wmi_sniffer_cfg_phy_info_mode_e {
+ SNIFFER_PHY_INFO_DISABLED = 0x0,
+ SNIFFER_PHY_INFO_ENABLED = 0x1
+};
+enum wmi_sniffer_cfg_phy_support_e {
+ SNIFFER_CP = 0x0,
+ SNIFFER_DP = 0x1,
+ SNIFFER_BOTH_PHYS = 0x2
+};
+ typedef PREPACK struct {
+ U32 mode;
+ U32 phy_info_mode;
+ U32 phy_support;
+ U32 channel_id;
+} POSTPACK wmi_sniffer_cfg_s;
+
+enum wmi_cfg_rx_chain_cmd_action_e {
+ ADD_RX_CHAIN = 0x0,
+ DELETE_RX_CHAIN = 0x1
+};
+enum wmi_cfg_rx_chain_cmd_decap_trans_type_e {
+ DECAP_TYPE_802_3 = 0x0,
+ DECAP_TYPE_NATIVE_WIFI = 0x1
+};
+enum wmi_cfg_rx_chain_cmd_nwifi_ds_trans_type_e {
+ NWIFI_RX_NO_TRANS_MODE = 0x0,
+ NWIFI_RX_PBSS2AP_TRANS_MODE = 0x1,
+ NWIFI_RX_PBSS2STA_TRANS_MODE = 0x2
+};
+
+ typedef PREPACK struct {
+ U32 action;
+ wmi_sw_ring_cfg_s rx_sw_ring;
+ U08 mid;
+ U08 decap_trans_type;
+
+ #define CFG_RX_CHAIN_CMD_L2_802_3_OFFLOAD_CTRL_VLAN_TAG_INSERTION_POS 0
+ #define CFG_RX_CHAIN_CMD_L2_802_3_OFFLOAD_CTRL_VLAN_TAG_INSERTION_LEN 1
+ #define CFG_RX_CHAIN_CMD_L2_802_3_OFFLOAD_CTRL_VLAN_TAG_INSERTION_MSK 0x1
+ U08 l2_802_3_offload_ctrl_byte;
+
+ #define CFG_RX_CHAIN_CMD_L2_NWIFI_OFFLOAD_CTRL_REMOVE_QOS_POS 0
+ #define CFG_RX_CHAIN_CMD_L2_NWIFI_OFFLOAD_CTRL_REMOVE_QOS_LEN 1
+ #define CFG_RX_CHAIN_CMD_L2_NWIFI_OFFLOAD_CTRL_REMOVE_QOS_MSK 0x1
+ #define CFG_RX_CHAIN_CMD_L2_NWIFI_OFFLOAD_CTRL_REMOVE_PN_POS 1
+ #define CFG_RX_CHAIN_CMD_L2_NWIFI_OFFLOAD_CTRL_REMOVE_PN_LEN 1
+ #define CFG_RX_CHAIN_CMD_L2_NWIFI_OFFLOAD_CTRL_REMOVE_PN_MSK 0x2
+ U08 l2_nwifi_offload_ctrl_byte;
+
+ U08 vlan_id;
+ U08 nwifi_ds_trans_type;
+
+ #define CFG_RX_CHAIN_CMD_L3_L4_CTRL_IPV4_CHECKSUM_EN_POS 0
+ #define CFG_RX_CHAIN_CMD_L3_L4_CTRL_IPV4_CHECKSUM_EN_LEN 1
+ #define CFG_RX_CHAIN_CMD_L3_L4_CTRL_IPV4_CHECKSUM_EN_MSK 0x1
+ #define CFG_RX_CHAIN_CMD_L3_L4_CTRL_TCPIP_CHECKSUM_EN_POS 1
+ #define CFG_RX_CHAIN_CMD_L3_L4_CTRL_TCPIP_CHECKSUM_EN_LEN 1
+ #define CFG_RX_CHAIN_CMD_L3_L4_CTRL_TCPIP_CHECKSUM_EN_MSK 0x2
+ U08 l3_l4_ctrl_byte;
+
+ #define CFG_RX_CHAIN_CMD_RING_CTRL_OVERRIDE_PREFETCH_THRSH_POS 0
+ #define CFG_RX_CHAIN_CMD_RING_CTRL_OVERRIDE_PREFETCH_THRSH_LEN 1
+ #define CFG_RX_CHAIN_CMD_RING_CTRL_OVERRIDE_PREFETCH_THRSH_MSK 0x1
+ #define CFG_RX_CHAIN_CMD_RING_CTRL_OVERRIDE_WB_THRSH_POS 1
+ #define CFG_RX_CHAIN_CMD_RING_CTRL_OVERRIDE_WB_THRSH_LEN 1
+ #define CFG_RX_CHAIN_CMD_RING_CTRL_OVERRIDE_WB_THRSH_MSK 0x2
+ #define CFG_RX_CHAIN_CMD_RING_CTRL_OVERRIDE_ITR_THRSH_POS 2
+ #define CFG_RX_CHAIN_CMD_RING_CTRL_OVERRIDE_ITR_THRSH_LEN 1
+ #define CFG_RX_CHAIN_CMD_RING_CTRL_OVERRIDE_ITR_THRSH_MSK 0x4
+ #define CFG_RX_CHAIN_CMD_RING_CTRL_OVERRIDE_HOST_THRSH_POS 3
+ #define CFG_RX_CHAIN_CMD_RING_CTRL_OVERRIDE_HOST_THRSH_LEN 1
+ #define CFG_RX_CHAIN_CMD_RING_CTRL_OVERRIDE_HOST_THRSH_MSK 0x8
+ U08 ring_ctrl;
+
+ U16 prefetch_thrsh;
+ U16 wb_thrsh;
+ U32 itr_value;
+ U16 host_thrsh;
+ U16 reserved;
+ wmi_sniffer_cfg_s sniffer_cfg;
+} POSTPACK WMI_CFG_RX_CHAIN_CMD;
+
+/*
+ * WMI_RCP_ADDBA_RESP_CMDID
+ */
+ typedef PREPACK struct {
+
+ #define CIDXTID_CID_POS 0
+ #define CIDXTID_CID_LEN 4
+ #define CIDXTID_CID_MSK 0xF
+ #define CIDXTID_TID_POS 4
+ #define CIDXTID_TID_LEN 4
+ #define CIDXTID_TID_MSK 0xF0
+ U08 cidxtid_byte;
+
+ U08 dialog_token;
+ U16 status_code;
+ U16 ba_param_set; /* ieee80211_ba_parameterset field to send */
+ U16 ba_timeout;
+} POSTPACK WMI_RCP_ADDBA_RESP_CMD;
+
+/*
+ * WMI_RCP_DELBA_CMDID
+ */
+ typedef PREPACK struct {
+
+ #define CIDXTID_CID_POS 0
+ #define CIDXTID_CID_LEN 4
+ #define CIDXTID_CID_MSK 0xF
+ #define CIDXTID_TID_POS 4
+ #define CIDXTID_TID_LEN 4
+ #define CIDXTID_TID_MSK 0xF0
+ U08 cidxtid_byte;
+
+ U08 rsvd;
+ U16 reason;
+} POSTPACK WMI_RCP_DELBA_CMD;
+
+/*
+ * WMI_RCP_ADDBA_REQ_CMDID
+ */
+ typedef PREPACK struct {
+
+ #define CIDXTID_CID_POS 0
+ #define CIDXTID_CID_LEN 4
+ #define CIDXTID_CID_MSK 0xF
+ #define CIDXTID_TID_POS 4
+ #define CIDXTID_TID_LEN 4
+ #define CIDXTID_TID_MSK 0xF0
+ U08 cidxtid_byte;
+
+ U08 dialog_token;
+ U16 ba_param_set; /* ieee80211_ba_parameterset field as it received */
+ U16 ba_timeout;
+ U16 ba_seq_ctrl; /* ieee80211_ba_seqstrl field as it received */
+} POSTPACK WMI_RCP_ADDBA_REQ_CMD;
+
+/**
+ * WMI_SET_MAC_ADDRESS_CMDID
+ */
+typedef PREPACK struct {
+ U08 macaddr[WMI_MAC_LEN];
+ U16 reserved;
+} POSTPACK WMI_SET_MAC_ADDRESS_CMD;
+
+
+/*
+* WMI_EAPOL_TX_CMDID
+*/
+ typedef PREPACK struct {
+ U08 dst_mac[WMI_MAC_LEN];
+ U16 eapol_len;
+ U08 eapol[EMPTY_ARRAY_SIZE];
+} POSTPACK WMI_EAPOL_TX_CMD;
+
+/*
+* WMI_ECHO_CMDID
+*/
+typedef PREPACK struct {
+ U32 value;
+} POSTPACK WMI_ECHO_CMD;
+
+/**
+ * **********************************************************************************************************************************
+ * WMI Events
+ * **********************************************************************************************************************************
+ */
+
+/*
+ * List of Events (target to host)
+ */
+enum WMI_EVENT_ID {
+ WMI_IMM_RSP_EVENTID = 0x0000,
+ WMI_READY_EVENTID = 0x1001,
+ WMI_CONNECT_EVENTID = 0x1002,
+ WMI_DISCONNECT_EVENTID = 0x1003,
+ WMI_SCAN_COMPLETE_EVENTID = 0x100a,
+ WMI_REPORT_STATISTICS_EVENTID = 0x100b,
+ WMI_RD_MEM_RSP_EVENTID = 0x1800,
+ WMI_FW_READY_EVENTID = 0x1801,
+ WMI_EXIT_FAST_MEM_ACC_MODE_EVENTID = 0x0200,
+ WMI_ECHO_RSP_EVENTID = 0x1803,
+ WMI_CONFIG_MAC_DONE_EVENTID = 0x1805,
+ WMI_CONFIG_PHY_DEBUG_DONE_EVENTID = 0x1806,
+ WMI_ADD_STATION_DONE_EVENTID = 0x1807,
+ WMI_ADD_DEBUG_TX_PCKT_DONE_EVENTID = 0x1808,
+ WMI_PHY_GET_STATISTICS_EVENTID = 0x1809,
+ WMI_FS_TUNE_DONE_EVENTID = 0x180A,
+ WMI_CORR_MEASURE_DONE_EVENTID = 0x180B,
+ WMI_TEMP_SENSE_DONE_EVENTID = 0x180E,
+ WMI_DC_CALIB_DONE_EVENTID = 0x180F,
+ WMI_IQ_TX_CALIB_DONE_EVENTID = 0x1811,
+ WMI_IQ_RX_CALIB_DONE_EVENTID = 0x1812,
+ WMI_SET_WORK_MODE_DONE_EVENTID = 0x1815,
+ WMI_LO_LEAKAGE_CALIB_DONE_EVENTID = 0x1816,
+ WMI_MARLON_R_ACTIVATE_DONE_EVENTID = 0x1817,
+ WMI_MARLON_R_READ_DONE_EVENTID = 0x1818,
+ WMI_MARLON_R_WRITE_DONE_EVENTID = 0x1819,
+ WMI_MARLON_R_TXRX_SEL_DONE_EVENTID = 0x181A,
+ WMI_SILENT_RSSI_CALIB_DONE_EVENTID = 0x181D,
+
+ WMI_CFG_RX_CHAIN_DONE_EVENTID = 0x1820,
+ WMI_VRING_CFG_DONE_EVENTID = 0x1821,
+ WMI_RX_ON_EVENTID = 0x1822,
+ WMI_BA_STATUS_EVENTID = 0x1823,
+ WMI_RCP_ADDBA_REQ_EVENTID = 0x1824,
+ WMI_ADDBA_RESP_SENT_EVENTID = 0x1825,
+ WMI_DELBA_EVENTID = 0x1826,
+ WMI_GET_SSID_EVENTID = 0x1828,
+ WMI_GET_PCP_CHANNEL_EVENTID = 0x182a,
+ WMI_SW_TX_COMPLETE_EVENTID = 0x182b,
+
+ WMI_READ_MAC_RXQ_EVENTID = 0x1830,
+ WMI_READ_MAC_TXQ_EVENTID = 0x1831,
+ WMI_WRITE_MAC_RXQ_EVENTID = 0x1832,
+ WMI_WRITE_MAC_TXQ_EVENTID = 0x1833,
+ WMI_WRITE_MAC_XQ_FIELD_EVENTID = 0x1834,
+
+ WMI_BEAFORMING_MGMT_DONE_EVENTID = 0x1836,
+ WMI_BF_TXSS_MGMT_DONE_EVENTID = 0x1837,
+ WMI_BF_RXSS_MGMT_DONE_EVENTID = 0x1839,
+ WMI_RS_MGMT_DONE_EVENTID = 0x1852,
+ WMI_RF_MGMT_STATUS_EVENTID = 0x1853,
+ WMI_BF_SM_MGMT_DONE_EVENTID = 0x1838,
+ WMI_RX_MGMT_PACKET_EVENTID = 0x1840,
+
+ /* Performance monitoring events */
+ WMI_DATA_PORT_OPEN_EVENTID = 0x1860,
+ WMI_WBE_LINKDOWN_EVENTID = 0x1861,
+
+ WMI_BF_CTRL_DONE_EVENTID = 0x1862,
+ WMI_NOTIFY_REQ_DONE_EVENTID = 0x1863,
+ WMI_GET_STATUS_DONE_EVENTID = 0x1864,
+
+ WMI_UNIT_TEST_EVENTID = 0x1900,
+ WMI_FLASH_READ_DONE_EVENTID = 0x1902,
+ WMI_FLASH_WRITE_DONE_EVENTID = 0x1903,
+
+
+ WMI_SET_CHANNEL_EVENTID = 0x9000,
+ WMI_ASSOC_REQ_EVENTID = 0x9001,
+ WMI_EAPOL_RX_EVENTID = 0x9002,
+ WMI_MAC_ADDR_RESP_EVENTID = 0x9003,
+ WMI_FW_VER_EVENTID = 0x9004,
+} ;
+
+
+
+/*******************************************************************************************************************
+ * Events data structures
+ *******************************************************************************************************************/
+
+/*
+ * WMI_RF_MGMT_STATUS_EVENTID
+ */
+enum wmi_rf_status_e {
+ WMI_RF_ENABLED = 0x0,
+ WMI_RF_DISABLED_HW = 0x1,
+ WMI_RF_DISABLED_SW = 0x2,
+ WMI_RF_DISABLED_HW_SW = 0x3
+};
+
+ typedef PREPACK struct {
+ U32 rf_status;
+} POSTPACK WMI_RF_MGMT_STATUS_EVENT;
+
+/*
+ * WMI_GET_STATUS_DONE_EVENTID
+ */
+ typedef PREPACK struct {
+ U32 is_associated;
+ U32 cid;
+ U16 bssid[3];
+ U16 channel;
+ U32 network_type;
+ U32 ssid_len;
+ U08 ssid[WMI_MAX_SSID_LEN];
+ U32 rf_status;
+ U32 is_secured;
+} POSTPACK WMI_GET_STATUS_DONE_EVENT;
+
+
+
+/**
+ * WMI_FW_VER_EVENTID
+ */
+ typedef PREPACK struct {
+ U08 major;
+ U08 minor;
+ U16 subminor;
+ U16 build;
+} POSTPACK WMI_FW_VER_EVENT;
+
+
+
+/*
+* WMI_MAC_ADDR_RESP_EVENTID
+*/
+ typedef PREPACK struct {
+ U08 mac_addr[WMI_MAC_LEN];
+ U08 auth_mode;
+ U08 crypt_mode;
+ U32 offload_mode; // 0/1
+} POSTPACK WMI_MAC_ADDR_RESP_EVENT;
+
+
+/*
+* WMI_EAPOL_RX_EVENTID
+*/
+ typedef PREPACK struct {
+ U08 src_mac[WMI_MAC_LEN];
+ U16 eapol_len;
+ U08 eapol[EMPTY_ARRAY_SIZE];
+} POSTPACK WMI_EAPOL_RX_EVENT;
+
+
+/*
+* WMI_READY_EVENTID
+*/
+ typedef PREPACK struct {
+ U32 sw_version;
+ U32 abi_version;
+ U08 macaddr[WMI_MAC_LEN];
+ U08 phyCapability; /* wmi_phy_capability_e */
+ U08 reserved;
+ U32 extend_mem_addr;
+ U32 extend_mem_size;
+} POSTPACK WMI_READY_EVENT;
+
+
+/*
+ * WMI_NOTIFY_REQ_DONE_EVENTID
+ */
+ typedef PREPACK struct {
+ U32 status;
+ U32 tsf_low;
+ U32 tsf_high;
+ U32 snr_val;
+ U32 tx_tpt;
+ U32 tx_goodput;
+ U32 rx_goodput;
+ U16 bf_mcs;
+ U16 my_rx_sector;
+ U16 my_tx_sector;
+ U16 other_rx_sector;
+ U16 other_tx_sector;
+ U16 range;
+} POSTPACK WMI_NOTIFY_REQ_DONE_EVENT;
+
+/*
+ * WMI_CONNECT_EVENTID
+ */
+ typedef PREPACK struct {
+ U16 channel;
+ U08 bssid[WMI_MAC_LEN];
+ U16 listenInterval;
+ U16 beaconInterval;
+ U32 networkType;
+ U08 beaconIeLen;
+ U08 assocReqLen;
+ U08 assocRespLen;
+ U08 cid;
+ U08 reserved0;
+ U16 reserved1;
+ U08 assocInfo[EMPTY_ARRAY_SIZE];
+} POSTPACK WMI_CONNECT_EVENT;
+
+
+
+/*
+ * WMI_DISCONNECT_EVENTID
+ */
+enum wmi_disconnect_reason_e {
+ NO_NETWORK_AVAIL = 0x01,
+ LOST_LINK = 0x02, /* bmiss */
+ DISCONNECT_CMD = 0x03,
+ BSS_DISCONNECTED = 0x04,
+ AUTH_FAILED = 0x05,
+ ASSOC_FAILED = 0x06,
+ NO_RESOURCES_AVAIL = 0x07,
+ CSERV_DISCONNECT = 0x08,
+ INVALID_PROFILE = 0x0a,
+ DOT11H_CHANNEL_SWITCH = 0x0b,
+ PROFILE_MISMATCH = 0x0c,
+ CONNECTION_EVICTED = 0x0d,
+ IBSS_MERGE = 0xe
+};
+
+ typedef PREPACK struct {
+ U16 protocolReasonStatus; /* reason code, see 802.11 spec. */
+ U08 bssid[WMI_MAC_LEN]; /* set if known */
+ U08 disconnectReason ; /* see wmi_disconnect_reason_e */
+ U08 assocRespLen;
+ U08 assocInfo[EMPTY_ARRAY_SIZE];
+} POSTPACK WMI_DISCONNECT_EVENT;
+
+
+/*
+ * WMI_SCAN_COMPLETE_EVENTID
+ */
+ typedef PREPACK struct {
+ U32 status;
+} POSTPACK WMI_SCAN_COMPLETE_EVENT;
+
+/*
+ * WMI_BA_STATUS_EVENTID
+ */
+enum wmi_vring_ba_status_e {
+ AGREED = 0x0,
+ NON_AGREED = 0x1,
+} ;
+
+ typedef PREPACK struct {
+ U16 status;
+ U16 reserved0;
+ U08 ringid;
+ U08 agg_wsize;
+ U16 ba_timeout;
+} POSTPACK WMI_VRING_BA_STATUS_EVENT;
+
+
+/*
+ * WMI_DELBA_EVENTID
+ */
+ typedef PREPACK struct {
+
+ #define CIDXTID_CID_POS 0
+ #define CIDXTID_CID_LEN 4
+ #define CIDXTID_CID_MSK 0xF
+ #define CIDXTID_TID_POS 4
+ #define CIDXTID_TID_LEN 4
+ #define CIDXTID_TID_MSK 0xF0
+ U08 cidxtid_byte;
+
+ U08 from_initiator;
+ U16 reason;
+} POSTPACK WMI_DELBA_EVENT;
+
+/*
+ * WMI_VRING_CFG_DONE_EVENTID
+ */
+enum wmi_vring_cfg_status {
+ VRING_CFG_SUCCESS = 0x0,
+ VRING_CFG_FAILURE = 0x1
+};
+
+ typedef PREPACK struct {
+ U08 ringid;
+ U08 status;
+ U16 reserved;
+ U32 tx_vring_tail_ptr;
+} POSTPACK WMI_VRING_CFG_DONE_EVENT;
+
+
+/*
+ * WMI_ADDBA_RESP_SENT_EVENTID
+ */
+enum wmi_rcp_addba_resp_sent_event_status_e {
+ SUCCESS = 0x0,
+ FAIL = 0x1
+};
+
+ typedef PREPACK struct {
+
+ #define CIDXTID_CID_POS 0
+ #define CIDXTID_CID_LEN 4
+ #define CIDXTID_CID_MSK 0xF
+ #define CIDXTID_TID_POS 4
+ #define CIDXTID_TID_LEN 4
+ #define CIDXTID_TID_MSK 0xF0
+ U08 cidxtid_byte;
+
+ U08 rsvd;
+ U16 status;
+} POSTPACK WMI_RCP_ADDBA_RESP_SENT_EVENT;
+
+/*
+ * WMI_RCP_ADDBA_REQ_EVENTID
+ */
+ typedef PREPACK struct {
+
+ #define CIDXTID_CID_POS 0
+ #define CIDXTID_CID_LEN 4
+ #define CIDXTID_CID_MSK 0xF
+ #define CIDXTID_TID_POS 4
+ #define CIDXTID_TID_LEN 4
+ #define CIDXTID_TID_MSK 0xF0
+ U08 cidxtid_byte;
+
+ U08 dialog_token;
+ U16 ba_param_set; /* ieee80211_ba_parameterset field as it received */
+ U16 ba_timeout;
+ U16 ba_seq_ctrl; /* ieee80211_ba_seqstrl field as it received */
+} POSTPACK WMI_RCP_ADDBA_REQ_EVENT;
+
+/*
+ * WMI_CFG_RX_CHAIN_DONE_EVENTID
+ */
+enum wmi_cfg_rx_chain_done_event_status_e {
+ CFG_RX_CHAIN_SUCCESS = 0x1,
+};
+
+ typedef PREPACK struct {
+ U32 rx_ring_tail_ptr; /* Rx V-Ring Tail pointer */
+ U32 status;
+} POSTPACK WMI_CFG_RX_CHAIN_DONE_EVENT;
+
+
+/*
+ * WMI_WBE_LINKDOWN_EVENTID
+ */
+enum wmi_wbe_link_down_event_reason_e {
+ USER_REQUEST = 0x0,
+ RX_DISASSOC = 0x1,
+ BAD_PHY_LINK = 0x2,
+};
+
+ typedef PREPACK struct {
+ U08 cid;
+ U08 reserved[3];
+ U32 reason;
+} POSTPACK WMI_WBE_LINK_DOWN_EVENT;
+
+/*
+ * WMI_DATA_PORT_OPEN_EVENTID
+ */
+ typedef PREPACK struct {
+ U08 cid;
+ U08 reserved0[3];
+} POSTPACK WMI_DATA_PORT_OPEN_EVENT;
+
+
+/*
+ * WMI_GET_PCP_CHANNEL_EVENTID
+ */
+ typedef PREPACK struct {
+ U08 channel_index;
+ U08 reserved[3];
+} POSTPACK WMI_GET_PCP_CHANNEL_EVENT;
+
+/*
+ * WMI_SW_TX_COMPLETE_EVENTID
+ */
+enum wmi_sw_tx_status_e {
+ TX_SW_STATUS_SUCCESS = 0x0,
+ TX_SW_STATUS_FAILED_NO_RESOURCES = 0x1,
+ TX_SW_STATUS_FAILED_TX = 0x2
+};
+
+typedef PREPACK struct {
+ U08 status;
+ U08 reserved[3];
+} POSTPACK WMI_SW_TX_COMPLETE_EVENT;
+
+/*
+ * WMI_GET_SSID_EVENTID
+ */
+ typedef PREPACK struct {
+ U32 ssid_len;
+ U08 ssid[WMI_MAX_SSID_LEN];
+} POSTPACK WMI_GET_SSID_EVENT;
+
+/*
+ * WMI_RX_MGMT_PACKET_EVENTID
+ */
+ typedef PREPACK struct {
+ U08 mcs;
+ S08 snr;
+ U16 range;
+ U16 stype;
+ U16 status;
+ U32 length;
+ U08 qid; /* Not resolved when == 0xFFFFFFFF ==> Broadcast to all MIDS */
+ U08 mid; /* Not resolved when == 0xFFFFFFFF ==> Broadcast to all MIDS */
+ U08 cid;
+ U08 channel; /* From Radio MNGR */
+} POSTPACK wmi_rx_mgmt_info_s;
+
+
+typedef PREPACK struct {
+ wmi_rx_mgmt_info_s info;
+ U32 payload;//[EMPTY_ARRAY_SIZE];
+} POSTPACK WMI_RX_MGMT_PACKET_EVENT;
+
+/*
+ * WMI_ECHO_RSP_EVENTID
+ */
+typedef PREPACK struct {
+ U32 echoed_value;
+} POSTPACK WMI_ECHO_EVENT;
+
+
+#if defined(_MSC_VER) // Microsoft
+#pragma pack (pop, marlon_wmi) /* restore original alignment from stack */
+#endif
+
+
+#endif /* MARLON_WMI_H_ */
diff --git a/debug-tools/lib/utils/Android.mk b/debug-tools/lib/utils/Android.mk
new file mode 100644
index 0000000..87b5650
--- /dev/null
+++ b/debug-tools/lib/utils/Android.mk
@@ -0,0 +1,18 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libwigig_utils
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_CPPFLAGS := -Wall -lpthread
+
+LOCAL_C_INCLUDES += \
+ $(LOCAL_PATH) \
+ $(LOCAL_PATH)/../inc \
+ $(LOCAL_PATH)/../inc/linux \
+ $(LOCAL_PATH)/linux
+
+LOCAL_SRC_FILES := $(shell find $(LOCAL_PATH) -name '*.cpp' | sed s:^$(LOCAL_PATH)::g )
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/debug-tools/lib/utils/DebugLogger.cpp b/debug-tools/lib/utils/DebugLogger.cpp
new file mode 100644
index 0000000..003be67
--- /dev/null
+++ b/debug-tools/lib/utils/DebugLogger.cpp
@@ -0,0 +1,269 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "wlct_os.h"
+#include "DebugLogger.h"
+#include "LoggerSupport.h"
+#include "Thread.h"
+
+#ifdef _WINDOWS
+#define TRACING_REGISTRY_PATH _T("Software\\QualcommAtheros\\WIGIG\\Tracing")
+#endif
+
+using namespace std;
+
+CDebugLogger g_Logger(_T("WLCT"));
+
+CDebugLogger *g_pLogger = &g_Logger;
+
+static const int WLCT_MAX_DEBUG_MSG_LEN = 512;
+
+const TCHAR *g_szMessageType[] =
+{
+ _T("ERROR"),
+ _T("WARN"),
+ _T("INFO"),
+ _T("DEBUG"),
+ _T("TRACE"),
+ _T("VERBOSE")
+};
+
+#ifdef _WINDOWS
+void ReadSettingsThread(void *pLogger)
+{
+ LOG_MESSAGE_DEBUG(_T("start running"));
+ CDebugLogger *pDebugLogger = (CDebugLogger*)pLogger;
+ pDebugLogger->m_bExit = false;
+
+ CRegKey regCofig;
+ if ( ERROR_SUCCESS == regCofig.Open(HKEY_LOCAL_MACHINE, TRACING_REGISTRY_PATH, KEY_READ))
+ {
+ // key found, reset settings
+// pDebugLogger->SetDefaultSettings();
+
+ DWORD dwTraceLevel;
+ if ( ERROR_SUCCESS == regCofig.QueryDWORDValue( _T("TraceLevel"), dwTraceLevel ) )
+ {
+ pDebugLogger->m_eTraceLevel = (COsDebugLogger::E_LOG_LEVEL)dwTraceLevel;
+ }
+
+ DWORD dwLogToFile;
+ if ( ERROR_SUCCESS == regCofig.QueryDWORDValue( _T("LogToFile"), dwLogToFile ) )
+ {
+ TCHAR szPath[MAX_PATH] = { 0 };
+ ULONG ulChars = MAX_PATH;
+ if ( ERROR_SUCCESS == regCofig.QueryStringValue( _T("LogFilePath"), szPath, &ulChars ) )
+ {
+ pDebugLogger->m_sLogFilePath = szPath;
+ //m_bLogToFile = TRUE;
+ }
+ }
+ }
+
+ // Create an event.
+ pDebugLogger->hNotifyEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+ if (pDebugLogger->hNotifyEvent == NULL)
+ {
+ _tprintf(TEXT("Error in CreateEvent (%d).\n"), GetLastError());
+ return;
+ }
+
+ LONG lErrorCode = 0;// regCofig.NotifyChangeKeyValue(FALSE, REG_NOTIFY_CHANGE_LAST_SET, pDebugLogger->hNotifyEvent, TRUE);
+ if (lErrorCode != ERROR_SUCCESS)
+ {
+ //_tprintf(TEXT("Error in RegNotifyChangeKeyValue (%d).\n"), lErrorCode);
+ return;
+ }
+
+ do
+ {
+ if (WaitForSingleObject(pDebugLogger->hNotifyEvent, INFINITE) == WAIT_FAILED)
+ {
+ _tprintf(TEXT("Error in WaitForSingleObject (%d).\n"), GetLastError());
+ }
+
+ DWORD dwTraceLevel;
+ if ( ERROR_SUCCESS == regCofig.QueryDWORDValue( _T("TraceLevel"), dwTraceLevel ) )
+ {
+ pDebugLogger->m_eTraceLevel = (COsDebugLogger::E_LOG_LEVEL)dwTraceLevel;
+ }
+
+ } while (!pDebugLogger->m_bExit);
+
+ CloseHandle(pDebugLogger->hNotifyEvent);
+ regCofig.Close();
+}
+#endif
+
+CDebugLogger::CDebugLogger(const TCHAR *tag, bool logToConsole) :
+ COsDebugLogger(logToConsole)
+{
+ m_sTag = tag;
+ SetDefaultSettings();
+
+// ReadTraceSettings( TRACING_REGISTRY_PATH );
+//
+// // override settings
+// CString sRegKeyPath;
+// sRegKeyPath.Format(_T("%s\\%s"), TRACING_REGISTRY_PATH, lpszTag );
+//
+// ReadTraceSettings(lpszTag);
+
+ // start the read tread
+#ifdef _WINDOWS
+ m_hThread = (HANDLE)_beginthread(ReadSettingsThread, 0, this);
+#endif
+}
+
+CDebugLogger::~CDebugLogger(void)
+{
+#ifdef _WINDOWS
+ m_bExit = true;
+ SetEvent(hNotifyEvent);
+ if (WaitForSingleObject(m_hThread, 1000) == WAIT_TIMEOUT)
+ {
+ TerminateThread(m_hThread, 1);
+ }
+#endif
+}
+
+void CDebugLogger::SetDefaultSettings(void)
+{
+ m_bLogToFile = false;
+ m_eTraceLevel = E_LOG_LEVEL_DEBUG;
+ m_sLogFilePath = _T("");
+}
+
+#ifdef _WINDOWS
+void CDebugLogger::ReadTraceSettings( LPCTSTR lpszRegistryPath )
+{
+ CRegKey regCofig;
+ if ( ERROR_SUCCESS == regCofig.Open(HKEY_LOCAL_MACHINE, lpszRegistryPath, KEY_READ))
+ {
+ // key found, reset settings
+ SetDefaultSettings();
+
+ DWORD dwTraceLevel;
+ if ( ERROR_SUCCESS == regCofig.QueryDWORDValue( _T("TraceLevel"), dwTraceLevel ) )
+ {
+ m_eTraceLevel = (COsDebugLogger::E_LOG_LEVEL)dwTraceLevel;
+ }
+
+ DWORD dwLogToFile;
+ if ( ERROR_SUCCESS == regCofig.QueryDWORDValue( _T("LogToFile"), dwLogToFile ) )
+ {
+ TCHAR szPath[MAX_PATH] = { 0 };
+ ULONG ulChars = MAX_PATH;
+ if ( ERROR_SUCCESS == regCofig.QueryStringValue( _T("LogFilePath"), szPath, &ulChars ) )
+ {
+ m_sLogFilePath = szPath;
+// m_bLogToFile = TRUE;
+ }
+ }
+ }
+}
+#endif
+
+void CDebugLogger::LogGlobalDebugMessage(CDebugLogger::E_LOG_LEVEL eTraceLevel,
+ S_LOG_CONTEXT *pCtxt, const TCHAR *fmt, ...)
+{
+ if (!g_pLogger)
+ {
+ return;
+ }
+
+ va_list args;
+ va_start(args, fmt);
+ g_pLogger->LogDebugMessageV(eTraceLevel, pCtxt, fmt, args);
+ va_end(args);
+}
+
+DWORD CDebugLogger::GetGlobalTraceLevel()
+{
+ if (!g_pLogger)
+ {
+ return 0;
+ }
+
+ return g_pLogger->GetGlobalTraceLevel();
+}
+
+void CDebugLogger::LogDebugMessage( CDebugLogger::E_LOG_LEVEL eTraceLevel,
+ S_LOG_CONTEXT *pCtxt, const TCHAR *fmt, ...)
+{
+ va_list args;
+
+ if (eTraceLevel > m_eTraceLevel)
+ {
+ return;
+ }
+
+ va_start(args, fmt);
+ LogDebugMessageV(eTraceLevel, pCtxt, fmt, args);
+ va_end(args);
+}
+
+void CDebugLogger::LogDebugMessageV( CDebugLogger::E_LOG_LEVEL eTraceLevel,
+ S_LOG_CONTEXT *pCtxt, const TCHAR *fmt, va_list args)
+{
+ TCHAR msg[WLCT_MAX_DEBUG_MSG_LEN] = {0};
+ int bytes_written = 0;
+
+ if (eTraceLevel > m_eTraceLevel)
+ {
+ return;
+ }
+
+ bytes_written = _stprintf_s(msg, WLCT_MAX_DEBUG_MSG_LEN,
+ _T("%s(%d): %s: [%s]; pid:%d; tid:%d; err=%d; f=[%s]; "),
+ (pCtxt ? pCtxt->funcName : _T("unknown")),
+ (pCtxt ? pCtxt->line : 0), m_sTag.c_str(), g_szMessageType[eTraceLevel],
+ CWlctThread::getCurrentProcessID(), CWlctThread::getCurrentThreadID(),
+ WlctGetLastError(), (pCtxt ? pCtxt->funcName : _T("unknown")));
+
+ bytes_written += _vsntprintf(msg + bytes_written,
+ WLCT_MAX_DEBUG_MSG_LEN - bytes_written, fmt, args);
+
+ _stprintf_s(msg + bytes_written, WLCT_MAX_DEBUG_MSG_LEN - bytes_written, _T("\n"));
+
+ print(msg);
+
+
+ if (m_bLogToFile)
+ {
+ FILE *fp = 0;
+ fp = _tfopen(m_sLogFilePath.c_str(), _T("a"));
+ if (NULL != fp)
+ {
+ fprintf(fp, "%s", msg);
+ fclose(fp);
+ }
+ }
+}
+
diff --git a/debug-tools/lib/utils/DebugLogger.h b/debug-tools/lib/utils/DebugLogger.h
new file mode 100644
index 0000000..efcff11
--- /dev/null
+++ b/debug-tools/lib/utils/DebugLogger.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "OsDebugLogger.h"
+
+class WLCT_API CDebugLogger : public COsDebugLogger
+{
+public:
+ struct WLCT_API S_LOG_CONTEXT
+ {
+ const TCHAR *funcName;
+ const TCHAR *fileName;
+ DWORD line;
+ };
+
+ CDebugLogger(const TCHAR *tag, bool logToConsole = false);
+ ~CDebugLogger(void);
+ COsDebugLogger::E_LOG_LEVEL GetTraceLevel() const
+ {
+ return m_eTraceLevel;
+ }
+
+ void LogDebugMessage(COsDebugLogger::E_LOG_LEVEL eTraceLevel,
+ S_LOG_CONTEXT *pCtxt, const TCHAR *tmt, ...);
+ void LogDebugMessageV(COsDebugLogger::E_LOG_LEVEL eTraceLevel,
+ S_LOG_CONTEXT *pCtxt, const TCHAR *fmt, va_list args);
+
+ static DWORD GetGlobalTraceLevel(void);
+ static void LogGlobalDebugMessage(COsDebugLogger::E_LOG_LEVEL eTraceLevel,
+ S_LOG_CONTEXT *pCtxt, const TCHAR *fmt, ...);
+
+private:
+ void ReadTraceSettings(const TCHAR *fileName);
+ void SetDefaultSettings();
+
+private:
+#ifdef _WINDOWS
+#pragma warning( disable : 4251 ) //suppress warning - it is OK on private members
+#endif
+ tstring m_sTag;
+ bool m_bLogToFile;
+#ifdef _WINDOWS
+#pragma warning( disable : 4251 ) //suppress warning - it is OK on private members
+#endif
+ tstring m_sLogFilePath;
+#ifdef _WINDOWS
+ HANDLE m_hThread;
+ bool m_bExit;
+ HANDLE hNotifyEvent;
+
+ friend void ReadSettingsThread(void *pLogger);
+#endif
+};
+
+extern CDebugLogger *g_pLogger;
diff --git a/debug-tools/lib/utils/LoggerSupport.h b/debug-tools/lib/utils/LoggerSupport.h
new file mode 100644
index 0000000..f85e386
--- /dev/null
+++ b/debug-tools/lib/utils/LoggerSupport.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "DebugLogger.h"
+
+#define LOG_MESSAGE( level, format, ...) \
+ {\
+ CDebugLogger::S_LOG_CONTEXT _logContext = { _T(__FUNCTION__), _T(__FILE__), __LINE__ }; \
+ CDebugLogger::LogGlobalDebugMessage( level, &_logContext, format,##__VA_ARGS__ );\
+ }
+
+#define LOG_MESSAGE_ERROR( format,...) LOG_MESSAGE(COsDebugLogger::E_LOG_LEVEL_ERROR, format,##__VA_ARGS__ )
+#define LOG_MESSAGE_WARN( format,...) LOG_MESSAGE(COsDebugLogger::E_LOG_LEVEL_WARN, format,##__VA_ARGS__ )
+#define LOG_MESSAGE_INFO( format,...) LOG_MESSAGE(COsDebugLogger::E_LOG_LEVEL_INFO, format,##__VA_ARGS__ )
+#define LOG_MESSAGE_DEBUG( format,...) LOG_MESSAGE(COsDebugLogger::E_LOG_LEVEL_DEBUG, format,##__VA_ARGS__ )
+#define LOG_MESSAGE_TRACE( format,...) LOG_MESSAGE(COsDebugLogger::E_LOG_LEVEL_TRACE, format,##__VA_ARGS__ )
+#define LOG_MESSAGE_VERBOSE( format,...) LOG_MESSAGE(COsDebugLogger::E_LOG_LEVEL_VERBOSE, format,##__VA_ARGS__ )
+#define LOG_STACK_ENTER LOG_MESSAGE(COsDebugLogger::E_LOG_LEVEL_VERBOSE, _T("Enter."))
+#define LOG_STACK_LEAVE LOG_MESSAGE(COsDebugLogger::E_LOG_LEVEL_VERBOSE, _T("Leave."))
diff --git a/debug-tools/lib/utils/Makefile b/debug-tools/lib/utils/Makefile
new file mode 100644
index 0000000..b648bfc
--- /dev/null
+++ b/debug-tools/lib/utils/Makefile
@@ -0,0 +1,56 @@
+-include $(TOPDIR)/rules.mk
+
+CFLAGS := -fPIC -Wall -g -MMD
+LDFLAGS := -shared -fPIC
+
+LIB := libwigig_utils.so
+
+.DEFAULT_GOAL = all
+
+
+ifneq ($(CONFIG_TARGET_ipq)$(CONFIG_TARGET_ipq806x),)
+is_ipq806x = 1
+endif
+
+ifeq ($(is_ipq806x), 1)
+ifneq ($(strip $(TOOLPREFIX)),)
+CROSS:=$(TOOLPREFIX)
+endif
+endif
+
+CC = $(CROSS)gcc
+CXX = $(CROSS)g++
+
+INCLUDES = -I . \
+ -I ../inc/linux \
+ -I ../inc \
+ -I ./linux \
+
+
+all: $(LIB)
+
+
+CPP_FILES := $(shell find . -type f -name '*.cpp')
+C_FILES := $(shell find . -type f -name '*.c')
+
+OBJ_FILES := $(CPP_FILES:.cpp=.o)
+OBJ_FILES += $(C_FILES:.c=.o)
+
+$(LIB): $(OBJ_FILES)
+ $(CXX) $(LDFLAGS) -o $(LIB) $(OBJ_FILES)
+
+%.o : %.cpp
+ $(CXX) $(CFLAGS) $(INCLUDES) -o $@ -c $<
+
+%.o : %.c
+ $(CC) $(CFLAGS) $(INCLUDES) -o $@ -c $<
+
+
+
+
+clean:
+ rm -rf $(LIB)
+ find . -type f \( -name "*.d" -o -name "*.o" \) -delete
+
+
+-include $(OBJ_FILES:%.o=%.d)
diff --git a/debug-tools/lib/utils/OsDebugLogger.h b/debug-tools/lib/utils/OsDebugLogger.h
new file mode 100644
index 0000000..4377f82
--- /dev/null
+++ b/debug-tools/lib/utils/OsDebugLogger.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "wlct_os.h"
+
+#if defined WLCTPCIACSS_EXPORTS && defined _WINDOWS
+#define WLCT_API __declspec(dllexport)
+#else
+#define WLCT_API
+#endif
+
+class WLCT_API COsDebugLogger {
+ public:
+ enum E_LOG_LEVEL
+ {
+ E_LOG_LEVEL_ERROR,
+ E_LOG_LEVEL_WARN,
+ E_LOG_LEVEL_INFO,
+ E_LOG_LEVEL_DEBUG,
+ E_LOG_LEVEL_TRACE,
+ E_LOG_LEVEL_VERBOSE
+ };
+
+ protected:
+ COsDebugLogger(bool logToConsole);
+ ~COsDebugLogger();
+ void print(const TCHAR *msg);
+
+ protected:
+ E_LOG_LEVEL m_eTraceLevel;
+ bool m_bLogToConsole;
+};
+
diff --git a/debug-tools/lib/utils/StlChar.h b/debug-tools/lib/utils/StlChar.h
new file mode 100644
index 0000000..4ae7bf6
--- /dev/null
+++ b/debug-tools/lib/utils/StlChar.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <string>
+#include <map>
+#include <vector>
+#include <sstream>
+
+#define WSTR_ARG(s) ToWString(s).c_str()
+#define TSTR_ARG(s) ToTString(s).c_str()
+
+#if defined(UNICODE) || defined(_UNICODE)
+typedef std::wstring tstring;
+typedef std::wstringstream tstringstream;
+typedef std::wostringstream tostringstream;
+#else
+typedef std::string tstring;
+typedef std::stringstream tstringstream;
+typedef std::ostringstream tostringstream;
+#endif
+
+typedef std::map<tstring, tstring> TStringMap;
+typedef std::vector<std::string> TStringList;
+
+inline std::wstring ToWString(const char *str)
+{
+ std::wostringstream s;
+ s << str;
+ return s.str();
+}
+
+inline std::wstring ToWString(const wchar_t *str)
+{
+ return str;
+}
+
+inline tstring ToTString(const char *str)
+{
+ tostringstream s;
+ s << str;
+ return s.str();
+}
+
+// printf format specifiers
+//
+//| Format Specifier | Win printf | Win wprintf | Lin printf | Lin wprintf |
+//|------------------|------------| ----------- | ---------- | ----------- |
+//| %s | char* | wchar_t* | char* | char* |
+//| %ls | wchar_t* | wchar_t* | wchar_t* | wchar_t* |
+//| %hs | char* | char* | NOT SUPPORTED |
+//| $S | wchar_t* | char* | wchar_t* | wchar_t* |
+//|------------------|------------| ----------- | ---------- | ----------- |
diff --git a/debug-tools/lib/utils/ThreadXFace.h b/debug-tools/lib/utils/ThreadXFace.h
new file mode 100644
index 0000000..8d119f2
--- /dev/null
+++ b/debug-tools/lib/utils/ThreadXFace.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "wlct_os.h"
+
+typedef void (*IWlctThreadThreadProc)(void *p);
+
+class IWlctThread
+{
+public:
+ IWlctThread(IWlctThreadThreadProc tProc, void *tCtx)
+ : threadProc(tProc), threadCtx(tCtx) {}
+ virtual ~IWlctThread() {}
+
+ bool ShouldStop()
+ {
+ return shouldStop;
+ }
+
+ virtual wlct_os_err_t Start() = 0;
+ virtual void Stop() = 0;
+
+protected:
+ IWlctThreadThreadProc threadProc;
+ void *threadCtx;
+ volatile bool shouldStop;
+};
diff --git a/debug-tools/lib/utils/linux/OsDebugLogger.cpp b/debug-tools/lib/utils/linux/OsDebugLogger.cpp
new file mode 100644
index 0000000..916f2bf
--- /dev/null
+++ b/debug-tools/lib/utils/linux/OsDebugLogger.cpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "OsDebugLogger.h"
+#include <syslog.h>
+
+COsDebugLogger::COsDebugLogger(bool logToConsole) : m_bLogToConsole(logToConsole)
+{
+ openlog("WLCT", m_bLogToConsole ? LOG_PERROR : 0, LOG_USER);
+}
+
+COsDebugLogger::~COsDebugLogger()
+{
+ closelog();
+}
+
+void COsDebugLogger::print(const char *msg)
+{
+ syslog(LOG_USER, "%s", msg);
+}
+
diff --git a/debug-tools/lib/utils/linux/Thread.cpp b/debug-tools/lib/utils/linux/Thread.cpp
new file mode 100644
index 0000000..3bdfc4e
--- /dev/null
+++ b/debug-tools/lib/utils/linux/Thread.cpp
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "Thread.h"
+#include "wlct_os.h"
+
+
+void *CWlctThread::GlobalThreadMain(void *p)
+{
+ CWlctThread *threadObj = (CWlctThread *)p;
+
+ threadObj->ThreadMain();
+
+ pthread_exit(&threadObj->threadResult);
+}
+
+void CWlctThread::ThreadMain(void)
+{
+ threadProc(threadCtx);
+}
+
+CWlctThread::CWlctThread(IWlctThreadThreadProc tProc, void *tCtx)
+ : IWlctThread(tProc, tCtx),
+ threadResult(0)
+{
+ memset(&threadObj, 0, sizeof(threadObj));
+}
+
+CWlctThread::~CWlctThread()
+{
+ Stop();
+}
+
+wlct_os_err_t CWlctThread::Start()
+{
+ shouldStop = false;
+
+ pthread_attr_t attr;
+
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
+
+ threadResult = pthread_create(&threadObj,
+ &attr,
+ GlobalThreadMain,
+ this);
+
+ pthread_attr_destroy(&attr);
+
+ return threadResult;
+}
+
+void CWlctThread::Stop()
+{
+ void *tres = NULL;
+ shouldStop = true;
+ /* Wait for the notification thread to process the signal */
+ pthread_join(threadObj, &tres);
+}
+
+uint32_t CWlctThread::getCurrentThreadID()
+{
+ return (uint32_t)pthread_self();
+}
+
+uint32_t CWlctThread::getCurrentProcessID()
+{
+ return (uint32_t)getpid();
+}
+
diff --git a/debug-tools/lib/utils/linux/Thread.h b/debug-tools/lib/utils/linux/Thread.h
new file mode 100644
index 0000000..438816e
--- /dev/null
+++ b/debug-tools/lib/utils/linux/Thread.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "ThreadXFace.h"
+#include <pthread.h>
+
+class CWlctThread : public IWlctThread
+{
+public:
+ CWlctThread(IWlctThreadThreadProc tProc, void *tCtx);
+ virtual ~CWlctThread();
+
+ virtual wlct_os_err_t Start();
+ virtual void Stop();
+
+ static uint32_t getCurrentThreadID();
+ static uint32_t getCurrentProcessID();
+
+protected:
+ static void *GlobalThreadMain(void *p);
+ void ThreadMain();
+
+ pthread_t threadObj;
+ int threadResult;
+};
diff --git a/debug-tools/lib/utils/linux/WlctCDevFile.cpp b/debug-tools/lib/utils/linux/WlctCDevFile.cpp
new file mode 100644
index 0000000..4078148
--- /dev/null
+++ b/debug-tools/lib/utils/linux/WlctCDevFile.cpp
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "wlct_os.h"
+#include "WlctCDevFile.h"
+#include "LoggerSupport.h"
+
+extern "C" {
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <unistd.h>
+};
+
+const int CWlctCDevFile::INVALID_FD = -1;
+
+CWlctCDevFile::CWlctCDevFile(): fd(INVALID_FD)
+{
+}
+
+CWlctCDevFile::~CWlctCDevFile()
+{
+ Close();
+}
+
+wlct_os_err_t CWlctCDevFile::Open(const char *fName, const char* interfaceName)
+{
+ //do something with params
+ (void)interfaceName;
+ wlct_os_err_t res = WLCT_OS_ERROR_GEN_FAILURE;
+
+ WLCT_ASSERT(IsOpened() == false);
+ WLCT_ASSERT(fName != NULL);
+
+ devFileName = fName;
+
+ LOG_MESSAGE_DEBUG("Char device file %s opening...", devFileName.c_str());
+
+ fd = open(devFileName.c_str(), 0);
+ if (INVALID_FD == fd)
+ {
+ res = errno;
+ LOG_MESSAGE_ERROR("Failed to open file %s (%d)", devFileName.c_str(), res);
+ goto Exit;
+ }
+
+ LOG_MESSAGE_DEBUG("Char device file opened: fd=%d", fd);
+
+ res = WLCT_OS_ERROR_SUCCESS;
+
+Exit:
+ if (res != WLCT_OS_ERROR_SUCCESS)
+ {
+ Close();
+ }
+
+ return res;
+}
+
+void CWlctCDevFile::Close()
+{
+ if (fd != INVALID_FD)
+ {
+ close(fd);
+ fd = INVALID_FD;
+ }
+
+ devFileName.erase();
+}
+
+wlct_os_err_t CWlctCDevFile::Ioctl(void *dataBuf,
+ DWORD dataBufLen,
+ DWORD ioctlFlags)
+{
+ wlct_os_err_t res = WLCT_OS_ERROR_GEN_FAILURE;
+ wlct_cdev_ioctl_hdr_t *ioctl_hdr = NULL;
+
+ WLCT_ASSERT(IsOpened() == true);
+ WLCT_ASSERT(dataBuf != NULL);
+ WLCT_ASSERT(dataBufLen != 0);
+
+ ioctl_hdr = (wlct_cdev_ioctl_hdr_t *)malloc((sizeof *ioctl_hdr) + dataBufLen);
+ if (NULL == ioctl_hdr)
+ {
+ LOG_MESSAGE_ERROR("Allocation failed (data of %u bytes)\n", dataBufLen);
+ res = WLCT_OS_ERROR_NOT_ENOUGH_MEMORY;
+ goto Exit;
+ }
+
+ ioctl_hdr->magic = WLCT_IOCTL_MAGIC;
+ ioctl_hdr->len = dataBufLen;
+ ioctl_hdr->flags = ioctlFlags;
+
+ if (ioctlFlags & WLCT_IOCTL_FLAG_SET)
+ memcpy(ioctl_hdr + 1, dataBuf, dataBufLen);
+
+ res = ioctl(fd, 0, ioctl_hdr);
+ if (0 != res)
+ {
+ res = errno;
+ LOG_MESSAGE_ERROR("ioctl failed with error code %d", res);
+ goto Exit;
+ }
+
+ if (ioctlFlags & WLCT_IOCTL_FLAG_GET)
+ memcpy(dataBuf, ioctl_hdr + 1, dataBufLen);
+
+Exit:
+ if (NULL != ioctl_hdr)
+ free(ioctl_hdr);
+
+ return res;
+}
diff --git a/debug-tools/lib/utils/linux/WlctCDevFile.h b/debug-tools/lib/utils/linux/WlctCDevFile.h
new file mode 100644
index 0000000..f1427f3
--- /dev/null
+++ b/debug-tools/lib/utils/linux/WlctCDevFile.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "wlct_cdev_shared.h"
+#include "wlct_os.h"
+
+#include <string>
+
+class CWlctCDevFile
+{
+public:
+ CWlctCDevFile();
+ virtual ~CWlctCDevFile();
+
+ virtual wlct_os_err_t Open(const char *fName, const char* interfaceName);
+ virtual void Close();
+ virtual wlct_os_err_t Ioctl(void *dataBuf, DWORD dataBufLen, DWORD ioctlFlags);
+ virtual wlct_os_err_t DebugFS(char *FileName, void *dataBuf, DWORD dataBufLen, DWORD DebugFSFlags)
+ {
+ //do something with params
+ (void)FileName;
+ (void)dataBuf;
+ (void)dataBufLen;
+ (void)DebugFSFlags;
+
+ return WLCT_OS_ERROR_CALL_NOT_IMPLEMENTED;
+ }
+
+ bool IsOpened() const
+ {
+ return (fd != INVALID_FD);
+ }
+
+protected:
+
+ int fd;
+ static const int INVALID_FD;
+
+private:
+
+ std::string devFileName;
+
+};
+
diff --git a/debug-tools/lib/utils/linux/WlctCDevSocket.cpp b/debug-tools/lib/utils/linux/WlctCDevSocket.cpp
new file mode 100644
index 0000000..5f0b091
--- /dev/null
+++ b/debug-tools/lib/utils/linux/WlctCDevSocket.cpp
@@ -0,0 +1,313 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "WlctCDevSocket.h"
+#include "LoggerSupport.h"
+#include "public.h"
+
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <linux/sockios.h>
+#include <linux/if.h>
+#include <sys/ioctl.h>
+#include <stdint.h>
+#include <iostream>
+#include <fstream>
+#include <string.h>
+
+
+//insted of "ioctl_if.h"
+#define WILOCITY_IOCTL_INDIRECT_READ IOCTL_INDIRECT_READ_OLD
+#define WILOCITY_IOCTL_INDIRECT_WRITE IOCTL_INDIRECT_WRITE_OLD
+#define WILOCITY_IOCTL_INDIRECT_READ_BLOCK IOCTL_INDIRECT_READ_BLOCK
+#define WILOCITY_IOCTL_INDIRECT_WRITE_BLOCK IOCTL_INDIRECT_WRITE_BLOCK
+
+#define EP_OPERATION_READ 0
+#define EP_OPERATION_WRITE 1
+#define WIL_IOCTL_MEMIO (SIOCDEVPRIVATE + 2)
+
+const char* DEBUGFS_ROOT = "/sys/kernel/debug/ieee80211/";
+
+CWlctCDevSocket::CWlctCDevSocket():CWlctCDevFile()
+{
+}
+
+int sendRWIoctl(wil_memio & io,int fd, char* interfaceName, bool activateLogs = true)
+{
+ int ret;
+ struct ifreq ifr;
+ ifr.ifr_data = &io;
+
+ snprintf(ifr.ifr_name, IFNAMSIZ, "%s", interfaceName);
+ ifr.ifr_name[IFNAMSIZ - 1] = 0;
+
+ ret = ioctl(fd, WIL_IOCTL_MEMIO, &ifr);
+ if (ret < 0 && activateLogs)
+ {
+ perror("ioctl");
+ }
+
+ return ret;
+}
+
+// Receives interface name (wigig#, wlan#) and checks if it is responding
+bool setInterfaceName(const char* interfaceName, int fd)
+{
+ if (interfaceName == NULL)
+ {
+ LOG_MESSAGE_ERROR("Invalid interface name (NULL)");
+ return false;
+ }
+
+ wil_memio io;
+ io.addr = 0x880050; //baud rate
+ io.op = EP_OPERATION_READ;
+
+ LOG_MESSAGE_DEBUG("Checking interface name: %s", interfaceName);
+
+ int ret = sendRWIoctl(io, fd, (char*)interfaceName, false);
+ if(ret == 0)
+ {
+ LOG_MESSAGE_DEBUG("Successfuly set interface name: %s", interfaceName);
+ return true;
+ }
+
+
+ return false;
+}
+
+wlct_os_err_t CWlctCDevSocket::Open(const char *fName, const char* ifName)
+{
+ wlct_os_err_t res = WLCT_OS_ERROR_GEN_FAILURE;
+
+ WLCT_ASSERT(IsOpened() == false);
+ WLCT_ASSERT(strlen(fName) < WLCT_CDEV_FILE_MAX_NAME_LEN);
+
+ LOG_MESSAGE_DEBUG("Char device file %s opening...", fName);
+
+ fd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (INVALID_FD == fd || fd < 0)
+ {
+ res = errno;
+ LOG_MESSAGE_ERROR("Failed to open socket to device");
+ Close();
+ return res;
+ }
+
+ LOG_MESSAGE_DEBUG("Trying to open socket to driver, device name: %s", ifName);
+
+ const TCHAR* const delimit = _T("!");
+
+ TCHAR* token;
+ TCHAR *next_token = NULL;
+
+ token = _tcstok_s( (char*)ifName, delimit, &next_token);
+ if (NULL == token)
+ {
+ LOG_MESSAGE_ERROR("No token found in %s", ifName);
+ Close();
+ return -1;
+ }
+
+ LOG_MESSAGE_DEBUG(_T("token: %s"), token);
+
+ // SPARROW
+ token = _tcstok_s( NULL, delimit, &next_token);
+ if (NULL == token)
+ {
+ LOG_MESSAGE_ERROR("No card token found in %s", ifName);
+ Close();
+ return -1;
+ }
+
+ LOG_MESSAGE_DEBUG(_T("token: %s"), token);
+
+ // wlan# or wigig#
+ token = _tcstok_s( NULL, delimit, &next_token);
+ if (NULL == token)
+ {
+ LOG_MESSAGE_ERROR("No interface token found in %s", ifName);
+ Close();
+ return -1;
+ }
+ LOG_MESSAGE_DEBUG(_T("token: %s"), token);
+
+ snprintf(interfaceName, IFNAMSIZ, "%s", token);
+
+ // Validate interface is 11ad interface
+ if(!setInterfaceName(interfaceName, fd))
+ {
+ LOG_MESSAGE_ERROR("Failed to query interface %s", interfaceName);
+ Close();
+ return res;
+ }
+
+ LOG_MESSAGE_DEBUG("Char device socket opened: fd=%d", fd);
+ LOG_MESSAGE_DEBUG("Looking for wil6210 in %s", DEBUGFS_ROOT);
+
+ const char* szCmdPattern = "find /sys/kernel/debug/ieee80211/ -name wil6210";
+ FILE* pIoStream = popen(szCmdPattern, "r");
+ if (!pIoStream)
+ {
+ LOG_MESSAGE_ERROR("Failed to run command to detect DebugFS\n" );
+ Close();
+ return res;
+ }
+
+ bool debugFsFound = false;
+ while (fgets(debugFSPath, WLCT_CDEV_FILE_MAX_NAME_LEN, pIoStream) != NULL)
+ {
+ // The command output contains a newline character that should be removed
+ debugFSPath[strcspn(debugFSPath, "\r\n")] = '\0';
+ LOG_MESSAGE_DEBUG("Found DebugFS Path: %s", debugFSPath);
+ if (debugFsFound)
+ {
+ // TODO - support DebugFS with Multiple interfaces for PMC
+ LOG_MESSAGE_INFO("DebugFS for Multiple WIGIG cards is not currently supported\n");
+ //Close();
+ //return res;
+ }
+ debugFsFound = true;
+ }
+
+ pclose(pIoStream);
+ return WLCT_OS_ERROR_SUCCESS;
+}
+
+
+wlct_os_err_t CWlctCDevSocket::Ioctl(void *dataBuf, DWORD dataBufLen, DWORD ioctlFlags)
+{
+ // doing something with unused params:
+ (void)dataBufLen;
+ (void)ioctlFlags;
+
+ wlct_ioctl_hdr_t *header = (wlct_ioctl_hdr_t*)dataBuf;
+ int32_t* inBuf = (int32_t*)((char*)dataBuf + sizeof(wlct_ioctl_hdr_t));
+ int32_t* outBuf = (int32_t*)((char*)dataBuf + sizeof(wlct_ioctl_hdr_t) + header->outBufOffset);
+ int32_t outBufferSize = header->outBufSize;
+ int Id = header->commandID;
+ int ret = 0;
+
+ //init for switch section
+ wil_memio io;
+ int numReads;
+ int32_t sizeToWrite;
+ PFILTER_WRITE_BLOCK inParam;
+ int i;
+ //end init for switch section
+
+
+ switch(Id){
+ case IOCTL_INDIRECT_READ_OLD:
+ //case WILOCITY_IOCTL_INDIRECT_READ:
+ //read is allways 32 bytes
+ io.addr = inBuf[0];
+ io.val = outBuf[0];
+ io.op = EP_OPERATION_READ;
+ ret = sendRWIoctl(io, fd, interfaceName);
+ *outBuf = io.val;
+ break;
+ case IOCTL_INDIRECT_WRITE_OLD:
+ //case WILOCITY_IOCTL_INDIRECT_WRITE:
+ //write parameters are passed only throgth "in param"
+ io.addr = inBuf[0];
+ io.val = inBuf[1];
+ io.op = EP_OPERATION_WRITE;
+ ret = sendRWIoctl(io, fd, interfaceName);
+ break;
+ //rb and wb are temporary! they should be replaced by a driver Ioctl
+ case WILOCITY_IOCTL_INDIRECT_READ_BLOCK:
+ //blocks must be 32bit alligned!
+ numReads = outBufferSize / 4;
+ io.op = EP_OPERATION_READ;
+ io.addr = inBuf[0];
+ for(i = 0 ; i < numReads ; i++){
+ ret = sendRWIoctl(io, fd, interfaceName);
+ if(ret != 0){
+ return -2;
+ }
+ outBuf[i] = io.val;
+ io.addr += sizeof(int32_t);
+ }
+ break;
+ case WILOCITY_IOCTL_INDIRECT_WRITE_BLOCK:
+ //blocks must be 32bit alligned!
+ inParam = reinterpret_cast<PFILTER_WRITE_BLOCK>(inBuf);
+ io.addr = inParam->address;
+ sizeToWrite = inParam->size / 4;
+ io.op = EP_OPERATION_WRITE;
+ for(i = 0 ; i < sizeToWrite ; i++){
+ io.val = inParam->buffer[i];
+ ret = sendRWIoctl(io, fd, interfaceName);
+ if(ret != 0){
+ return -3;
+ }
+ io.addr += sizeof(int32_t);
+ }
+ break;
+ default:
+ return -1;
+ }
+
+ return ret;
+
+}
+
+wlct_os_err_t CWlctCDevSocket::DebugFS(char *FileName, void *dataBuf, DWORD dataBufLen, DWORD DebugFSFlags)
+{
+ //doing somethin with unused params:
+ (void)dataBufLen;
+ (void)DebugFSFlags;
+ char file_to_open[WLCT_CDEV_FILE_MAX_NAME_LEN] ;
+ int *dataBuf_debugFS = (int*) dataBuf;
+ int num_desc = *dataBuf_debugFS;
+ dataBuf_debugFS++;
+ int size_desc = *dataBuf_debugFS;
+
+ LOG_MESSAGE_INFO(_T("DebugFS: %s"), FileName);
+
+ if(strlen(debugFSPath) == 0) return WLCT_OS_ERROR_OPEN_FAILED;
+
+ snprintf( file_to_open, WLCT_CDEV_FILE_MAX_NAME_LEN, "%s/%s", debugFSPath, FileName);
+ std::ofstream debugFSFile;
+ debugFSFile.open(file_to_open);
+
+ if ( (debugFSFile.rdstate() & std::ifstream::failbit ) != 0 ){
+ std::cout << "error while writing to debugfs! trying to write to address : ";
+ std::cout << file_to_open << std::endl;
+ return WLCT_OS_ERROR_GEN_FAILURE;
+ }
+ if(num_desc != 0 && size_desc != 0) debugFSFile << "alloc " << num_desc << " " << size_desc;
+ else debugFSFile << "free";
+ debugFSFile.close();
+
+ return WLCT_OS_ERROR_SUCCESS;
+}
+
+CWlctCDevSocket::~CWlctCDevSocket(){}
diff --git a/debug-tools/lib/utils/linux/WlctCDevSocket.h b/debug-tools/lib/utils/linux/WlctCDevSocket.h
new file mode 100644
index 0000000..d2998dd
--- /dev/null
+++ b/debug-tools/lib/utils/linux/WlctCDevSocket.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "wlct_os.h"
+#include "WlctCDevFile.h"
+
+#include <sys/socket.h>
+#include <linux/if.h>
+
+
+#define WLCT_CDEV_FILE_MAX_NAME_LEN 225
+
+class CWlctCDevSocket : public CWlctCDevFile
+{
+public:
+ CWlctCDevSocket();
+ virtual ~CWlctCDevSocket();
+
+ virtual wlct_os_err_t Ioctl(void *dataBuf,
+ DWORD dataBufLen,
+ DWORD ioctlFlags);
+ virtual wlct_os_err_t Open(const char *fName, const char* interfaceName);
+ virtual wlct_os_err_t DebugFS(char *FileName, void *dataBuf, DWORD dataBufLen, DWORD DebugFSFlags);
+
+private:
+
+ char interfaceName[IFNAMSIZ];
+ char debugFSPath[WLCT_CDEV_FILE_MAX_NAME_LEN];
+};
+
+typedef struct {
+ uint32_t op;
+ uint32_t addr; /* should be 32-bit aligned */
+ uint32_t val;
+} wil_memio;
+
+
diff --git a/debug-tools/remoteserver/Android.mk b/debug-tools/remoteserver/Android.mk
new file mode 100644
index 0000000..9a215a8
--- /dev/null
+++ b/debug-tools/remoteserver/Android.mk
@@ -0,0 +1,25 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := wigig_remoteserver
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_CPPFLAGS := -Wall -lpthread -fexceptions
+
+LOCAL_C_INCLUDES += \
+ $(LOCAL_PATH)/../lib/WlctPciAcss \
+ $(LOCAL_PATH)/../lib/inc \
+ $(LOCAL_PATH)/../lib/utils
+
+LOCAL_SHARED_LIBRARIES := \
+ libwigig_utils \
+ libwigig_pciaccess
+
+LOCAL_SRC_FILES := $(shell find $(LOCAL_PATH) -name '*.cpp' | sed s:^$(LOCAL_PATH)::g )
+LOCAL_SRC_FILES += parser.l
+
+
+include $(BUILD_EXECUTABLE)
+
diff --git a/debug-tools/remoteserver/Makefile b/debug-tools/remoteserver/Makefile
new file mode 100644
index 0000000..e9bef43
--- /dev/null
+++ b/debug-tools/remoteserver/Makefile
@@ -0,0 +1,62 @@
+-include $(TOPDIR)/rules.mk
+
+CFLAGS := -fPIE -Wall -g -MMD -Wno-unused-function
+LDFLAGS := -pie -fPIE -pthread -lwigig_pciaccess -lwigig_utils
+
+ifneq ($(CONFIG_TARGET_ipq)$(CONFIG_TARGET_ipq806x),)
+is_ipq806x = 1
+endif
+
+ifeq ($(is_ipq806x), 1)
+ifneq ($(strip $(TOOLPREFIX)),)
+CROSS:=$(TOOLPREFIX)
+endif
+endif
+
+CC := $(CROSS)gcc
+CXX := $(CROSS)g++
+
+.DEFAULT_GOAL = all
+PROG = wigig_remoteserver
+
+INCLUDES = -I ../lib/WlctPciAcss \
+ -I ../lib/inc \
+ -I ../lib/utils \
+
+LIBS = -L../lib/WlctPciAcss \
+ -L../lib/utils \
+
+all: $(PROG)
+
+CPP_FILES = $(shell find . -type f -name '*.cpp')
+C_FILES = $(shell find . -type f -name '*.c')
+LEX_FILES = $(shell find . -type f -name '*.l')
+
+
+GENERATED_C_FILES=$(LEX_FILES:.l=.c)
+OBJ_FILES= $(CPP_FILES:.cpp=.o)
+OBJ_FILES += $(C_FILES:.c=.o)
+OBJ_FILES += $(GENERATED_C_FILES:.c=.o)
+
+.PRECIOUS: $(GENERATED_C_FILES)
+
+$(PROG): $(OBJ_FILES)
+ $(CXX) -o $@ $^ $(LIBS) $(LDFLAGS)
+
+%.o : %.c
+ $(CC) $(CFLAGS) $(INCLUDES) -o $@ -c $<
+
+%.o : %.cpp
+ $(CXX) $(CFLAGS) $(INCLUDES) -o $@ -c $<
+
+%.c : %.l
+ flex -o $@ $<
+
+
+
+clean:
+ rm -rf $(PROG) $(GENERATED_C_FILES)
+ find . -type f \( -name "*.d" -o -name "*.o" \) -delete
+
+
+-include $(OBJ_FILES:%.o=%.d)
diff --git a/debug-tools/remoteserver/cmdiface.cpp b/debug-tools/remoteserver/cmdiface.cpp
new file mode 100644
index 0000000..9c03471
--- /dev/null
+++ b/debug-tools/remoteserver/cmdiface.cpp
@@ -0,0 +1,645 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <pthread.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sstream>
+#include <iostream>
+#include <fstream>
+
+#include "cmdiface.h"
+#include "parser.h"
+#include "debug.h"
+#include "WlctPciAcss.h"
+#include "pmc_file.h"
+#include "udp_server.h"
+
+
+struct open_interface_s *CmdIface::open_interfaces = NULL;
+pthread_mutex_t CmdIface::open_interfaces_mutex = PTHREAD_MUTEX_INITIALIZER;
+int CmdIface::interface_id = 0;
+
+/*
+*/
+void *CmdIface::get_interface(const char *name)
+{
+ struct open_interface_s *s = open_interfaces;
+ LOG_DEBUG << "Looking for interface: " << name << std::endl;
+
+ while(s != NULL)
+ {
+ LOG_VERBOSE << "Checking interface for match: " << s->interface << std::endl;
+ if(0 == strncasecmp(name, s->interface, MAX_INTERFACE_NAME))
+ {
+ LOG_VERBOSE << "Match found" << std::endl;
+ return s->handler;
+ }
+ s = s->next;
+ }
+
+ return NULL;
+}
+
+/*
+*/
+void *CmdIface::add_interface(const char *name, void *handler)
+{
+ LOG_DEBUG << "Adding interface: " << name << std::endl;
+
+ void *h = get_interface(name);
+ if(h != NULL)
+ {
+ LOG_DEBUG << "The interface is already open" << std::endl;
+ return h; // Interface already opened
+ }
+
+ // Add interface to the list
+ struct open_interface_s *s = new struct open_interface_s;
+ if(s == NULL)
+ {
+ return NULL;
+ }
+
+ snprintf(s->interface, MAX_INTERFACE_NAME, "%s", name);
+ s->handler = handler;
+ pthread_mutex_lock(&open_interfaces_mutex);
+ s->next = open_interfaces;
+ open_interfaces = s;
+ pthread_mutex_unlock(&open_interfaces_mutex);
+
+ return handler;
+}
+
+/*
+*/
+void CmdIface::del_interface(void *handler)
+{
+ LOG_DEBUG << "Deleting interfaces by handler" << std::endl;
+
+ struct open_interface_s *s = open_interfaces;
+ struct open_interface_s *prev = NULL;
+
+ while(s != NULL) {
+ if(handler == s->handler) {
+ // Remove the interface from the list
+ pthread_mutex_lock(&open_interfaces_mutex);
+ if(prev != NULL)
+ prev->next = s->next;
+ else
+ open_interfaces = s->next;
+ pthread_mutex_unlock(&open_interfaces_mutex);
+ delete s;
+ }
+ prev = s;
+ s = s->next;
+ }
+}
+
+/*
+*/
+int CmdIface::cmd_get_interfaces()
+{
+ INTERFACE_LIST interfaces;
+ int num_interfaces;
+ int rc;
+
+ LOG_DEBUG << "Getting active WIGIG card interfaces" << std::endl;
+
+ rc = GetInterfaces(&interfaces, &num_interfaces);
+ LOG_DEBUG << "Found " << num_interfaces << " interfaces" << std::endl;
+
+ std::ostringstream replyBuilder;
+
+ if(rc == 0)
+ {
+ for(int i=0; i < num_interfaces; i++)
+ {
+ replyBuilder << interfaces.list[i].ifName << ' ';
+ }
+ }
+
+ replyBuilder << "\r\n";
+ m_Reply = replyBuilder.str();
+
+ return 0;
+}
+
+/*
+*/
+int CmdIface::cmd_open_interface(char *interface)
+{
+ void *handler = NULL;
+ int rc=0;
+
+ LOG_DEBUG << "Opening an interface: " << interface << std::endl;
+
+ if( strstr(interface, "SPARROW")|| strstr(interface, "sparrow")){
+ rc = CreateDeviceAccessHandler(interface, MST_SPARROW, &handler);
+ }
+ else if(strstr(interface, "MARLON") || strstr(interface, "marlon")){
+ rc = CreateDeviceAccessHandler(interface, MST_MARLON, &handler);
+ }
+ else{
+ m_Reply = "0xDEAD\r\n";
+ }
+ if(rc != 0)
+ m_Reply = "0xDEADDEAD\r\n";
+ else {
+
+ std::ostringstream replyBuilder;
+
+ replyBuilder << interface << '_' << interface_id;
+ add_interface(replyBuilder.str().c_str(), handler);
+ replyBuilder << "\r\n";
+ m_Reply = replyBuilder.str();
+ interface_id++; // TODO: Should be protected by a mutex? I didn't see it's being used in the application
+ }
+ return 0;
+}
+
+/*
+*/
+int CmdIface::cmd_close_interface(char *interface)
+{
+ LOG_DEBUG << "Closing interface: " << interface << std::endl;
+
+ void *handler = get_interface(interface);
+
+ if(handler != NULL)
+ {
+ del_interface(handler);
+ interface_id--;
+ }
+ else
+ {
+ LOG_WARNING << "Interface " << interface << " wasn't opened" << std::endl;
+ }
+
+ m_Reply = "0\r\n";
+ return 0;
+}
+
+/*
+*/
+int CmdIface::cmd_r(char *interface, unsigned int address)
+{
+ unsigned int val = 0xDEADDEAD;
+ void *handler = get_interface(interface);
+
+ std::ostringstream replyBuilder;
+ if(handler == NULL)
+ {
+ m_Reply = "0xDEADDEAD";
+ }
+ else
+ {
+ int rc = WlctAccssRead(handler, address, val);
+ (void)rc;
+ replyBuilder << val;
+ }
+
+ replyBuilder << "\r\n";
+ m_Reply = replyBuilder.str();
+
+ return 0;
+}
+
+/*
+*/
+int CmdIface::cmd_w(char *interface, unsigned int address, unsigned int data)
+{
+ int rc;
+ void *handler = get_interface(interface);
+
+ std::ostringstream replyBuilder;
+
+ if(handler == NULL)
+ {
+ replyBuilder << "0xDEADDEAD";
+ }
+ else
+ {
+ rc = WlctAccssWrite(handler, address, data);
+ if(rc == 0)
+ replyBuilder << "0";
+ else
+ replyBuilder << "ERROR";
+ }
+
+ replyBuilder << "\r\n";
+ m_Reply = replyBuilder.str();
+
+ return 0;
+}
+
+/*
+*/
+int CmdIface::cmd_alloc_pmc(char *interface, unsigned int desc_size, unsigned int desc_num)
+{
+ int rc;
+ LOG_DEBUG << "Allocating PMC descriptors:"
+ << " interface = " << interface
+ << " size = " << desc_size
+ << " number = " << desc_num
+ << std::endl;
+
+ std::ostringstream replyBuilder;
+
+ void *handler = get_interface(interface);
+ if(handler == NULL)
+ {
+ LOG_DEBUG << "Cannot get handler for interface " << interface << std::endl;
+ replyBuilder << "0xDEADDEAD";
+ }
+ else
+ {
+ rc = WlctAccssAllocPmc(handler, desc_size, desc_num);
+
+ if(rc == 0)
+ {
+ LOG_DEBUG << "Successfully allocated PMC descriptors" << std::endl;
+ replyBuilder << "0";
+ }
+ else
+ {
+ LOG_ERROR << "Error allocating PMC descriptors" << std::endl;
+ replyBuilder << "ERROR";
+ }
+ }
+
+ replyBuilder << "\r\n";
+ m_Reply = replyBuilder.str();
+
+ return 0;
+}
+
+/*
+*/
+int CmdIface::cmd_read_pmc(char *interface, unsigned int ref_number)
+{
+ LOG_DEBUG << "Reading PMC data:"
+ << " interface = " << interface
+ << " reference number = " << ref_number
+ << std::endl;
+
+ void *handler = get_interface(interface);
+
+ if(handler == NULL)
+ {
+ LOG_ERROR << "No interface found: " << interface << std::endl;
+ m_Reply = "0xDEADDEAD\r\n";
+ return 0;
+ }
+
+ PmcFile pmcFile(ref_number);
+ PmcFileWriter pmcFileWriter(pmcFile);
+ bool status = pmcFileWriter.WriteFile();
+ if (false == status)
+ {
+ LOG_ERROR << "Error creating PMC data file" << std::endl;
+ m_Reply = "0xDEADDEAD\r\n";
+ return 0;
+ }
+
+ // Reply with file size
+ size_t pmcFileSize = pmcFileWriter.GetFileSize();
+
+ std::ostringstream replyBuilder;
+ replyBuilder << pmcFileSize << "\r\n";
+ m_Reply = replyBuilder.str();
+
+ return 0;
+}
+
+/*
+*/
+int CmdIface::cmd_read_pmc_file(unsigned int ref_number)
+{
+ LOG_DEBUG << "Reading PMC File #" << ref_number << std::endl;
+
+ PmcFile pmcFile(ref_number);
+
+ if (NULL == pmcFile.GetFileName())
+ {
+ LOG_ERROR << "Error getting PMC data file #" << ref_number << std::endl;
+ m_Reply = "0xDEADDEAD\r\n";
+ return 0;
+ }
+
+ // Note: No \r\n is needed here, the file name won't be sent to a clientls
+ m_Reply = pmcFile.GetFileName();
+ replyType = REPLY_TYPE_FILE;
+ return 0;
+}
+
+/*
+*/
+int CmdIface::cmd_rb(char *interface, unsigned int address, unsigned int num_regs)
+{
+ void *handler = get_interface(interface);
+
+ if((handler == NULL) || (num_regs > MAX_REGS_LEN))
+ {
+ m_Reply = "0xDEADDEAD\r\n";
+ return 0;
+ }
+
+ unsigned int *val = new unsigned int[num_regs];
+ int rc = readBlock(handler, address, num_regs*sizeof(unsigned int), (char*)val);
+
+ if (rc == 0)
+ {
+ std::ostringstream replyBuilder;
+ replyBuilder << std::hex;
+
+ for(unsigned int i=0; i < num_regs; i++)
+ {
+ replyBuilder << "0x" << val[i];
+ if(i < num_regs -1 )
+ {
+ replyBuilder << ' ';
+ }
+ }
+
+ replyBuilder << "\r\n";
+ m_Reply = replyBuilder.str();
+ }
+ else
+ {
+ m_Reply = "0xDEADDEAD\r\n";
+ }
+
+ delete[] val;
+ return 0;
+}
+
+/*
+*/
+int CmdIface::cmd_wb(char *interface, unsigned int address, unsigned int len, const char *block)
+{
+ void *handler = get_interface(interface);
+
+ if((handler == NULL) || (len > MAX_REGS_LEN))
+ {
+ m_Reply = "0xDEADDEAD\r\n";
+ return 0;
+ }
+
+ LOG_VERBOSE << "current WB is " << block << " length is " << len << std::endl;
+ int rc = writeBlock(handler, address, len, block);
+ if(rc == 0)
+ {
+ m_Reply = "0\r\n";
+ }
+ else
+ {
+ m_Reply = "ERROR\r\n";
+ }
+
+ return 0;
+}
+
+
+int CmdIface::cmd_interface_reset(char *interface)
+{
+ void *handler = get_interface(interface);
+ if(handler == NULL)
+ {
+ m_Reply = "0xDEADDEAD\r\n";
+ }
+ else
+ {
+ int rc = InterfaceReset(handler);
+ if(rc == 0)
+ {
+ m_Reply = "OK\r\n";
+ }
+ else
+ {
+ m_Reply = "0xDEADDEAD\r\n";
+ }
+ }
+
+ return 0;
+}
+
+
+int CmdIface::cmd_sw_reset(char *interface)
+{
+ void *handler = get_interface(interface);
+ if (handler == NULL)
+ {
+ m_Reply = "0xDEADDEAD\r\n";
+ }
+ else
+ {
+ int rc = SwReset(handler);
+ if (rc == 0)
+ {
+ m_Reply = "OK\r\n";
+ }
+ else
+ {
+ m_Reply = "0xDEADDEAD\r\n";
+ }
+ }
+
+ return 0;
+}
+
+int CmdIface::cmd_set_host_alias(char* alias)
+{
+ std::ofstream fd(UdpServer::host_details_file_name.c_str());
+ if (!fd.is_open())
+ {
+ m_Reply = "FAIL : Coudn't set the new alias: failed to open the configuration file";
+ LOG_VERBOSE << m_Reply << std::endl;
+ return -1;
+ }
+ fd << alias;
+ if (fd.bad())
+ {
+ m_Reply = "FAIL : Coudn't set the new alias: failed to write the new alias to the configuration file";
+ LOG_VERBOSE << m_Reply << std::endl;
+ fd.close();
+ return -2;
+ }
+ fd.close();
+
+ UdpServer::SetHostAlias(alias);
+ UdpServer::SendAll(UdpServer::GetHostDetails());
+ return 0;
+}
+
+
+/*
+ Execute command received from a remote client
+ The command of length 'len' is in 'buf'. 'outlen' has
+ the max output buffer size.
+ On return, 'outbuf' may have a reply to be sent to the client,
+ 'outlen' should have the reply length or 0 if no reply required.
+ Returns KEEPALIVE_OK if ok, KEEPALIVE_CLOSE to close the connection, KEEPALIVE_SHUTDOWN to shutdown the server (debug mode)
+*/
+int CmdIface::do_command(const char *buf, int len)
+{
+ servercmd_t s;
+ int result = KEEPALIVE_OK;
+ replyType = REPLY_TYPE_BUFFER;
+
+ ((char*)buf)[len] = '\0'; // Make a zero-terminated string
+
+ // Parse the command
+ parse_line(buf, &s);
+ dump_parser(&s);
+
+ // Check for the parser error. Note, not all the commands in the original protocol report about errors. so we check the error
+ // for selected commands only TODO: verify the commands list reporting the error
+ if(s.cmd == CMD_OPEN_INTERFACE || s.cmd == CMD_R || s.cmd == CMD_RB || s.cmd == CMD_W || s.cmd == CMD_WB)
+ {
+ if(s.error != 0)
+ {
+ LOG_ERROR << "Command line parsing error" << std::endl;
+ m_Reply = "0xDEADDEAD\r\n"; // TODO: or should it be "dmtools_error"??
+ return result;
+ }
+ }
+
+ switch(s.cmd)
+ {
+ case CMD_GET_INTERFACES:
+ cmd_get_interfaces();
+ break;
+ case CMD_OPEN_INTERFACE:
+ cmd_open_interface(s.interface);
+ break;
+ case CMD_CLOSE_INTERFACE:
+ cmd_close_interface(s.interface);
+ break;
+ case CMD_R:
+ cmd_r(s.interface, s.address);
+ break;
+ case CMD_RB:
+ cmd_rb(s.interface, s.address, s.value);
+ break;
+ case CMD_W:
+ cmd_w(s.interface, s.address, s.value);
+ break;
+ case CMD_WB:
+ // hexdata_len is in dwords, cmd_wb works in bytes. (hence * 4)
+ cmd_wb(s.interface, s.address, s.hexdata_len * 4, (const char*)s.hexdata);
+ break;
+ case CMD_INTERFACE_RESET:
+ cmd_interface_reset(s.interface);
+ break;
+ case CMD_SW_RESET:
+ cmd_sw_reset(s.interface);
+ break;
+ case CMD_EXIT:
+ result = KEEPALIVE_CLOSE; // Terminate the connection
+ break;
+ case CMD_ALLOC_PMC:
+ cmd_alloc_pmc(s.interface, s.address, s.value);
+ break;
+ case CMD_READ_PMC:
+ cmd_read_pmc(s.interface, s.address);
+ break;
+ case CMD_READ_PMC_FILE:
+ cmd_read_pmc_file(s.address);
+ break;
+ case CMD_SET_HOST_ALIAS:
+ cmd_set_host_alias(s.interface);
+ break;
+ case CMD_COMMAND_UNKNOWN:
+ default:
+ m_Reply = "dmtools_error\r\n";
+
+ }
+ return result;
+}
+
+/*
+ Dump the parser structure, for debugging only
+*/
+void CmdIface::dump_parser(servercmd_t *s)
+{
+ if(s->error)
+ {
+ LOG_ERROR << "Parser error in comand parsing."
+ << " Error: " << s->error
+ << " Message: " << parser_error_to_string(s->error)
+ << std::endl;
+
+ return;
+ }
+
+ LOG_VERBOSE << "Parsed Command: " << command_to_string(s->cmd)
+ << " Interface: " << s->interface << std::endl;
+
+ if(s->address != (unsigned int)-1)
+ {
+ LOG_VERBOSE << "Address: " << s->address << std::endl;
+ }
+ if(s->value != (unsigned int)-1)
+ {
+ LOG_VERBOSE << "Value: " << s->value << std::endl;
+ }
+ if(s->hexdata_len)
+ {
+ for(int i=0; i < s->hexdata_len && i < MAX_REGS_LEN; i++)
+ LOG_VERBOSE << std::hex << "0x" << s->hexdata[i] << std::dec << std::endl;
+ }
+}
+
+/*
+*/
+int CmdIface::get_reply_len()
+{
+ return m_Reply.size();
+}
+
+/*
+*/
+void CmdIface::to_lower(char* string)
+{
+ for (int i = 0; string[i]; i++)
+ {
+ string[i] = tolower(string[i]);
+ }
+
+ return;
+}
+
+/*
+*/
+CmdIface::CmdIface()
+ : replyType(REPLY_TYPE_BUFFER)
+{
+}
diff --git a/debug-tools/remoteserver/cmdiface.h b/debug-tools/remoteserver/cmdiface.h
new file mode 100644
index 0000000..a58864e
--- /dev/null
+++ b/debug-tools/remoteserver/cmdiface.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __interface_h
+#define __interface_h
+
+#include <pthread.h>
+#include <string>
+
+extern "C"
+{
+#include "parser.h"
+}
+
+struct open_interface_s {
+ char interface[MAX_INTERFACE_NAME];
+ void *handler;
+ struct open_interface_s *next;
+};
+
+#define KEEPALIVE_OK 0 // keep the connection
+#define KEEPALIVE_CLOSE 1 // close the connection
+#define KEEPALIVE_SHUTDOWN 2 // close the connection and shutdown the server. For debugging only, remove from the production
+
+
+// Max buffer size for a command and a reply. We should consider the longest command/data sequence to fit in a buffer.
+// rb reading 1024 (MAX_REGS_LEN) registers: rb HHHHHHHH HHHH 1024*(0xHHHHHHHH) = 17 + 1024*10 = 10257 bytes
+// wb writing 1024 (MAX_REGS_LEN) hex values: wb HHHHHHHH "1024*HH" = 14+1024*2 = 2062 bytes
+#define MAX_INPUT_BUF (11*MAX_REGS_LEN)
+
+// The reply data may be generated in several ways, the data is expected to be obtained according to this type
+enum REPLY_TYPE
+{
+ REPLY_TYPE_NONE,
+ REPLY_TYPE_BUFFER,
+ REPLY_TYPE_FILE
+};
+
+
+class CmdIface
+{
+public:
+ CmdIface();
+
+ int do_command(const char *buf, int len);
+ const char *get_reply() const { return m_Reply.c_str(); };
+ int get_reply_len();
+ REPLY_TYPE get_reply_type() const { return replyType; }
+
+private:
+
+ static struct open_interface_s *open_interfaces;
+ static pthread_mutex_t open_interfaces_mutex;
+ static int interface_id; // Interface id counter returned in open_interface
+
+ void *get_interface(const char *name);
+ void *add_interface(const char *name, void *handler);
+ void del_interface(void *handler);
+
+ int cmd_get_interfaces();
+ int cmd_open_interface(char *interface);
+ int cmd_close_interface(char *interface);
+ int cmd_r(char *interface, unsigned int address);
+ int cmd_rb(char *interface, unsigned int address, unsigned int num_regs);
+ int cmd_w(char *interface, unsigned int address, unsigned int data);
+ int cmd_wb(char *interface, unsigned int address, unsigned int len, const char *block);
+ int cmd_interface_reset(char *interface);
+ int cmd_sw_reset(char *interface);
+ int cmd_alloc_pmc(char *interface, unsigned int desc_size, unsigned int desc_num);
+ int cmd_read_pmc(char *interface, unsigned int ref_number);
+ int cmd_read_pmc_file(unsigned int ref_number);
+ void dump_parser(servercmd_t *s);
+ int cmd_set_host_alias(char *alias);
+
+ void to_lower(char* string);
+
+ REPLY_TYPE replyType;
+ std::string m_Reply;
+
+};
+
+#endif // interface_h
+
diff --git a/debug-tools/remoteserver/debug.cpp b/debug-tools/remoteserver/debug.cpp
new file mode 100644
index 0000000..7a3502d
--- /dev/null
+++ b/debug-tools/remoteserver/debug.cpp
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "debug.h"
+#include <stdio.h>
+
+// *************************************************************************************************
+
+LogConfig g_LogConfig(LOG_SEV_INFO, false);
+
+// *************************************************************************************************
+
+LogConfig::LogConfig(LogSeverity maxSeverity, bool bPrintLocation)
+ : m_MaxSeverity(maxSeverity), m_PrintLocation(bPrintLocation)
+{
+}
+
+void LogConfig::SetMaxSeverity(int traceLevel)
+{
+ if (traceLevel > LOG_SEV_VERBOSE)
+ {
+ fprintf(stderr, "Invalid trace level, setting %d\n", LOG_SEV_VERBOSE);
+ m_MaxSeverity = LOG_SEV_VERBOSE;
+ }
+ else
+ {
+ m_MaxSeverity = static_cast<LogSeverity>(traceLevel);
+ fprintf(stdout, "Setting trace level to %d\n", m_MaxSeverity);
+ }
+}
+
+// *************************************************************************************************
+
+const char* LogMsgPrefix::SeverityToString(LogSeverity sev)
+{
+ static const char* const pSeverityToString[] = { "ERR", "WRN", "INF", "DBG", "VRB" };
+
+ size_t index = static_cast<size_t>(sev);
+ if (index >= sizeof(pSeverityToString)/sizeof(pSeverityToString[0]))
+ {
+ return "---";
+ }
+
+ return pSeverityToString[index];
+}
+
+std::ostream& operator<<(std::ostream& os, const LogMsgPrefix& prefix)
+{
+ os << '[' << LogMsgPrefix::SeverityToString(prefix.Severity) << "] ";
+ if (!g_LogConfig.ShouldPrintLocation()) return os;
+ return os << "(" << prefix.File << ':' << prefix.Line << ") ";
+}
diff --git a/debug-tools/remoteserver/debug.h b/debug-tools/remoteserver/debug.h
new file mode 100644
index 0000000..d3c99bf
--- /dev/null
+++ b/debug-tools/remoteserver/debug.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __debug_h
+#define __debug_h
+
+#include <iostream>
+
+// Severity values are expected to raise from zero
+enum LogSeverity
+{
+ LOG_SEV_ERROR = 0, // Unexpected input/events that may cause server misbehavior
+ LOG_SEV_WARNING = 1, // Suspicious events
+ LOG_SEV_INFO = 2, // Events like command/response
+ LOG_SEV_DEBUG = 3, // Detailed functionality
+ LOG_SEV_VERBOSE = 4 // Excessive debug
+};
+
+#define TRACE_WITH_PREFIX(SEV) \
+ g_LogConfig.ShouldPrint(SEV) && std::cout << LogMsgPrefix(SEV, __FILE__, __LINE__)
+
+#define LOG_ERROR TRACE_WITH_PREFIX(LOG_SEV_ERROR)
+#define LOG_WARNING TRACE_WITH_PREFIX(LOG_SEV_WARNING)
+#define LOG_INFO TRACE_WITH_PREFIX(LOG_SEV_INFO)
+#define LOG_DEBUG TRACE_WITH_PREFIX(LOG_SEV_DEBUG)
+#define LOG_VERBOSE TRACE_WITH_PREFIX(LOG_SEV_VERBOSE)
+
+// *************************************************************************************************
+
+struct LogConfig
+{
+public:
+ LogConfig(LogSeverity maxSeverity, bool bPrintLocation);
+ void SetMaxSeverity(int traceLevel);
+
+ bool ShouldPrint(LogSeverity sev) const { return sev <= m_MaxSeverity; }
+ bool ShouldPrintLocation() const { return m_PrintLocation; }
+
+private:
+
+ LogSeverity m_MaxSeverity;
+ const bool m_PrintLocation;
+
+};
+
+// *************************************************************************************************
+
+extern LogConfig g_LogConfig;
+
+// *************************************************************************************************
+
+class LogMsgPrefix
+{
+ friend std::ostream& operator<<(std::ostream& os, const LogMsgPrefix& prefix);
+
+public:
+
+ LogMsgPrefix(LogSeverity severity, const char* pFile, int line)
+ : Severity(severity), File(pFile), Line(line) {}
+
+private:
+
+ static const char* SeverityToString(LogSeverity sev);
+
+ const LogSeverity Severity;
+ const char* const File;
+ const int Line;
+};
+
+
+// *************************************************************************************************
+// Stream Formatters
+// *************************************************************************************************
+
+// Print a boolean value as a string
+struct BoolStr
+{
+ explicit BoolStr(bool value): Value(value) {}
+ const bool Value;
+};
+
+inline std::ostream& operator<<(std::ostream& os, const BoolStr& boolStr)
+{
+ return os << std::boolalpha << boolStr.Value << std::noboolalpha;
+}
+
+// *************************************************************************************************
+
+// Print a string while displaying newline characters
+struct PlainStr
+{
+ explicit PlainStr(const std::string& value): Value(value) {}
+ const std::string& Value;
+};
+
+inline std::ostream& operator<<(std::ostream& os, const PlainStr& plainStr)
+{
+ for (std::string::const_iterator it = plainStr.Value.begin(); it != plainStr.Value.end(); ++it)
+ {
+ switch (*it)
+ {
+ case '\r': os << "\\r"; break;
+ case '\n': os << "\\n"; break;
+ case '\t': os << "\\t"; break;
+ default: os << *it; break;
+ }
+ }
+
+ return os;
+}
+
+
+#endif
diff --git a/debug-tools/remoteserver/file_reader.cpp b/debug-tools/remoteserver/file_reader.cpp
new file mode 100644
index 0000000..3e08e73
--- /dev/null
+++ b/debug-tools/remoteserver/file_reader.cpp
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "file_reader.h"
+#include "debug.h"
+
+#include <cstring>
+#include <cerrno>
+#include <stdio.h>
+
+// *************************************************************************************************
+
+FileReader::FileReader(const char* pFileName)
+ : m_FileName(pFileName)
+ , m_pFile(NULL)
+ , m_FileSize(0)
+ , m_ReadTillNow(0)
+ , m_IsCompleted(false)
+ , m_IsError(false)
+{
+ if (NULL == pFileName)
+ {
+ LOG_ERROR << "No file name provided" << std::endl;
+ return;
+ }
+
+ LOG_DEBUG << "Opening file reader for: " << m_FileName << std::endl;
+ m_pFile = fopen(pFileName, "rb");
+
+ if (NULL == m_pFile)
+ {
+ int lastErrno = errno;
+ LOG_ERROR << "Error opening file."
+ << " Name: " << pFileName
+ << " Error: " << lastErrno
+ << " Message: " << strerror(lastErrno)
+ << std::endl;
+ return;
+ }
+
+ fseek (m_pFile, 0, SEEK_END);
+ m_FileSize = ftell(m_pFile);
+ rewind(m_pFile);
+
+ LOG_DEBUG <<"Get file size for " << pFileName << ": " << m_FileSize << "B" << std::endl;
+}
+
+// *************************************************************************************************
+
+FileReader::~FileReader()
+{
+ if (m_pFile)
+ {
+ LOG_DEBUG << "Closing the file: " << m_FileName << std::endl;
+ fclose (m_pFile);
+ m_pFile = NULL;
+ }
+}
+
+// *************************************************************************************************
+
+bool FileReader::CanReadFromFile(char* pBuf, size_t availableSpace)
+{
+ if (!pBuf)
+ {
+ LOG_ERROR << "Cannot read from file " << m_FileName << ": "
+ << "No buffer is provided" << std::endl;
+ return false;
+ }
+
+ if (0 == availableSpace)
+ {
+ LOG_ERROR << "Cannot read from file " << m_FileName << ": "
+ << "No buffer space is provided" << std::endl;
+ return false;
+ }
+
+ if (NULL == m_pFile)
+ {
+ LOG_ERROR << "Cannot read from file " << m_FileName << ": "
+ << "No file handle is available" << std::endl;
+ return false;
+ }
+
+ if (m_IsCompleted)
+ {
+ LOG_ERROR << "Unexpected read from file " << m_FileName << ": "
+ << "EoF is reached" << std::endl;
+ return false;
+ }
+
+ if (m_IsError)
+ {
+ LOG_ERROR << "Unexpected read from file " << m_FileName << ": "
+ << "Error occured" << std::endl;
+ return false;
+ }
+
+ return true;
+
+}
+
+// *************************************************************************************************
+
+size_t FileReader::ReadChunk(char* pBuf, size_t availableSpace)
+{
+ LOG_DEBUG << "Reading a chunk."
+ << " File Name: " << m_FileName
+ << " File Size: " << m_FileSize << "B"
+ << " Read till now: " << m_ReadTillNow << "B"
+ << " Buffer: " << availableSpace << "B"
+ << " Completed: " << BoolStr(m_IsCompleted)
+ << " Error: " << BoolStr(m_IsError)
+ << std::endl;
+
+ if (false == CanReadFromFile(pBuf, availableSpace))
+ {
+ LOG_ERROR << "Cannot read from file: " << m_FileName
+ << " Check previous errors/status" << std::endl;
+ m_IsError = true;
+ return 0;
+ }
+
+ // Read up to availableSpace. Reading less means either EoF is reached or read error occured
+ size_t readBytes = fread(pBuf, 1, availableSpace, m_pFile);
+ m_ReadTillNow += readBytes;
+
+ if (feof(m_pFile))
+ {
+ LOG_DEBUG << "EOF reached" << std::endl;
+ m_IsCompleted = true;
+ }
+
+ if (ferror(m_pFile))
+ {
+ int lastErrno = errno;
+ m_IsError = true;
+ LOG_ERROR << "Cannot read file"
+ << " Name: " << m_FileName
+ << " Error: " << lastErrno
+ << " Message:" << strerror(lastErrno)
+ << std::endl;
+ }
+
+ LOG_VERBOSE << "Got a chunk."
+ << " File Name: " << m_FileName
+ << " File Size: " << m_FileSize << "B"
+ << " Read till now: " << m_ReadTillNow << "B"
+ << " Buffer: " << availableSpace << "B"
+ << " Completed: " << BoolStr(m_IsCompleted)
+ << " Error: " << BoolStr(m_IsError)
+ << std::endl;
+
+ return readBytes;
+
+}
diff --git a/debug-tools/remoteserver/file_reader.h b/debug-tools/remoteserver/file_reader.h
new file mode 100644
index 0000000..2b7b12f
--- /dev/null
+++ b/debug-tools/remoteserver/file_reader.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _FILE_READER_H_
+#define _FILE_READER_H_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string>
+
+// *************************************************************************************************
+
+// Reads a file from the file system and exports its content to a buffer provided by the caller.
+// If the file is larger than a provide bugffer, it is delivered by chunks of the buffer size.
+// The last chunk may occupy less than the whole buffer. It's a caller's responsibility to allocate
+// the buffer and call the FileReader API untill the file is fully exported.
+
+class FileReader
+{
+public:
+
+ explicit FileReader(const char* pFileName);
+ ~FileReader();
+
+ size_t ReadChunk(char* pBuf, size_t availableSpace);
+
+ bool IsCompleted() const { return m_ReadTillNow == m_FileSize; }
+ bool IsError() const { return m_IsError; }
+
+ size_t ReadTillNow() const { return m_ReadTillNow; }
+ size_t GetFileSize() const { return m_FileSize; }
+
+private:
+
+ bool CanReadFromFile(char* pBuf, size_t availableSpace);
+
+ const std::string m_FileName; // File name - cached for tracing
+ FILE* m_pFile; // File Handler - open for read
+ size_t m_FileSize; // File Size
+ size_t m_ReadTillNow; // Bytes read till now
+ bool m_IsCompleted; // Set to true when OEF is reached
+ bool m_IsError; // Error flag
+
+};
+
+
+#endif // _FILE_READER_H_
diff --git a/debug-tools/remoteserver/main.cpp b/debug-tools/remoteserver/main.cpp
new file mode 100644
index 0000000..dae1030
--- /dev/null
+++ b/debug-tools/remoteserver/main.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <unistd.h> // getopt
+#include <stdlib.h> // atoi
+#include <signal.h> // SIGQUIT handling
+#include "parser.h"
+#include "server.h"
+#include "udp_server.h"
+#include "debug.h"
+
+#define WILSERVER_VERSION 0x0100
+#define DEFAULT_SERVER_PORT 12348
+#define DEFAULT_UDP_LOCAL_SERVER_PORT_IN 12349
+#define DEFAULT_UDP_REMOTE_SERVER_PORT_IN 12350
+
+UdpServer us;
+Server s;
+
+void sig_quit_handler(int signum)
+{
+ if (signum == SIGQUIT)
+ {
+ printf("Exiting Wilserver as per user request\n");
+ us.stop();
+ s.stop();
+ exit(signum);
+ }
+}
+
+int main(int argc, char* argv[])
+{
+ // Register for SIGQUIT signal
+ signal(SIGQUIT, sig_quit_handler);
+
+ int opt;
+ int port=DEFAULT_SERVER_PORT;
+ int localUdpPortIn = DEFAULT_UDP_LOCAL_SERVER_PORT_IN;
+ int remoteUdpPortIn = DEFAULT_UDP_REMOTE_SERVER_PORT_IN;
+ int traceLevel = LOG_SEV_WARNING;
+
+ while ((opt = getopt(argc, argv, "d:vp:")) != -1) {
+ switch (opt) {
+ case 'd':
+ traceLevel = atoi(optarg);
+ g_LogConfig.SetMaxSeverity(traceLevel);
+ break;
+ case 'p':
+ port = atoi(optarg);
+ if(port == 0) {
+ LOG_ERROR << "Invalid port specified" << optarg << std::endl;
+ exit(EXIT_FAILURE);
+ }
+ break;
+ default:
+ fprintf(stderr, "Usage: %s [-d debug_level] | [-p port]\n", argv[0]);
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ LOG_INFO << "Starting WIGIG Remote Server" << std::endl;
+ us.start(localUdpPortIn, remoteUdpPortIn);
+ s.start(port);
+ return 0;
+}
+
+
diff --git a/debug-tools/remoteserver/parser.h b/debug-tools/remoteserver/parser.h
new file mode 100644
index 0000000..112f90f
--- /dev/null
+++ b/debug-tools/remoteserver/parser.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __parser_h
+#define __parser_h
+
+#include "servercmd.h"
+
+
+int parse_line(const char *line, servercmd_t *s);
+
+#endif /* __parser_h */
diff --git a/debug-tools/remoteserver/parser.l b/debug-tools/remoteserver/parser.l
new file mode 100644
index 0000000..e4d0507
--- /dev/null
+++ b/debug-tools/remoteserver/parser.l
@@ -0,0 +1,211 @@
+%{
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "servercmd.h"
+
+static int acc_byte = 0;
+static int acc_len = 0;
+
+%}
+%option noyywrap
+%option nounput
+/* We need reentratnt scanner for multiple connections */
+%option reentrant
+/* %option c++ */
+%x str
+DIGIT [0-9]
+HEXDIGIT [0-9A-Fa-f]
+
+ID [A-Za-z_!][A-Za-z_!0-9]*
+
+%%
+"get_interfaces" {
+ if(cb_cmd(yyextra, CMD_GET_INTERFACES))
+ yyterminate();
+ }
+"open_interface" {
+ if(cb_cmd(yyextra, CMD_OPEN_INTERFACE))
+ yyterminate();
+ }
+"close_interface" {
+ if(cb_cmd(yyextra, CMD_CLOSE_INTERFACE))
+ yyterminate();
+ }
+"r" {
+ if(cb_cmd(yyextra, CMD_R))
+ yyterminate();
+ }
+"rb" {
+ if(cb_cmd(yyextra, CMD_RB))
+ yyterminate();
+ }
+"w" {
+ if(cb_cmd(yyextra, CMD_W))
+ yyterminate();
+ }
+"wb" {
+ if(cb_cmd(yyextra, CMD_WB))
+ yyterminate();
+ }
+"alloc_pmc" {
+ if(cb_cmd(yyextra, CMD_ALLOC_PMC))
+ yyterminate();
+ }
+"read_pmc" {
+ if(cb_cmd(yyextra, CMD_READ_PMC))
+ yyterminate();
+ }
+"read_pmc_file" {
+ if(cb_cmd(yyextra, CMD_READ_PMC_FILE))
+ yyterminate();
+ }
+"interface_reset" {
+ if(cb_cmd(yyextra, CMD_INTERFACE_RESET))
+ yyterminate();
+ }
+
+"sw_reset" {
+ if(cb_cmd(yyextra, CMD_SW_RESET))
+ yyterminate();
+ }
+"exit" {
+ if(cb_cmd(yyextra, CMD_EXIT))
+ yyterminate();
+ }
+"set_host_alias" {
+ if(cb_cmd(yyextra, CMD_SET_HOST_ALIAS))
+ yyterminate();
+ }
+{DIGIT}+ {
+ /* A decimal number represents the address/value */
+ if(cb_number(yyextra, yytext))
+ yyterminate();
+ }
+
+{ID} {
+ /* The protocol doesn't separate between interface id and command */
+ if(cb_id(yyextra, yytext))
+ yyterminate();
+ }
+\" {
+ /* Start of string */
+ BEGIN(str);
+ acc_byte = 0;
+ acc_len = 0;
+ }
+<str>\" {
+ /* End of string */
+ if(acc_len > 0) {
+ if(cb_hexbyte(yyextra, acc_byte))
+ yyterminate();
+ }
+ /* Callback for end of hex string */
+ if(cb_endhex(yyextra))
+ yyterminate();
+ BEGIN(INITIAL);
+ }
+<str>{HEXDIGIT} {
+ /* We get hex bytes in the string */
+ if(acc_len == 10) {
+ cb_error(yyextra, ERR_BAD_HEX_VALUE, "");
+ yyterminate();
+ }else if(acc_len <= 1){
+ acc_len++;
+ // do nothing on the 0x
+ }
+ else {
+ acc_len++;
+ acc_byte = acc_byte * 16 + hexdigit(yytext[0]);
+ }
+ }
+<str>[ \t] {
+ /* Hex bytes separated by spaces */
+ if(acc_len > 0) {
+ if(cb_hexbyte(yyextra, acc_byte))
+ yyterminate();
+ acc_len = 0;
+ acc_byte = 0;
+ }
+ }
+<str><<EOF>> {
+ /* Check the end of string with unterminated quote */
+ cb_error(yyextra, ERR_UNTERMINATED_STRING, "");
+ yyterminate();
+ }
+<str>x {
+ /* if we ancounter 0x, remove the x and continue */
+ if(acc_len != 1){
+ cb_error(yyextra, ERR_BAD_HEX_VALUE, "");
+ }
+ acc_len++;
+ }
+<str>. {
+ /* Anything except the hex bytes is not allowed in the string parameter */
+ cb_error(yyextra, ERR_BAD_HEX_VALUE, "");
+ yyterminate();
+ }
+
+[ \t\r\n]+ {
+ /* Whitespace */
+ if(cb_separator(yyextra))
+ yyterminate();
+ }
+. {
+ cb_error(yyextra, ERR_BAD_TOKEN, yytext);
+ yyterminate();
+ }
+%%
+
+/*
+ Parses the input line
+*/
+int parse_line(const char *line, servercmd_t *s)
+{
+ yyscan_t scanner;
+ YY_BUFFER_STATE bs;
+ cb_parser_start(s);
+ yylex_init(&scanner);
+
+ if (!scanner)
+ {
+ return 1;
+ }
+
+ yyset_extra(s, scanner);
+ bs = yy_scan_string(line, scanner);
+ yylex(scanner);
+ yy_delete_buffer(bs, scanner);
+ yylex_destroy(scanner);
+ cb_parser_end(s);
+ return s->error;
+}
+
+
+
diff --git a/debug-tools/remoteserver/pmc_file.cpp b/debug-tools/remoteserver/pmc_file.cpp
new file mode 100644
index 0000000..e449739
--- /dev/null
+++ b/debug-tools/remoteserver/pmc_file.cpp
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "pmc_file.h"
+#include "debug.h"
+
+#include <cstring>
+#include <cerrno>
+#include <sstream>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+// *************************************************************************************************
+#ifdef __ANDROID__
+#define PMC_DATA_DIRECTORY "/data/pmc"
+#else
+#define PMC_DATA_DIRECTORY "/var/pmc"
+#endif
+
+// PMC directory and file name pattern should be managed separately as directory is required as a
+// separate variable.
+
+const char* const PmcFile::s_pDirectory = PMC_DATA_DIRECTORY;
+const char* const PmcFile::s_pFileNamePrefix = "pmc_data_";
+
+// *************************************************************************************************
+
+PmcFile::PmcFile(int fileId)
+ : m_FileId(fileId)
+{
+ std::stringstream ss;
+ ss << s_pDirectory << '/' << s_pFileNamePrefix << fileId;
+ m_FileName = ss.str();
+
+ LOG_DEBUG << "PMC file name #" << fileId << " generated: " << m_FileName << std::endl;
+}
+
+std::ostream& operator<<(std::ostream& os, const PmcFile& pmcFile)
+{
+ return os << "PMC file #" << pmcFile.GetFileId() << " (" << pmcFile.GetFileName() << ')';
+}
+
+// *************************************************************************************************
+
+PmcFileWriter::PmcFileWriter(const PmcFile& pmcFile)
+ : m_PmcFile(pmcFile)
+{
+}
+
+// *************************************************************************************************
+
+bool PmcFileWriter::CreateDirectoryIfNeeded() const
+{
+ // Create a PMC directory if does not exist
+ struct stat st = {};
+ if (stat(m_PmcFile.GetDirectory(), &st) != -1)
+ {
+ LOG_DEBUG << "PMC directory " << m_PmcFile.GetDirectory()
+ << " exists for " << m_PmcFile.GetFileName() << std::endl;
+ return true;
+ }
+
+ LOG_DEBUG << "Creating a PMC directory: " << m_PmcFile.GetDirectory() << std::endl;
+
+ int status = mkdir(m_PmcFile.GetDirectory(), 0700);
+ if (0 != status)
+ {
+ int lastErrno = errno;
+ LOG_ERROR << "Cannot create PMC directory."
+ << " Path: " << m_PmcFile.GetDirectory()
+ << " Error:" << lastErrno
+ << " Message: " << strerror(lastErrno)
+ << std::endl;
+
+ return false;
+ }
+
+ return true;
+}
+
+// *************************************************************************************************
+
+bool PmcFileWriter::WriteFile() const
+{
+ if (false == CreateDirectoryIfNeeded())
+ {
+ LOG_ERROR << "Cannot create a PMC directory for " << m_PmcFile << std::endl;
+ return false;
+ }
+
+ // Create a PMC file
+ const char* pCmdPrefix =
+ "D=$(find /sys/kernel/debug/ieee80211/ -name wil6210); cat $D/pmcdata >> ";
+ std::stringstream ss;
+ ss << pCmdPrefix << m_PmcFile.GetFileName();
+
+ system(ss.str().c_str());
+ return true;
+
+}
+
+// *************************************************************************************************
+
+size_t PmcFileWriter::GetFileSize() const
+{
+ FILE *pFile = fopen(m_PmcFile.GetFileName(), "r");
+
+ if (NULL == pFile)
+ {
+ int lastErrno = errno;
+ LOG_ERROR << "Cannot open " << m_PmcFile << " for writing."
+ << " Error: " << lastErrno
+ << " Message: " << strerror(lastErrno)
+ << std::endl;
+ return 0;
+ }
+
+ fseek (pFile, 0, SEEK_END);
+ size_t fileSize = ftell(pFile);
+ fclose(pFile);
+
+ LOG_DEBUG << "Get PMC file size for " << m_PmcFile
+ << ": " << fileSize << "B" << std::endl;
+
+ return fileSize;
+}
diff --git a/debug-tools/remoteserver/pmc_file.h b/debug-tools/remoteserver/pmc_file.h
new file mode 100644
index 0000000..b7af0b7
--- /dev/null
+++ b/debug-tools/remoteserver/pmc_file.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _PMC_FILE_H_
+#define _PMC_FILE_H_
+
+#include <stdio.h>
+#include <string>
+
+// *************************************************************************************************
+
+// Generates a PMC file name from its ID.
+class PmcFile
+{
+public:
+
+ explicit PmcFile(int fileId);
+
+ int GetFileId() const { return m_FileId; }
+ const char* GetFileName() const { return m_FileName.c_str(); }
+
+ static const char* GetDirectory() { return s_pDirectory; }
+
+private:
+
+ static const char* const s_pDirectory;
+ static const char* const s_pFileNamePrefix;
+
+ const int m_FileId; // File ID (expected to be unique)
+ std::string m_FileName; // File Name Buffer
+
+};
+
+std::ostream& operator<<(std::ostream& os, const PmcFile& pmcFile);
+
+// *************************************************************************************************
+
+// Creates a PMC data file according to a provided ID.
+class PmcFileWriter
+{
+public:
+
+ explicit PmcFileWriter(const PmcFile& pmcFile);
+
+ bool WriteFile() const;
+ size_t GetFileSize() const;
+
+private:
+
+ bool CreateDirectoryIfNeeded() const;
+
+ const PmcFile& m_PmcFile;
+
+};
+
+
+#endif // PMC_FILE_H_
diff --git a/debug-tools/remoteserver/server.cpp b/debug-tools/remoteserver/server.cpp
new file mode 100644
index 0000000..5ee1b48
--- /dev/null
+++ b/debug-tools/remoteserver/server.cpp
@@ -0,0 +1,319 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <cerrno>
+#include <unistd.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <fstream>
+#include "server.h"
+#include "cmdiface.h"
+#include "debug.h"
+#include "pmc_file.h"
+#include "file_reader.h"
+
+// Thread parameters structure
+typedef struct {
+ int sock;
+ struct sockaddr address;
+ int addr_len;
+} connection_par_t;
+
+volatile int Server::shutdown_flag = 0;
+volatile int Server::running_threads = 0;
+pthread_mutex_t Server::threads_counter_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+void *Server::server_process(void *ptr)
+{
+ char *buf;
+ CmdIface *iface;
+ int rw;
+
+ if(ptr == NULL)
+ {
+ pthread_exit(0);
+ }
+
+ connection_par_t *par = (connection_par_t*)ptr;
+ iface = new CmdIface();
+ buf = new char[MAX_INPUT_BUF+1];
+ memset(buf, 0, MAX_INPUT_BUF+1);
+ rw = read(par->sock, buf, MAX_INPUT_BUF);
+
+ while(rw > 0)
+ {
+ // Got some data
+ if(rw)
+ {
+ buf[rw] = '\0';
+ LOG_INFO << "Client Command: " << PlainStr(buf) << std::endl;
+ int cmdKeepalive = iface->do_command((const char*)buf, rw);
+ LOG_DEBUG << "Command handling keepalive: " << cmdKeepalive << std::endl;
+
+ // Check for keepalive return value
+ int replyKeepalive = reply(par->sock, iface);
+
+ if(cmdKeepalive == KEEPALIVE_CLOSE || replyKeepalive == KEEPALIVE_CLOSE)
+ {
+ // Handler asked to close the connection
+ rw = 0;
+ break;
+ }
+ }
+ rw = read(par->sock, buf, MAX_INPUT_BUF);
+ }
+
+ // if 0 - connection is closed, <0 - error
+ LOG_DEBUG << "Closing connection. Read result: " << rw << std::endl;
+ close(par->sock);
+ delete[] buf;
+ delete iface;
+ delete par;
+ pthread_mutex_lock(&threads_counter_mutex);
+ running_threads--;
+ pthread_mutex_unlock(&threads_counter_mutex);
+ pthread_exit(0);
+}
+
+int Server::reply(int sock, CmdIface* iface)
+{
+ LOG_INFO << "Reply: " << PlainStr(iface->get_reply()) << std::endl;
+
+ switch (iface->get_reply_type())
+ {
+ case REPLY_TYPE_BUFFER:
+ return reply_buffer(sock, iface->get_reply(), iface->get_reply_len());
+
+ case REPLY_TYPE_FILE:
+ return reply_file(sock, iface->get_reply());
+
+ default:
+ LOG_ERROR << "Unexpected reply type: " << iface->get_reply_type() << std::endl;
+ return KEEPALIVE_CLOSE;
+ }
+}
+
+int Server::reply_buffer(int sock, const char* pBuf, size_t len)
+{
+ LOG_DEBUG << "Replying from a buffer (" << len << "B) Content: " << PlainStr(pBuf) << std::endl;
+
+ if (0 == len)
+ {
+ LOG_ERROR << "No reply generated by a command handler - connection will be closed" << std::endl;
+ return KEEPALIVE_CLOSE;
+ }
+
+ if (false == send_buffer(sock, pBuf, len))
+ {
+ return KEEPALIVE_CLOSE;
+ }
+
+ return KEEPALIVE_OK;
+}
+
+int Server::reply_file(int sock, const char* pFileName)
+{
+ LOG_DEBUG << "Replying from a file: " << pFileName << std::endl;
+
+ FileReader fileReader(pFileName);
+ size_t fileSize = fileReader.GetFileSize();
+
+ if (0 == fileSize)
+ {
+ LOG_ERROR << "No file content is available for reply" << std::endl;
+ return KEEPALIVE_CLOSE;
+ }
+
+ static const size_t BUF_LEN = 64 * 1024;
+
+ char* pBuf = new char[BUF_LEN];
+ size_t chunkSize = 0;
+ bool isError = false;
+
+ do
+ {
+ LOG_VERBOSE << "Requesting for a file chunk" << std::endl;
+
+ chunkSize = fileReader.ReadChunk(pBuf, BUF_LEN);
+ if (chunkSize > 0)
+ {
+ if (false == send_buffer(sock, pBuf, chunkSize))
+ {
+ LOG_ERROR << "Send error detected" << std::endl;
+ isError = true;
+ break;
+ }
+ }
+
+ // Error/Completion may occur with non-zero chunk as well
+ if (fileReader.IsError())
+ {
+ LOG_ERROR << "File read error detected" << std::endl;
+ isError = true;
+ break;
+ }
+
+ if (fileReader.IsCompleted())
+ {
+ LOG_DEBUG << "File completion detected" << std::endl;
+ break;
+ }
+
+ LOG_DEBUG << "File Chunk Delivered: " << chunkSize << "B" << std::endl;
+ }
+ while (chunkSize > 0);
+
+ delete[] pBuf;
+
+ if (isError)
+ {
+ LOG_ERROR << "Error occured while replying file content" << std::endl;
+ return KEEPALIVE_CLOSE;
+ }
+ else
+ {
+ LOG_DEBUG << "File Content successfully delivered" << std::endl;
+ return KEEPALIVE_OK;
+ }
+}
+
+bool Server::send_buffer(int sock, const char* pBuf, size_t len)
+{
+ if (!pBuf)
+ {
+ LOG_ERROR << "Cannot reply to a command - No buffer is provided" << std::endl;
+ return false;
+ }
+
+ size_t sentTillNow = 0;
+
+ while(sentTillNow < len)
+ {
+ ssize_t sentBytes = write(sock, pBuf, len);
+ if (sentBytes < 0)
+ {
+ int lastErrno = errno;
+ LOG_ERROR << "Cannot send response buffer."
+ << " Error:" << lastErrno
+ << " Message: " << strerror(lastErrno)
+ << std::endl;
+ return false;
+ }
+
+ sentTillNow += sentBytes;
+ LOG_DEBUG << "Sent response chunk."
+ << " Chunk Size: " << sentBytes
+ << " Sent till now: " << sentTillNow
+ << " Response Length: " << len
+ << std::endl;
+ }
+
+ LOG_DEBUG << "Response buffer fully sent" << std::endl;
+ return true;
+}
+
+/*
+ Close the server to allow un-bind te socket - allowing future connections without delay
+*/
+int Server::stop()
+{
+ LOG_INFO << "Stopping the server" << std::endl;
+ shutdown(sock, SHUT_RDWR);
+ return 0;
+}
+
+/*
+ Initialize server on the given port. The function returns in case of error,
+ otherwise it doesn't return
+*/
+int Server::start(int port)
+{
+ LOG_INFO << "Starting the server on port " << port << std::endl;
+
+ struct sockaddr_in address;
+ sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+
+ if(sock < 0)
+ {
+ LOG_ERROR << "Cannot create a socket on port " << port << std::endl;
+ return -1;
+ }
+
+ address.sin_family = AF_INET;
+ address.sin_addr.s_addr = INADDR_ANY;
+ address.sin_port = htons(port);
+
+ // Set the "Re-Use" socket option - allows reconnections after wilserver exit
+ int reuse = 1;
+ setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(int));
+
+ if(bind(sock, (struct sockaddr *)&address, sizeof(struct sockaddr_in)) < 0)
+ {
+ LOG_ERROR << "Cannot bind socket to port " << port << std::endl;
+ return -2;
+ }
+
+ if (listen(sock, 5) < 0)
+ {
+ LOG_ERROR << "Cannot listen on port " << port << std::endl;
+ return -3;
+ }
+
+ shutdown_flag = 0;
+ while (shutdown_flag == 0) {
+ pthread_t thread;
+ connection_par_t *par = new connection_par_t;
+ par->sock = accept(sock, &par->address, (socklen_t*)&par->addr_len);
+ if(par->sock < 0)
+ delete par;
+ else {
+ pthread_mutex_lock(&threads_counter_mutex);
+ running_threads++;
+ pthread_mutex_unlock(&threads_counter_mutex);
+ pthread_create(&thread, 0, &Server::server_process, (void *)par);
+ pthread_detach(thread);
+ }
+
+ }
+ // Wait till all the threads are done in case we ever exit the loop above
+ while(running_threads > 0)
+ sleep(1);
+
+ LOG_INFO << "Server shutdown" << std::endl;
+
+ return 0; // Wont get here, just to avoid the warning
+}
diff --git a/debug-tools/remoteserver/server.h b/debug-tools/remoteserver/server.h
new file mode 100644
index 0000000..01cd080
--- /dev/null
+++ b/debug-tools/remoteserver/server.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __server_h
+#define __server_h
+#include <pthread.h>
+#include <string>
+
+class CmdIface;
+
+class Server
+{
+public:
+
+ int start(int port);
+ int stop();
+
+ static int get_shutdown_flag() { return shutdown_flag; }
+
+
+private:
+
+ static volatile int shutdown_flag;
+ static volatile int running_threads;
+ static pthread_mutex_t threads_counter_mutex;
+ int sock;
+
+ static void *server_process(void *ptr);
+ static bool send_buffer(int sock, const char* pBuf, size_t len);
+ static int reply(int sock, CmdIface* iface);
+ static int reply_buffer(int sock, const char* pBuf, size_t len);
+ static int reply_file(int sock, const char* pFileName);
+};
+
+#endif // server_h
+
diff --git a/debug-tools/remoteserver/servercmd.cpp b/debug-tools/remoteserver/servercmd.cpp
new file mode 100644
index 0000000..bfc180b
--- /dev/null
+++ b/debug-tools/remoteserver/servercmd.cpp
@@ -0,0 +1,336 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sstream>
+
+#include "servercmd.h"
+#include "debug.h"
+
+#define EXP_NON 0
+#define EXP_CMD (-1)
+#define EXP_IFC 1
+#define EXP_NUM 2
+#define EXP_HEX 3
+#define EXP_SEP 4
+#define EXP_END 5
+
+const char* parser_state_to_string(int parserState)
+{
+ switch (parserState)
+ {
+ case EXP_NON: return "EXP_NON";
+ case EXP_CMD: return "EXP_CMD";
+ case EXP_IFC: return "EXP_IFC";
+ case EXP_NUM: return "EXP_NUM";
+ case EXP_HEX: return "EXP_HEX";
+ case EXP_SEP: return "EXP_SEP";
+ case EXP_END: return "EXP_END";
+ default: return "<unknown>";
+ }
+}
+
+
+static int states_table[][5] =
+{
+ { EXP_END, 0, 0, 0, 0 }, // 0 - get_interfaces
+ { EXP_IFC, EXP_END, 0, 0, 0 }, // 1 - open_interface name
+ { EXP_IFC, EXP_END, 0, 0, 0 }, // 2 - close_interface name
+ { EXP_IFC, EXP_NUM, EXP_END, 0, 0 }, // 3 - r name address
+ { EXP_IFC, EXP_NUM, EXP_NUM, EXP_END, 0 }, // 4 - rb name address count
+ { EXP_IFC, EXP_NUM, EXP_NUM, EXP_END, 0 }, // 5 - w name address value
+ { EXP_IFC, EXP_NUM, EXP_HEX, EXP_END, 0 }, // 6 - wb name address hexstring
+ { EXP_IFC, EXP_END, 0, 0, 0 }, // 7 - interface_reset name
+ { EXP_IFC, EXP_END, 0, 0, 0 }, // 8 - sw_reset name
+ { EXP_END, 0, 0, 0, 0 }, // 9 - exit
+ { EXP_IFC, EXP_NUM, EXP_NUM, EXP_END, 0 }, // 10 - Alloc_PMC name number_of_descriptors size_of_descriptors
+ { EXP_IFC, EXP_NUM, EXP_END, 0, 0 }, // 11 - read_pmc interface requestReferenceNumber
+ { EXP_NUM, EXP_END, 0, 0, 0 }, // 12 - read_pmc_file requestReferenceNumber
+ { EXP_IFC, EXP_END, 0, 0, 0 }, // 13 - set_host_alias
+};
+
+
+// The return value is copied because std::stringstream::str() returns a temporary object
+std::string parser_state_machine_to_string(int* pStateMachine)
+{
+ if (!pStateMachine)
+ {
+ return std::string("{}");
+ }
+
+ std::stringstream ss;
+
+ ss << "{ ";
+
+ size_t numStates = sizeof(states_table[0])/sizeof(int);
+ for (size_t i = 0; i < numStates; ++i)
+ {
+ ss << parser_state_to_string(pStateMachine[i]) << " ";
+ }
+ ss << "}";
+
+ return ss.str();
+}
+
+
+const char* command_to_string(int cmdCode)
+{
+ switch (cmdCode)
+ {
+ case CMD_COMMAND_UNKNOWN: return "CMD_COMMAND_UNKNOWN";
+ case CMD_GET_INTERFACES: return "CMD_GET_INTERFACES";
+ case CMD_OPEN_INTERFACE: return "CMD_OPEN_INTERFACE";
+ case CMD_CLOSE_INTERFACE: return "CMD_CLOSE_INTERFACE";
+ case CMD_R: return "CMD_R";
+ case CMD_RB: return "CMD_RB";
+ case CMD_W: return "CMD_W";
+ case CMD_WB: return "CMD_WB";
+ case CMD_INTERFACE_RESET: return "CMD_INTERFACE_RESET";
+ case CMD_SW_RESET: return "CMD_SW_RESET";
+ case CMD_EXIT: return "CMD_EXIT";
+ case CMD_ALLOC_PMC: return "CMD_ALLOC_PMC";
+ case CMD_READ_PMC: return "CMD_READ_PMC";
+ case CMD_READ_PMC_FILE: return "CMD_READ_PMC_FILE";
+ case CMD_SET_HOST_ALIAS: return "CMD_SET_HOST_ALIAS";
+ default: return "<unknown>";
+ }
+}
+
+
+const char* parser_error_to_string(int parserError)
+{
+ switch (parserError)
+ {
+ case ERR_BAD_TOKEN: return "ERR_BAD_TOKEN";
+ case ERR_BAD_VALUE: return "VALUE";
+ case ERR_UNTERMINATED_STRING: return "ERR_UNTERMINATED_STRING";
+ case ERR_BAD_HEX_VALUE: return "ERR_BAD_HEX_VALUE";
+ case ERR_CMD_NOT_EXPECTED: return "ERR_CMD_NOT_EXPECTED";
+ case ERR_IFACE_NOT_EXPECTED: return "ERR_IFACE_NOT_EXPECTED";
+ case ERR_VALUE_NOT_EXPECTED: return "ERR_VALUE_NOT_EXPECTED";
+ case ERR_HEX_NOT_EXPECTED: return "ERR_HEX_NOT_EXPECTED";
+ case ERR_END_NOT_EXPECTED: return "ERR_END_NOT_EXPECTED";
+ default: return "<unknown>";
+ }
+}
+
+
+
+/*
+ Callback on parser start.
+ Returns the handler to be used in all subsequent callbacks
+ or NULL in case of error, the parsing will be aborted then
+*/
+void cb_parser_start(servercmd_t *s)
+{
+ s->states = NULL;
+ s->state = EXP_CMD; // We start with expecting a command
+ s->cmd = CMD_COMMAND_UNKNOWN;
+ s->error = 0;
+ s->address = (unsigned int)-1;
+ s->value = (unsigned int)-1;
+ s->hexdata_len = 0;
+ s->hexdata = (unsigned int*)malloc (sizeof(int)*MAX_REGS_LEN);
+}
+
+/*
+ Callback on a command. Gets the command code.
+ Returns 0 if ok, 1 if error, the parsing will be aborted then
+*/
+int cb_cmd(servercmd_t *s, int cmd)
+{
+ LOG_VERBOSE <<"cb_cmd(" << cmd << ") state index = " << s->state << std::endl;
+ LOG_VERBOSE << "State Machine: " << parser_state_machine_to_string(s->states) << std::endl;
+
+ if(s->state != EXP_CMD) {
+ s->error = ERR_CMD_NOT_EXPECTED;
+ LOG_ERROR << "Command not expected, expecting " << s->state << std::endl;
+ return -1;
+ }
+ LOG_VERBOSE << "Parsed Command: " << cmd << "(" << command_to_string(cmd) << ")" << std::endl;
+ s->cmd = cmd;
+ s->states = states_table[cmd];
+ s->state++;
+
+ return 0;
+}
+
+
+/*
+ Returns 0 if ok, 1 if error, the parsing will be aborted then
+*/
+int cb_id(servercmd_t *s, const char *id)
+{
+ LOG_VERBOSE << "cb_id(" << id << ") state index = " << s->state << std::endl;
+ LOG_VERBOSE << "State Machine: " << parser_state_machine_to_string(s->states) << std::endl;
+
+ if((s->states == NULL) || (s->states[s->state] != EXP_IFC)) {
+ s->error = ERR_IFACE_NOT_EXPECTED;
+ LOG_ERROR << "Interface not expected, expecting: "
+ << (s->states?s->states[s->state]:-1) << std::endl;
+ return -1;
+ }
+
+ LOG_VERBOSE << "Interface id: " << id << std::endl;
+ snprintf(s->interface, MAX_INTERFACE_NAME, "%s", id);
+ s->state++;
+ return 0;
+}
+
+/*
+ Returns 0 if ok, 1 if error, the parsing will be aborted then
+*/
+int cb_number(servercmd_t *s, const char *id)
+{
+ LOG_VERBOSE << "cb_number(" << id << ") state index = " << s->state << std::endl;
+ LOG_VERBOSE << "State Machine: " << parser_state_machine_to_string(s->states) << std::endl;
+
+ if((s->states == NULL) || (s->states[s->state] != EXP_NUM)) {
+ s->error = ERR_VALUE_NOT_EXPECTED;
+ LOG_ERROR << "Number not expected, expecting " << (s->states?s->states[s->state]:-1) << std::endl;
+ return -1;
+ }
+
+ // A hack now. if address already set, the number is for data
+ LOG_VERBOSE << "string number " << id << std::endl;
+
+ if(s->address != (unsigned int)-1){
+ sscanf(id, "%u", &(s->value));
+ //s->value = strtoul(id, tmp, 10); //10 is the base for conversion
+ // dprint("str to uint Parsed val %u\n", strtoul(id, tmp, 10));
+ // dprint("str to int Parsed val %u\n", atol(id));//s->value = atol(id);
+ LOG_VERBOSE << "scanf Parsed value: " << s->value << std::endl;
+ }
+ else{
+ // s->address = atol(id);
+ sscanf(id, "%u", &(s->address));
+ LOG_VERBOSE << "Parsed addr " << s->address << std::endl;
+ }
+ s->state++;
+ return 0;
+}
+
+/*
+ Callback on hex data
+ Returns 0 if ok, 1 if error, the parsing will be aborted then
+*/
+int cb_hexbyte(servercmd_t *s, int b)
+{
+ LOG_VERBOSE << "cb_hexbyte(0x" << std::hex << b << std::dec << ") state index = " << s->state << std::endl;
+ LOG_VERBOSE << "State Machine: " << parser_state_machine_to_string(s->states) << std::endl;
+
+ if((s->states == NULL) || (s->states[s->state] != EXP_HEX)) {
+ s->error = ERR_HEX_NOT_EXPECTED;
+ LOG_ERROR << "Hex not expected, expecting " << (s->states?s->states[s->state]:-1) << std::endl;
+ return -1;
+ }
+ if(s->hexdata_len == MAX_REGS_LEN) {
+ s->error = ERR_BAD_HEX_VALUE;
+ LOG_ERROR << "Too long hex data" << std::endl;
+ return -1;
+ }
+ LOG_VERBOSE << "Hex byte 0x" << std::hex << b << std::dec << std::endl;
+ s->hexdata[s->hexdata_len] = b;
+ s->hexdata_len++;
+ // Do not change the s->state here, we are still expecting hex data. cb_endhex will change the state
+ return 0;
+}
+
+/*
+ Callback on end of hex data string
+ Returns 0 if ok, 1 if error, the parsing will be aborted then
+*/
+
+int cb_endhex(servercmd_t *s)
+{
+ LOG_VERBOSE << "cb_endhex() state index = " << s->state << std::endl;
+ LOG_VERBOSE << "State Machine: " << parser_state_machine_to_string(s->states) << std::endl;
+
+ if((s->states == NULL) || (s->states[s->state] != EXP_HEX)) {
+ s->error = ERR_HEX_NOT_EXPECTED;
+ LOG_ERROR << "Hex not expected, expecting " << (s->states?s->states[s->state]:-1) << std::endl;
+ return -1;
+ }
+ s->state++;
+ return 0;
+}
+
+/*
+ Callback on a separator, not used.
+ Returns 0 if ok, 1 if error, the parsing will be aborted then
+*/
+int cb_separator(servercmd_t *s)
+{
+ (void)s;
+ return 0;
+}
+
+/*
+ Callback on the parser end
+ Returns the parser result: 0 if ok, error otherwise
+*/
+void cb_parser_end(servercmd_t *s)
+{
+ LOG_VERBOSE << "cb_parser_end() state index = " << s->state << std::endl;
+ LOG_VERBOSE << "State Machine: " << parser_state_machine_to_string(s->states) << std::endl;
+
+ if((s->error == 0) && ((s->states == NULL) || (s->states[s->state] != EXP_END))) {
+ LOG_ERROR << "End of parser while still expecting " << (s->states?s->states[s->state]:-1) << std::endl;
+ s->error = ERR_END_NOT_EXPECTED;
+ }
+
+ free(s->hexdata);
+}
+
+/*
+ Callback on parser error
+*/
+void cb_error(servercmd_t *s, int error, const char *str)
+{
+ (void)str;
+ s->error = error;
+ LOG_ERROR << "Parser error: " << error << std::endl;
+}
+
+/*
+ Service function. Converting a hex digit from a character.
+*/
+int hexdigit(char d)
+{
+ if((d >= '0') && (d <= '9'))
+ return d-'0';
+ else if((d >= 'A') && (d <= 'F'))
+ return d-'A'+10;
+ else if((d >- 'a') && (d <= 'f'))
+ return d-'a'+10;
+ else // This shouldn't happen, it's the parser's responsibility to parse valid hex digits
+ return 0;
+}
diff --git a/debug-tools/remoteserver/servercmd.h b/debug-tools/remoteserver/servercmd.h
new file mode 100644
index 0000000..c63e3c7
--- /dev/null
+++ b/debug-tools/remoteserver/servercmd.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __servercmd_h
+#define __servercmd_h
+
+// This header is included by the parser, which is flex-generated C code
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Commands list
+#define CMD_COMMAND_UNKNOWN (-1)
+#define CMD_GET_INTERFACES 0
+#define CMD_OPEN_INTERFACE 1
+#define CMD_CLOSE_INTERFACE 2
+#define CMD_R 3
+#define CMD_RB 4
+#define CMD_W 5
+#define CMD_WB 6
+#define CMD_INTERFACE_RESET 7
+#define CMD_SW_RESET 8
+#define CMD_EXIT 9 // debug command
+#define CMD_ALLOC_PMC 10
+#define CMD_READ_PMC 11
+#define CMD_READ_PMC_FILE 12
+#define CMD_SET_HOST_ALIAS 13
+
+
+const char* command_to_string(int cmdCode);
+
+#define MAX_INTERFACE_NAME 32 // TODO: better to include WlctPciAcss.h that defines MAX_IF_NAME_LENGTH==32
+#define MAX_REGS_LEN (256* 1024) // Max registers to read/write at once
+
+// Parser errors
+#define ERR_BAD_TOKEN (-1)
+#define ERR_BAD_VALUE (-2)
+#define ERR_UNTERMINATED_STRING (-3)
+#define ERR_BAD_HEX_VALUE (-4)
+#define ERR_CMD_NOT_EXPECTED (-5)
+#define ERR_IFACE_NOT_EXPECTED (-6)
+#define ERR_VALUE_NOT_EXPECTED (-7)
+#define ERR_HEX_NOT_EXPECTED (-8)
+#define ERR_END_NOT_EXPECTED (-9)
+
+const char* parser_error_to_string(int parserError);
+
+
+/*
+ Parser result/state structure
+*/
+typedef struct {
+ int state;
+ int cmd;
+ int *states;
+ char interface[MAX_INTERFACE_NAME+1];
+ unsigned int address;
+ unsigned int value;
+ unsigned int* hexdata;
+ int hexdata_len;
+ int error;
+} servercmd_t;
+
+
+
+/*
+ Parser callbacks
+*/
+void cb_parser_start(servercmd_t *s);
+int cb_cmd(servercmd_t *s, int cmd);
+int cb_id(servercmd_t *s, const char *id);
+int cb_number(servercmd_t *s, const char *id);
+int cb_hexbyte(servercmd_t *s, int b);
+int cb_endhex(servercmd_t *s);
+int cb_separator(servercmd_t *s);
+void cb_parser_end(servercmd_t *s);
+void cb_error(servercmd_t *s, int error, const char *str);
+
+/* helper functions */
+int hexdigit(char d);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // servercmd_h
diff --git a/debug-tools/remoteserver/udp_server.cpp b/debug-tools/remoteserver/udp_server.cpp
new file mode 100644
index 0000000..64c161d
--- /dev/null
+++ b/debug-tools/remoteserver/udp_server.cpp
@@ -0,0 +1,295 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <cerrno>
+#include <unistd.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <fstream>
+#include "server.h"
+#include "cmdiface.h"
+#include "debug.h"
+#include "pmc_file.h"
+#include "file_reader.h"
+#include "udp_server.h"
+
+const std::string UdpServer::local_host = "127.0.0.1";
+const std::string UdpServer::host_details_file_name = "/etc/wigig_remoteserver_details";
+const std::string UdpServer::cmd_get_host_identity = "GetHostIdentity";
+const std::string UdpServer::cmd_delimiter = ";";
+
+std::string UdpServer::host_broadcast_ip = "";
+std::string UdpServer::host_ip = "";
+std::string UdpServer::host_alias = "";
+int UdpServer::sock_in = 0;
+int UdpServer::sock_out = 0;
+int UdpServer::port_in = 0;
+int UdpServer::port_out = 0;
+
+int UdpServer::SendAll(std::string message)
+{
+ int result = -1;
+
+ struct sockaddr_in dstAddress;
+ dstAddress.sin_family = AF_INET;
+ inet_pton(AF_INET , host_broadcast_ip.c_str(), &dstAddress.sin_addr.s_addr);
+ dstAddress.sin_port = htons(UdpServer::port_out);
+ int messageSize = message.length() * sizeof(char);
+ result = sendto(UdpServer::sock_out, message.c_str(), messageSize, 0, (sockaddr*)&dstAddress, sizeof(dstAddress));
+ LOG_DEBUG << "INFO : sendto with sock_out=" << UdpServer::sock_out << ", message=" << message << " messageSize=" << messageSize << " returned with " << result << std::endl;
+ if (result < 0)
+ {
+ LOG_DEBUG << "ERROR : Cannot send udp broadcast message, error " << errno << ": " << strerror(errno) << std::endl;
+ return -4;
+ }
+
+ return 0;
+}
+
+int UdpServer::HandleRequest(char* buf)
+{
+ if(NULL == buf)
+ {
+ return 0;
+ }
+
+ LOG_DEBUG << "INFO : Client Command: " << PlainStr(buf) << std::endl;
+
+ std::string cmd(buf);
+ std::string answer;
+
+ if (UdpServer::local_host == host_ip)
+ {
+ LOG_DEBUG << "WARNING : There is no support in UDP srevices when using local host" << std::endl;
+ return 0;
+ }
+
+ if (UdpServer::cmd_get_host_identity == cmd)
+ {
+ answer = GetHostDetails();
+ }
+ else
+ {
+ LOG_DEBUG << "ERROR : Unkonwn UDP command" << std::endl;
+ }
+
+ // send back response in broadcast
+ // For the time being, all requests will have broadcast response
+ // All responses will use the same outgoing communication port
+ LOG_DEBUG << "INFO : Answer is: " << PlainStr(answer.c_str()) << std::endl;
+ SendAll(answer);
+
+ return 0;
+}
+
+
+/*
+ Close the server to allow un-bind te socket - allowing future connections without delay
+*/
+int UdpServer::stop()
+{
+ LOG_DEBUG << "INFO : Stopping the UDP server" << std::endl;
+ shutdown(UdpServer::sock_in, SHUT_RDWR);
+ return 0;
+}
+
+/*
+ Initialize UPD server on the given port. The function returns in case of error,
+ otherwise it doesn't return
+*/
+int UdpServer::start(int localUdpPortIn, int remoteUdpPortIn)
+{
+ LOG_DEBUG << "INFO : Starting UDP server on port " << localUdpPortIn << std::endl;
+ LOG_DEBUG << "INFO : Sending broadcast answers to port " << remoteUdpPortIn << std::endl;
+
+ // open the UDP server on a new thread
+ UdpServer::port_in = localUdpPortIn;
+ UdpServer::port_out = remoteUdpPortIn;
+ pthread_t thread;
+ pthread_create(&thread, 0, start_udp_server, NULL);
+ pthread_detach(thread);
+
+ return 0;
+}
+
+void* UdpServer::start_udp_server(void* unused)
+{
+ (void)unused;
+ if (LoadHostDetails() < 0)
+ {
+ return NULL;
+ }
+
+ // Create outgoing response socket
+ UdpServer::sock_out = socket(AF_INET, SOCK_DGRAM, 0);
+ if (UdpServer::sock_out < 0)
+ {
+ LOG_DEBUG << "ERROR : Cannot open udp broadcast outgoing socket" << std::endl;
+ return NULL;
+ }
+
+ int enabled = 1;
+ int result;
+ result = setsockopt(UdpServer::sock_out, SOL_SOCKET, SO_BROADCAST, (char*)&enabled, sizeof(enabled));
+ if (result < 0)
+ {
+ LOG_DEBUG << "ERROR : Cannot set broadcast option for udp socket, error " << errno << ": " << strerror(errno) << std::endl;
+ shutdown(UdpServer::sock_out, SHUT_RDWR);
+ return NULL;
+ }
+
+ // Create incoming request socket
+ struct sockaddr_in address;
+ UdpServer::sock_in = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if(UdpServer::sock_in < 0)
+ {
+ LOG_DEBUG << "ERROR : Cannot create a socket on port " << UdpServer::port_in << std::endl;
+ return NULL;
+ }
+
+ address.sin_family = AF_INET;
+ address.sin_addr.s_addr = INADDR_ANY;
+ address.sin_port = htons(UdpServer::port_in);
+ // Set the "Re-Use" socket option - allows reconnections after wilserver exit
+ int reuse = 1;
+ setsockopt(UdpServer::sock_in, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(int));
+ if(bind(UdpServer::sock_in, (struct sockaddr *)&address, sizeof(struct sockaddr_in)) < 0)
+ {
+ LOG_DEBUG << "ERROR : Cannot bind socket to port " << UdpServer::port_in << ", error " << errno << ": " << strerror(errno) << std::endl;
+ return NULL;
+ }
+
+ char* buf = new char[MAX_INPUT_BUF];
+
+ do
+ {
+ if (recvfrom(UdpServer::sock_in, buf, MAX_INPUT_BUF, 0, NULL, 0) < 0)
+ {
+ LOG_DEBUG << "ERROR : Cannot listen on port " << UdpServer::port_in << std::endl;
+ return NULL;
+ }
+
+ HandleRequest(buf);
+
+ } while (true);
+
+ LOG_DEBUG << "INFO : UDP server shutdown" << std::endl;
+ return NULL; // Wont get here, just to avoid the warning
+}
+
+bool FindEthernetInterface(struct ifreq& ifr, int& fd)
+{
+ fd = socket(AF_INET, SOCK_DGRAM, 0);
+ if(fd < 0)
+ {
+ LOG_DEBUG << "ERROR : Cannot get host and broadcast IPs" << std::endl;
+ return -1;
+ }
+
+ for (int i = 0; i < 100; i++)
+ {
+ snprintf(ifr.ifr_name, IFNAMSIZ-1, "eth%d", i);
+
+ if (ioctl(fd, SIOCGIFADDR, &ifr) >= 0)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+int UdpServer::LoadHostAndBroadcastIps()
+{
+ int fd;
+ struct ifreq ifr;
+
+ ifr.ifr_addr.sa_family = AF_INET; // IP4V
+
+ // Get IP address according to OS
+ if (FindEthernetInterface(ifr, fd))
+ {
+ LOG_INFO << "Linux OS" << std::endl;
+ }
+ else
+ {
+ snprintf(ifr.ifr_name, IFNAMSIZ, "br-lan");
+ if (ioctl(fd, SIOCGIFADDR, &ifr) >= 0)
+ {
+ LOG_INFO << "OpenWRT OS" << std::endl;
+ }
+ else
+ {
+ // Probably Android OS
+ LOG_INFO << "Android OS (no external IP Adress)" << std::endl;
+ host_ip = UdpServer::local_host;
+ host_broadcast_ip = UdpServer::local_host;
+ return 0;
+ }
+ }
+ host_ip = inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr);
+
+ if (ioctl(fd, SIOCGIFBRDADDR, &ifr) < 0)
+ {
+ LOG_DEBUG << "ERROR : Cannot get broadcast IP" << std::endl;
+ return -3;
+ }
+ host_broadcast_ip = inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr);
+ LOG_DEBUG << "INFO : " << "host_ip=" << host_ip << std::endl;
+ LOG_DEBUG << "INFO : " << "host_broadcast_ip=" << host_broadcast_ip << std::endl;
+
+ close(fd);
+ return 0;
+}
+
+void UdpServer::LoadHostAlias()
+{
+ std::ifstream infile;
+ infile.open(host_details_file_name.c_str());
+ std::getline(infile, host_alias);
+ infile.close();
+}
+
+int UdpServer::LoadHostDetails()
+{
+ if (LoadHostAndBroadcastIps() < 0)
+ {
+ return -1;
+ }
+ LoadHostAlias();
+ return 0;
+}
diff --git a/debug-tools/remoteserver/udp_server.h b/debug-tools/remoteserver/udp_server.h
new file mode 100644
index 0000000..01855d7
--- /dev/null
+++ b/debug-tools/remoteserver/udp_server.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __udp_server_h
+#define __udp_server_h
+
+class UdpServer
+{
+public:
+ int start(int localUdpPortIn, int remoteUdpPortIn);
+ int stop();
+
+ static int SendAll(std::string message);
+ static std::string GetHostDetails() { return UdpServer::cmd_get_host_identity + UdpServer::cmd_delimiter + host_ip + UdpServer::cmd_delimiter + host_alias; }
+ static void SetHostAlias(std::string alias) { host_alias = alias; }
+
+ static const std::string host_details_file_name;
+
+private:
+ // members
+ static const std::string local_host;
+ static const std::string cmd_get_host_identity;
+ static const std::string cmd_delimiter;
+ static std::string host_broadcast_ip;
+ static std::string host_ip;
+ static std::string host_alias;
+ static int sock_in;
+ static int sock_out;
+ static int port_in;
+ static int port_out;
+
+ // methods
+ static void* start_udp_server(void* unused);
+ static int LoadHostDetails();
+ static int LoadHostIp(); // assumption: each host has only one IP address for ethernet interfaces
+ static void LoadHostAlias();
+ static int HandleRequest(char* buf);
+ static int LoadHostAndBroadcastIps();
+};
+
+#endif // udp_server_h
diff --git a/debug-tools/wiburn/Android.mk b/debug-tools/wiburn/Android.mk
new file mode 100644
index 0000000..34521f6
--- /dev/null
+++ b/debug-tools/wiburn/Android.mk
@@ -0,0 +1,30 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := wigig_wiburn
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_CPPFLAGS := -Wall -lpthread -fexceptions
+
+LOCAL_C_INCLUDES += \
+ $(LOCAL_PATH)/../lib/WlctPciAcss \
+ $(LOCAL_PATH)/../lib/FlashAcss \
+ $(LOCAL_PATH)/../lib/inc \
+ $(LOCAL_PATH)/../lib/utils
+
+LOCAL_SHARED_LIBRARIES := \
+ libwigig_utils \
+ libwigig_pciaccess \
+ libwigig_flashaccess
+
+LOCAL_SRC_FILES := \
+ wiburn.cpp \
+ translation_map.cpp \
+ ParameterParser.cpp \
+ template_inst.cpp \
+ CCRC32.cpp
+
+include $(BUILD_EXECUTABLE)
+
diff --git a/debug-tools/wiburn/CCRC32.cpp b/debug-tools/wiburn/CCRC32.cpp
new file mode 100644
index 0000000..7352264
--- /dev/null
+++ b/debug-tools/wiburn/CCRC32.cpp
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "wlct_os.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "CCRC32.h"
+
+CCRC32::CCRC32(void)
+{
+ int index = 0;
+ while (index <= BYTE_MASK)
+ {
+ lookup[index] = Reflect(index, 8);
+ lookup[index] = lookup[index] << 24;
+
+ // Repeat 8 times
+ int subindex = 0;
+ while(subindex < 8)
+ {
+ subindex++;
+
+ int check;
+ if (lookup[index] & (1 << 31))
+ {
+ check = POLYNOMIAL;
+ }
+ else
+ {
+ check = 0;
+ }
+
+ lookup[index] = (lookup[index] << 1);
+ lookup[index] = lookup[index] ^ check;
+ }
+
+ lookup[index] = Reflect(lookup[index], 32);
+ index++;
+ }
+}
+
+uint32_t CCRC32::Reflect(uint32_t reflected, const char bitsToReflect)
+{
+ uint32_t retVal = 0;
+
+ int index = 1;
+
+ while(index < (bitsToReflect + 1))
+ {
+ if((reflected % 2) == 1)
+ {
+ retVal |= (1 << (bitsToReflect - index));
+ }
+ else
+ {
+ // do nothing
+ }
+ reflected >>= 1;
+ index++;
+ }
+
+ return retVal;
+}
+
+void CCRC32::CalcCRCStep(uint32_t *crc, const unsigned char *data, uint32_t length)
+{
+ uint32_t tempCRC = *crc;
+
+ for (uint32_t index = 0; index < length; index++)
+ {
+ tempCRC = (tempCRC >> 8) ^ lookup[(tempCRC & BYTE_MASK) ^ *data++];
+ }
+
+ *crc = tempCRC;
+}
+
+uint32_t CCRC32::CalcCRC(const unsigned char *data, uint32_t length)
+{
+ uint32_t crc = CRC_MASK;
+ CalcCRCStep(&crc, data, length);
+ return(crc ^ CRC_MASK);
+}
diff --git a/debug-tools/wiburn/CCRC32.h b/debug-tools/wiburn/CCRC32.h
new file mode 100644
index 0000000..aa896f8
--- /dev/null
+++ b/debug-tools/wiburn/CCRC32.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CRC32_H
+#define CRC32_H
+
+#define POLYNOMIAL 0x04C11DB7
+#define CRC_MASK 0xffffffff
+#define LOOKUP_SIZE 256
+#define BYTE_MASK 0xff
+
+class CCRC32
+{
+public:
+ CCRC32();
+
+ uint32_t CalcCRC(const unsigned char *data, uint32_t length);
+
+private:
+ uint32_t Reflect(uint32_t ulReflect, const char bitsToReflect);
+ uint32_t lookup[LOOKUP_SIZE];
+ void CalcCRCStep(uint32_t *ulCRC, const unsigned char *data, uint32_t length);
+};
+
+#endif
diff --git a/debug-tools/wiburn/Makefile b/debug-tools/wiburn/Makefile
new file mode 100644
index 0000000..1e8f296
--- /dev/null
+++ b/debug-tools/wiburn/Makefile
@@ -0,0 +1,53 @@
+-include $(TOPDIR)/rules.mk
+
+CFLAGS := -fPIE -Wall -g -MMD -fPIE -Wno-reorder
+LDFLAGS := -pie -fPIE -pthread -lwigig_flashaccess -lwigig_pciaccess -lwigig_utils
+
+ifneq ($(CONFIG_TARGET_ipq)$(CONFIG_TARGET_ipq806x),)
+is_ipq806x = 1
+endif
+
+ifeq ($(is_ipq806x), 1)
+ifneq ($(strip $(TOOLPREFIX)),)
+CROSS:=$(TOOLPREFIX)
+endif
+endif
+
+CC := $(CROSS)gcc
+CXX := $(CROSS)g++
+
+.DEFAULT_GOAL = all
+PROG = wigig_wiburn
+
+INCLUDES += -I ../lib/WlctPciAcss \
+ -I ../lib/FlashAcss \
+ -I ../lib/inc \
+ -I ../lib/utils \
+
+LIBS = -L../lib/FlashAcss \
+ -L../lib/WlctPciAcss \
+ -L../lib/utils \
+
+all: $(PROG)
+
+CPP_FILES = wiburn.cpp \
+ translation_map.cpp \
+ ParameterParser.cpp \
+ template_inst.cpp \
+ CCRC32.cpp \
+
+OBJ_FILES = $(CPP_FILES:.cpp=.o)
+
+$(PROG): $(OBJ_FILES)
+ $(CXX) -o $@ $^ $(LIBS) $(LDFLAGS)
+
+%.o : %.cpp
+ $(CXX) $(CFLAGS) $(INCLUDES) -o $@ -c $<
+
+clean:
+ rm -rf $(PROG)
+ find . -type f \( -name "*.d" -o -name "*.o" \) -delete
+
+
+-include $(OBJ_FILES:%.o=%.d)
+
diff --git a/debug-tools/wiburn/ParameterParser.cpp b/debug-tools/wiburn/ParameterParser.cpp
new file mode 100644
index 0000000..84980e2
--- /dev/null
+++ b/debug-tools/wiburn/ParameterParser.cpp
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "ParameterParser.h"
+
+#include "wlct_os.h"
+
+ParameterParser::ParameterParser()
+{
+}
+
+void ParameterParser::setVerbose()
+{
+ verbose = true ;
+}
+
+void ParameterParser::printVerbose()
+{
+ if( verbose )
+ cout << endl ;
+}
+void ParameterParser::printVerbose( const char *INFO )
+{
+ if( verbose )
+ cout << INFO ;
+}
+
+int ParameterParser::processCommandArgs( int _argc, char **_argv )
+{
+ for (int index = 1; index < _argc; index++)
+ {
+ if (IsFlag(_argv[index]))
+ {
+ Flags[_argv[index]] = true;
+ }
+ else if (IsParam(_argv[index]))
+ {
+ Parameters[_argv[index]] = _argv[index + 1];
+ index++;
+ }
+ else
+ {
+ printUsage();
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+bool ParameterParser::IsFlag(string flag)
+{
+ for (list<string>::iterator iterator = flags.begin(); iterator != flags.end(); iterator++)
+ {
+ if (flag.compare(*iterator) == 0)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool ParameterParser::IsParam(string param)
+{
+ for (list<string>::iterator iterator = params.begin(); iterator != params.end(); iterator++)
+ {
+ if (param.compare(*iterator) == 0)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool ParameterParser::ParamFound(string param)
+{
+ return (Parameters.find(param) != Parameters.end());
+}
+
+bool ParameterParser::FlagFound(string flag)
+{
+ return (Flags.find(flag) != Flags.end());
+}
+
+void ParameterParser::addFlag(string flag)
+{
+ flags.push_front(flag);
+}
+
+void ParameterParser::addParam(string param)
+{
+ params.push_front(param);
+}
+
+char* ParameterParser::getValue(string option)
+{
+ if (IsParam(option) && ParamFound(option))
+ {
+ return Parameters[option];
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+bool ParameterParser::getFlag(string option)
+{
+ if (IsFlag(option) && FlagFound(option))
+ {
+ return Flags[option];
+ }
+ else
+ {
+ return false;
+ }
+}
+
+void ParameterParser::printUsage()
+{
+ cout<<
+ "***************\n"\
+ "Usage \n" \
+ "***************\n" \
+ "Commands:\n" \
+ " -help --- Prints this help \n" \
+ " -burn --- Burn to flash\n" \
+ " -query --- disaply the image info section from flash\n" \
+ " -read --- read image from flash\n" \
+ " -read_formatted --- read image from flash and display in formatted manner\n" \
+ " -erase --- Erase the flash\n" \
+ " -debug --- Prints debug messages\n" \
+ " -verify --- Verify burning\n" \
+ " -force --- Force burning even if it is unsafe\n" \
+ " -ignore_lock --- Ignore flash lock mechanism\n" \
+ " -read_ids_to_file --- Read the IDS section in the Flash, and write it to file\n" \
+ "\n" \
+ "Parameters:\n" \
+ " -bin binary_image_filename --- The binary image filename to use\n" \
+ " -fw fw_ini_filename --- The FW INI filename to use\n" \
+ " -ids ids_ini_filename --- The IDs INI filename to use\n" \
+ " -production prod_ini_filename --- The Production INI filename to use\n" \
+ " -board board_ini_filename --- The board INI filename to use\n" \
+ " -board2 board_ini_filename --- The board 2 INI filename to use\n" \
+ " -board3 board_ini_filename --- The board 3 INI filename to use\n" \
+ " -setup_ini setup_ini_filename --- The setup_ini INI filename to use\n" \
+ " -usb usb_ini_filename --- The USB INI filename to use\n" \
+ " -interface interface_name --- The interface to use\n" \
+ " -device device_type --- The type of device\n" \
+ " -offset --- offset address\n" \
+ " -length --- Length (in bytes)\n" \
+ "\n" \
+ "Examples\n" \
+ "To burn FW INI file to flash using PCI on MARLON with ignore_loc\n" \
+ " wiburn -erase -burn -fw fw.ini -interface wpci2l!malon -ignore_lock -device MARLO\n" \
+ "\n" \
+ "To burn FW INI file to binary image file out.bi\n" \
+ " wiburn -burn -erase -fw fw.ini -interface out.bin -device MARLO\n" \
+ "\n" \
+ "To burn FW INI file to flash using automatically selected interfac\n" \
+ " wiburn -burn -erase -fw fw.ini -device MARLO\n" \
+ "\n" \
+ "To read image from flash on Sparrow using Jtag\n" \
+ " wiburn -read_formatted -length 0x80000 -offset 0 -interface wjtag0!sparrow -device SPARRO\n" \
+ "\n" \
+ "To burn IDS section to flash using JTAG\n" \
+ " wiburn -section -ids ids_file.ini -interface wjtag0!sparrow -device SPARRO\n" \
+ "\n" \
+ "To erase the flash using JTA\n" \
+ " wiburn -interface wjtag0!sparrow -erase -device SPARRO\n";
+}
diff --git a/debug-tools/wiburn/ParameterParser.h b/debug-tools/wiburn/ParameterParser.h
new file mode 100644
index 0000000..92f586a
--- /dev/null
+++ b/debug-tools/wiburn/ParameterParser.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _PARAMETER_PARSER_H
+#define _PARAMETER_PARSER_H
+
+#include <iostream>
+#include <fstream>
+#include <stdlib.h>
+#include <string>
+#include <map>
+#include <list>
+#include <algorithm>
+
+using namespace std;
+
+class ParameterParser
+{
+ map<string, char*> Parameters;
+ map<string, bool> Flags;
+ list<string> flags;
+ list<string> params;
+
+public:
+ ParameterParser();
+ ~ParameterParser();
+
+ int processCommandArgs( int _argc, char **_argv );
+
+ char *getValue(string _option);
+ bool getFlag(string _option);
+
+ void printUsage();
+
+ void printHelp();
+
+ void setVerbose();
+
+ void addFlag(string flag);
+ void addParam(string param);
+
+private:
+ int argc;
+ char **argv;
+
+ bool verbose;
+
+ void printVerbose( const char *INFO );
+ void printVerbose( char *INFO );
+ void printVerbose( char ch );
+ void printVerbose( );
+
+ bool IsFlag(string flag);
+ bool IsParam(string param);
+
+ bool ParamFound(string param);
+
+ bool FlagFound(string flag);
+};
+
+#endif /* ! _PARAMETER_PARSER_H */
diff --git a/debug-tools/wiburn/flash_image.cpp b/debug-tools/wiburn/flash_image.cpp
new file mode 100644
index 0000000..6d87c22
--- /dev/null
+++ b/debug-tools/wiburn/flash_image.cpp
@@ -0,0 +1,743 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "flash_image.h"
+#include <memory.h>
+#include <iostream>
+
+
+//extern ini_parser g_parser;
+
+#define NEXT_PTR(ptr) (((ptr) & SUB_SECTOR_MASK) + SUB_SECTOR )
+
+u_int16_t crc_16 (const u_int32_t *buffer, int size)
+{
+ return 0;
+ u_int16_t crc;
+ u_int32_t element;
+
+ crc = 0xffff;
+
+ for (int j = 0; j < size; j++) {
+ element = buffer[j];
+ for (int i=0; i<32; i++) {
+ if (crc & 0x8000) {
+ crc = (u_int16_t) ((((crc<<1) | (element>>31)) ^ 0x100b) & 0xffff);
+ }
+ else {
+ crc= (u_int16_t) (((crc<<1) | (element>>31)) & 0xffff);
+ }
+ element = (element<<1) & 0xffffffff;
+ }
+ }
+
+ for (int k=0; k<16; k++) {
+ if (crc & 0x8000)
+ crc=((crc<<1) ^ 0x100b) & 0xffff;
+ else
+ crc=(crc<<1) & 0xffff;
+ }
+
+ // Revert 16 low bits
+ crc = crc ^ 0xffff;
+ return crc;
+}
+
+
+template <class PRODUCT>
+flash_image<PRODUCT>::flash_image () :
+ pointer_section ("pointer_section"),
+ hw_conf_section ("hw_conf_section", hw_conf_section_id, &pointer_section.m_pointers.hw_pointer),
+
+ fw1_code_section ("fw1_code_section", fw1_code_section_id, &pointer_section.m_pointers.fw1_pointer, &pointer_section.m_pointers.fw1_length),
+ fw1_data_section ("fw1_data_section",fw1_data_section_id, &pointer_section.m_pointers.fw1_data_pointer, &pointer_section.m_pointers.fw1_data_length),
+ fw1_static_conf_section ("fw1_static_conf_section",fw1_static_conf_section_id, &pointer_section.m_pointers.fw1_static_conf_pointer),
+
+ fw2_code_section ("fw2_code_section",fw2_code_section_id, &pointer_section.m_pointers.fw2_pointer, &pointer_section.m_pointers.fw2_length),
+ fw2_data_section ("fw2_data_section",fw2_data_section_id, &pointer_section.m_pointers.fw2_data_pointer, &pointer_section.m_pointers.fw2_data_length),
+ fw2_static_conf_section ( "fw2_static_conf_section",fw2_static_conf_section_id, &pointer_section.m_pointers.fw2_static_conf_pointer),
+
+ system_config_section ( "config_section", &pointer_section.m_pointers.config_section_pointer),
+
+ production_section ("production_section",production_section_id, &pointer_section.m_pointers.production_pointer),
+ user_conf_section ("user_conf_section",user_conf_section_id, &pointer_section.m_pointers.user_pointer),
+
+ image_info_section ("image_info_section",image_info_section_id, &pointer_section.m_pointers.image_info_pointer),
+ ids_section("ids_section", ids_section_id, &pointer_section.m_pointers.ids_pointer),
+
+ usb_section("usb_section", &pointer_section.m_pointers.usb_pointer),
+ usb_info_section("usb_info_section", usb_info_section_id, &pointer_section.m_pointers.usb_info_pointer),
+
+ radio_tx_conf_section ("radio_tx_conf_section", radio_tx_conf_section_id, &pointer_section.m_pointers.radio_tx_cnf_pointer),
+ radio_rx_conf_section ("radio_rx_conf_section", radio_rx_conf_section_id, &pointer_section.m_pointers.radio_rx_cnf_pointer),
+ radio_tx_conf2_section ("radio_tx_conf2_section", radio_tx_conf2_section_id, &pointer_section.m_pointers.radio_tx_cnf2_pointer),
+ radio_rx_conf2_section ("radio_rx_conf2_section", radio_rx_conf2_section_id, &pointer_section.m_pointers.radio_rx_cnf2_pointer),
+
+ // The following is unused!
+ raw_data_section ("raw_data_section", raw_data_section_id, &pointer_section.m_pointers.raw_data_pointer, &pointer_section.m_pointers.raw_data_length),
+ proxy_product(NULL)
+{
+ // proxy_product = new PRODUCT;
+ memset(m_image, -1, sizeof m_image);
+}
+
+template <class PRODUCT>
+flash_image<PRODUCT>::~flash_image ()
+{
+}
+
+template <class PRODUCT>
+const BYTE* flash_image<PRODUCT>::get_image (void) const
+{
+ return m_image;
+}
+
+template <class PRODUCT>
+u_int32_t flash_image<PRODUCT>::get_image_size (void) const
+{
+ return sizeof m_image;
+}
+
+template <class PRODUCT>
+void flash_image<PRODUCT>::init( const char *filename)
+{
+ FILE *stream;
+ stream = fopen(filename, "r");
+ if( NULL == stream )
+ {
+ ERR("Failed opening file %s for reading\n", filename);
+ EXIT (-1);
+ }
+
+ u_int32_t cnt = fread(m_image, sizeof m_image, 1, stream);
+ if (cnt < sizeof m_image) {
+ INFO("Initialized from partial image file of size 0x%04x\n", cnt);
+ }
+ fclose(stream);
+}
+
+template <class PRODUCT>
+void flash_image<PRODUCT>::init_pointer_section (flash_base *fl)
+{
+ pointer_section.init(fl);
+
+ // In order to prevent reading from the flash over the signature
+ // when the flash is un-initiated, we reset the signature
+ // after reading from flash.
+ pointer_section.m_pointers.signature = 0x40;
+}
+
+template <class PRODUCT>
+void flash_image<PRODUCT>::init_hw_conf_section (flash_base *fl)
+{
+ hw_conf_section.init(fl);
+}
+
+// template <class PRODUCT>
+// void flash_image<PRODUCT>::init_radio_tx_conf_section (flash_base *fl)
+// {
+// radio_tx_conf_section.init(fl);
+// }
+//
+// template <class PRODUCT>
+// void flash_image<PRODUCT>::init_radio_rx_conf_section (flash_base *fl)
+// {
+// radio_rx_conf_section.init(fl);
+// }
+//
+// template <class PRODUCT>
+// void flash_image<PRODUCT>::init_radio_tx_conf2_section (flash_base *fl)
+// {
+// radio_tx_conf2_section.init(fl);
+// }
+//
+// template <class PRODUCT>
+// void flash_image<PRODUCT>::init_radio_rx_conf2_section (flash_base *fl)
+// {
+// radio_rx_conf2_section.init(fl);
+// }
+
+template <class PRODUCT>
+void flash_image<PRODUCT>::init_image_info_section (flash_base *fl)
+{
+ image_info_section.init(fl);
+}
+
+template <class PRODUCT>
+void flash_image<PRODUCT>::init_ids_section (flash_base *fl, bool isReduced)
+{
+ if (isReduced)
+ {
+ *ids_section.m_ptr = 4 * 1024 + sizeof(section_header_t);
+ }
+ else
+ {
+ *ids_section.m_ptr = 44 * 1024 + sizeof(section_header_t);
+ }
+
+ ids_section.init(fl);
+}
+
+template <class PRODUCT>
+void flash_image<PRODUCT>::init_usb_info_section (flash_base *fl)
+{
+ usb_info_section.init(fl);
+}
+
+template <class PRODUCT>
+const pointer_section_t<PRODUCT>& flash_image<PRODUCT>::get_pointer_section(void) const
+{
+ return pointer_section;
+}
+
+template <class PRODUCT>
+const hw_section_t<PRODUCT>& flash_image<PRODUCT>::get_hw_conf_section(void) const
+{
+ return hw_conf_section;
+}
+
+// template <class PRODUCT>
+// const hw_section_t<marlon>& flash_image<PRODUCT>::get_radio_tx_conf_section(void) const
+// {
+// return radio_tx_conf_section;
+// }
+//
+// template <class PRODUCT>
+// const hw_section_t<marlon>& flash_image<PRODUCT>::get_radio_rx_conf_section(void) const
+// {
+// return radio_rx_conf_section;
+// }
+//
+// template <class PRODUCT>
+// const hw_section_t<marlon>& flash_image<PRODUCT>::get_radio_tx_conf2_section(void) const
+// {
+// return radio_tx_conf2_section;
+// }
+//
+// template <class PRODUCT>
+// const hw_section_t<marlon>& flash_image<PRODUCT>::get_radio_rx_conf2_section(void) const
+// {
+// return radio_rx_conf2_section;
+// }
+
+template <class PRODUCT>
+const image_info_section_t<PRODUCT>& flash_image<PRODUCT>::get_image_info_section(void) const
+{
+ return image_info_section;
+}
+
+template <class PRODUCT>
+const usb_info_section_t<PRODUCT>& flash_image<PRODUCT>::get_usb_info_section(void) const
+{
+ return usb_info_section;
+}
+
+template <class PRODUCT>
+const ids_section_t<PRODUCT>& flash_image<PRODUCT>::get_ids_section(void) const
+{
+ return ids_section;
+}
+
+
+// template <class PRODUCT>
+// const image_section_t<PRODUCT>& flash_image<PRODUCT>::get_fw1_code_section () const
+// {
+// return fw1_code_section;
+// }
+//
+// template <class PRODUCT>
+// const image_section_t<PRODUCT>& flash_image<PRODUCT>::get_fw2_code_section () const
+// {
+// return fw2_code_section;
+// }
+
+template <class PRODUCT>
+void flash_image<PRODUCT>::save( const char *filename)
+{
+ FILE *stream;
+ stream = fopen(filename, "wb");
+ if( NULL == stream )
+ {
+ ERR("Failed opening file %s for writing\n", filename);
+ EXIT (-1);
+ }
+
+ fwrite(m_image, sizeof m_image, 1, stream);
+ fclose(stream);
+}
+
+/*
+ MARLON: SPARROW: SPARROW REDUCED:
+ +-------------------------------------------+ 0k +-------------------------------------------+ 0k +-------------------------------------------+ 0k
+ | POINTER | | POINTER | | POINTER |
+ +-------------------------------------------+ 4k +-------------------------------------------+ 4k +-------------------------------------------+ 4k
+ | production (40K) | | production (40K) | | IDS (4K) |
+ +-------------------------------------------+ 48k +-------------------------------------------+ 48k +-------------------------------------------+
+ | IDS (4K) | | IDS (4K) | +-------------------------------------------+ 8k
+ +-------------------------------------------+ +-------------------------------------------+ | HW (4k) |
+ +-------------------------------------------+ 52k +-------------------------------------------+ 52k +-------------------------------------------+ 12k
+ | HW (4k) | | HW (4k) | | FW CODE (44K) |
+ +-------------------------------------------+ 56k +-------------------------------------------+ 56k +-------------------------------------------+ 56k
+ | FW CODE (256K) | | FW CODE (256K) | | FW DATA (8K) |
+ +-------------------------------------------+ 312k +-------------------------------------------+ 312k +-------------------------------------------+ 64k
+ | FW DATA (32K) | | FW DATA (32K) |
+ +-------------------------------------------+ 344k +-------------------------------------------+ 344k
+ | uCode CODE (64K) | | uCode CODE (128K) |
+ +-------------------------------------------+ 408k +-------------------------------------------+ 472k
+ | uCode DATA (8K) | | uCode DATA (8K) |
+ +-------------------------------------------+ 416k +-------------------------------------------+ 480k
+ | FW STATICS (4K) | | FW STATICS (4K) |
+ +-------------------------------------------+ 420k +-------------------------------------------+ 484k
+ | uCode STATICS (4K) | | uCode STATICS (4K) |
+ +-------------------------------------------+ +-------------------------------------------+
+ +-------------------------------------------+ 424k +-------------------------------------------+ 488k
+ | System Config Selector (4K) | | System Config Selector (4K) |
+ +-------------------------------------------+ 428k +-------------------------------------------+ 492k
+ | System Config Factory (4K) | | System Config Factory (4K) |
+ +-------------------------------------------+ 432k +-------------------------------------------+ 496k
+ | System Config User1 (4K) | | System Config User1 (4K) |
+ +-------------------------------------------+ 436k +-------------------------------------------+ 500k
+ | System Config User2 (4K) | | System Config User2 (4K) |
+ +-------------------------------------------+ +-------------------------------------------+
+ +-------------------------------------------+ 440k +-------------------------------------------+ 504k
+ | IMAGE INFO (4K) | | IMAGE INFO (4K) |
+ | image format version | | image format version |
+ | FW VERSION | | FW VERSION |
+ | fw_timestamp | | fw_timestamp |
+ | ucode_version | | ucode_version |
+ | ucode_timestamp | | ucode_timestamp |
+ | configuration_id | | configuration_id |
+ | device_id | | device_id |
+ | hw_id | | hw_id |
+ +-------------------------------------------+ 444k +-------------------------------------------+ 508k
+ | radio_tx_conf (8K) |
+ +-------------------------------------------+ 452k
+ | radio_rx_conf (8K) |
+ +-------------------------------------------+ 460k
+ | radio_tx_conf2 (8K) |
+ +-------------------------------------------+ 468k
+ | radio_rx_conf2 (8K) |
+ +-------------------------------------------+ 476k
+ | RAW DATA (4K) |
+ +-------------------------------------------+ 480k
+*/
+template <class PRODUCT>
+void flash_image<PRODUCT>::init(ini_parser_base *parser, bool full_image, bool isReducedSip)
+{
+ ini_file_t::iterator iter1;
+ ini_file_t::const_iterator iter2;
+ int ptr;
+ ptr = NEXT_PTR( 0 );
+ string section_name;
+ bool reducedSip = isReducedSip && ((PRODUCT::id == sparrow::id) || (PRODUCT::id == talyn::id));
+
+ if (!reducedSip)
+ {
+ section_name = "production";
+ if (parser->get_section(section_name, 0, &iter1, false, false) )
+ {
+ production_section.set_max_size( flash::SUB_SECTOR_SIZE * 10 );
+ production_section.handle_ini_section(0, *(iter1->second));
+ production_section.set_offset( ptr );
+ production_section.write_to_buffer(m_image);
+ }
+
+ //Force the section size to be 40K
+ ptr += NEXT_PTR( (1<<15) -1 ); // 32K
+ ptr += NEXT_PTR( (1<<13) -1 ); // 8K
+ }
+
+ section_name = "ids";
+
+ // Always set ids section. The existing values remain if input file is not provided
+ ids_section.set_max_size( flash::SUB_SECTOR_SIZE );
+ if (parser->get_section(section_name, 0, &iter1, true, false))
+ {
+ ids_section.handle_ini_section( *(iter1->second));
+ }
+
+ ids_section.set_offset( ptr );
+ ids_section.write_to_buffer(m_image);
+
+ ptr += NEXT_PTR( 0 );
+
+ section_name = "hw_config";
+ if (parser->get_section(section_name, TRANSLATION_MAP_REGTREE, &iter1, false, full_image))
+ {
+ hw_conf_section.set_max_size( flash::SUB_SECTOR_SIZE );
+ hw_conf_section.handle_ini_section(TRANSLATION_MAP_REGTREE, *(iter1->second));
+ hw_conf_section.set_offset( ptr );
+ hw_conf_section.write_to_buffer(m_image);
+ }
+ ptr += NEXT_PTR( 0 );
+
+ section_name = "fw_code";
+ if (parser->get_section(section_name, 0, &iter1, false, full_image))
+ {
+ if (reducedSip)
+ {
+ fw1_code_section.set_max_size( flash::SUB_SECTOR_SIZE * 11);
+ }
+ else
+ {
+ // FW code limit to 256K
+#ifdef FLASH_256KB
+ fw1_code_section.set_max_size( flash::SUB_SECTOR_SIZE * 16);
+#else
+ if (PRODUCT::id == sparrow::id)
+ {
+ fw1_code_section.set_max_size( flash::SUB_SECTOR_SIZE * 64);
+ }
+ else if (PRODUCT::id == talyn::id)
+ {
+ fw1_code_section.set_max_size( flash::SUB_SECTOR_SIZE * 256);
+ }
+ else
+ {
+ fw1_code_section.set_max_size( flash::SUB_SECTOR_SIZE * 64);
+ }
+#endif
+ }
+
+ fw1_code_section.handle_ini_section( *(iter1->second));
+ fw1_code_section.set_offset( ptr );
+ fw1_code_section.write_to_buffer(m_image);
+ }
+
+ if (reducedSip)
+ {
+ ptr += NEXT_PTR( (0xB000) -1 ); //Force the Code size to be 44K (including header+CRC)
+ }
+ else
+ {
+#ifdef FLASH_256KB
+ ptr += NEXT_PTR( (1<<16) -1 ); //Force the Code size to be 64K (including header+CRC)
+#else
+ if (PRODUCT::id == sparrow::id)
+ {
+ ptr += NEXT_PTR( (1<<18) -1 ); //Force the Code size to be 256K (including header+CRC)
+ }
+ else if (PRODUCT::id == talyn::id)
+ {
+ ptr += NEXT_PTR( (1<<20) -1 ); //Force the Code size to be 1M (including header+CRC)
+ }
+ else
+ {
+ ptr += NEXT_PTR( (1<<18) -1 ); //Force the Code size to be 256K (including header+CRC)
+ }
+#endif
+ }
+
+ section_name = "fw_data";
+ if (parser->get_section(section_name, 0, &iter1, false, full_image))
+ {
+ if (reducedSip)
+ {
+ // FW data limit to 8K
+ fw1_data_section.set_max_size( flash::SUB_SECTOR_SIZE * 2 );
+ }
+ else
+ {
+ if (PRODUCT::id == sparrow::id)
+ {
+ // FW data limit to 32K
+ fw1_data_section.set_max_size( flash::SUB_SECTOR_SIZE * 8 );
+ }
+ else if (PRODUCT::id == talyn::id)
+ {
+ // FW data limit to 128K
+ fw1_data_section.set_max_size( flash::SUB_SECTOR_SIZE * 32 );
+ }
+ else
+ {
+ // FW data limit to 32K
+ fw1_data_section.set_max_size( flash::SUB_SECTOR_SIZE * 8 );
+ }
+ }
+ fw1_data_section.handle_ini_section( *(iter1->second));
+ fw1_data_section.set_offset( ptr );
+ fw1_data_section.write_to_buffer(m_image);
+ }
+ if (reducedSip)
+ {
+ ptr += NEXT_PTR( (1<<13) -1 ); //Force the Data size to be 8K (including header+CRC)
+ }
+ else
+ {
+ ptr += NEXT_PTR( (1<<15) -1 ); //Force the Data size to be 32K (including header+CRC)
+ }
+
+ if (!reducedSip)
+ {
+ section_name = "ucode_code";
+ if (parser->get_section(section_name, 0, &iter1, false, full_image))
+ {
+ if (PRODUCT::id == sparrow::id)
+ {
+ // ucode code limit to 128K - Sparrow
+ fw2_code_section.set_max_size( flash::SUB_SECTOR_SIZE * 32 );
+ }
+ else if (PRODUCT::id == talyn::id)
+ {
+ // ucode code limit to 256K - Talyn
+ fw2_code_section.set_max_size( flash::SUB_SECTOR_SIZE * 64 );
+ }
+ else
+ {
+ // ucode code limit to 64K - Marlon, default
+ fw2_code_section.set_max_size( flash::SUB_SECTOR_SIZE * 16 );
+ }
+
+ fw2_code_section.handle_ini_section( *(iter1->second));
+ fw2_code_section.set_offset( ptr );
+ fw2_code_section.write_to_buffer(m_image);
+ }
+
+ if (PRODUCT::id == sparrow::id)
+ {
+ ptr += NEXT_PTR( (1<<17) -1 ); //Force the Code size to be 128K - Sparrow (including header+CRC)
+ }
+ else if (PRODUCT::id == talyn::id)
+ {
+ ptr += NEXT_PTR( (1<<18) -1 ); //Force the Code size to be 256K - Talyn (including header+CRC)
+ }
+ else
+ {
+ ptr += NEXT_PTR( (1<<16) -1 ); //Force the Code size to be 64K - Marlon, default (including header+CRC)
+ }
+
+ section_name = "ucode_data";
+ if (parser->get_section(section_name, 0, &iter1, false, full_image))
+ {
+ if (PRODUCT::id == sparrow::id)
+ {
+ // ucode data limit to 16K
+ fw2_data_section.set_max_size( flash::SUB_SECTOR_SIZE * 4);
+ }
+ else if (PRODUCT::id == talyn::id)
+ {
+ // ucode data limit to 32K
+ fw2_data_section.set_max_size( flash::SUB_SECTOR_SIZE * 8);
+ }
+ else
+ {
+ // ucode data limit to 8K
+ fw2_data_section.set_max_size( flash::SUB_SECTOR_SIZE * 2);
+ }
+
+ fw2_data_section.handle_ini_section( *(iter1->second));
+ fw2_data_section.set_offset( ptr );
+ fw2_data_section.write_to_buffer(m_image);
+ }
+ //ptr += NEXT_PTR( 0 );
+ ptr += NEXT_PTR( (1<<13) -1 );
+
+ section_name = "fw_static";
+ if (full_image) {
+ if (parser->get_section(section_name, TRANSLATION_MAP_REGTREE | TRANSLATION_MAP_FW, &iter1, false, full_image))
+ {
+ fw1_static_conf_section.set_max_size( flash::SUB_SECTOR_SIZE );
+ fw1_static_conf_section.handle_ini_section(TRANSLATION_MAP_REGTREE | TRANSLATION_MAP_FW, *(iter1->second));
+ fw1_static_conf_section.set_offset( ptr );
+ fw1_static_conf_section.write_to_buffer(m_image);
+ }
+ else
+ {
+ //ERR("Could not find mandatory section %s\n", section_name.c_str() );
+ //EXIT (-1);
+ }
+ }
+ ptr += NEXT_PTR( 0 );
+
+ if (full_image) {
+ section_name = "ucode_static";
+ if (parser->get_section(section_name, TRANSLATION_MAP_REGTREE | TRANSLATION_MAP_UCODE, &iter1, false, full_image))
+ {
+ fw2_static_conf_section.set_max_size( flash::SUB_SECTOR_SIZE );
+ fw2_static_conf_section.handle_ini_section(TRANSLATION_MAP_REGTREE | TRANSLATION_MAP_UCODE, *(iter1->second));
+ fw2_static_conf_section.set_offset( ptr );
+ fw2_static_conf_section.write_to_buffer(m_image);
+ }else{
+ //ERR("Could not find mandatory section %s\n", section_name.c_str() );
+ //EXIT (-1);
+ }
+ }
+ ptr += NEXT_PTR( 0 );
+
+ section_name = "system_config_section";
+ system_config_section.set_max_size( flash::SUB_SECTOR_SIZE * 4 );
+ if (full_image) {
+ system_config_section.set_offset( ptr );
+ system_config_section.write_to_buffer(m_image);
+ }
+
+ ptr += NEXT_PTR( (1<<14) -1 );
+
+ /*section_name = "user";
+ if (parser->get_section(section_name, TRANSLATION_MAP_REGTREE | TRANSLATION_MAP_FW, &iter1, false, full_image))
+ {
+ user_conf_section.set_max_size( flash::SUB_SECTOR_SIZE );
+ user_conf_section.handle_ini_section(TRANSLATION_MAP_REGTREE | TRANSLATION_MAP_FW, *(iter1->second));
+ user_conf_section.set_offset( ptr );
+ user_conf_section.write_to_buffer(m_image);
+ }
+ ptr += NEXT_PTR( 0 ); */
+
+ bool image_info_section_exist = false;
+ section_name = "image_format_version";
+ if (parser->get_section(section_name, 0, &iter1, true, full_image))
+ {
+ image_info_section.set_max_size( flash::SUB_SECTOR_SIZE );
+ image_info_section.handle_ini_section( *(iter1->second), section_name);
+ image_info_section_exist = true;
+ }
+
+ section_name = "fw_version";
+ if (parser->get_section(section_name, 0, &iter1, true, full_image))
+ {
+ image_info_section.handle_ini_section( *(iter1->second), section_name);
+ image_info_section_exist = true;
+ }
+
+ section_name = "fw_timestamp";
+ if (parser->get_section(section_name, 0, &iter1, true, full_image))
+ {
+ image_info_section.handle_ini_section( *(iter1->second), section_name);
+ image_info_section_exist = true;
+ }
+
+ section_name = "ucode_version";
+ if (parser->get_section(section_name, 0, &iter1, true, full_image))
+ {
+ image_info_section.handle_ini_section( *(iter1->second), section_name);
+ image_info_section_exist = true;
+ }
+
+ section_name = "ucode_timestamp";
+ if (parser->get_section(section_name, 0, &iter1, true, full_image))
+ {
+ image_info_section.handle_ini_section( *(iter1->second), section_name);
+ image_info_section_exist = true;
+ }
+
+ section_name = "configuration_id";
+ if (parser->get_section(section_name, 0, &iter1, true, full_image))
+ {
+ image_info_section.handle_ini_section( *(iter1->second), section_name);
+ image_info_section_exist = true;
+ }
+
+ section_name = "device_id";
+ if (parser->get_section(section_name, 0, &iter1, true, full_image))
+ {
+ image_info_section.handle_ini_section( *(iter1->second), section_name);
+ image_info_section_exist = true;
+ }
+
+ section_name = "hw_id";
+ if (parser->get_section(section_name, 0, &iter1, true, full_image))
+ {
+ image_info_section.handle_ini_section( *(iter1->second), section_name);
+ image_info_section_exist = true;
+ }
+
+ if ( image_info_section_exist ) {
+ image_info_section.set_offset( ptr );
+ image_info_section.write_to_buffer(m_image);
+ }
+ ptr += NEXT_PTR( 0 );
+
+ if (PRODUCT::id == marlon::id) {
+
+ section_name = "radio_tx_conf";
+ if (parser->get_section(section_name, 0, &iter1, false, false) )
+ {
+ // parser->update_section(iter1->second, *(iter2->second), false);
+ radio_tx_conf_section.set_max_size( flash::SUB_SECTOR_SIZE * 2);
+ radio_tx_conf_section.handle_ini_section(0, *(iter1->second));
+ radio_tx_conf_section.set_offset( ptr );
+ radio_tx_conf_section.write_to_buffer(m_image);
+ }
+
+ ptr += NEXT_PTR( (1<<13) -1 ); //Force the section size to be 8K
+ section_name = "radio_rx_conf";
+ if (parser->get_section(section_name, 0, &iter1, false, false) )
+ {
+ // parser->update_section(iter1->second, *(iter2->second), false);
+ radio_rx_conf_section.set_max_size( flash::SUB_SECTOR_SIZE * 2);
+ radio_rx_conf_section.handle_ini_section(0, *(iter1->second));
+ radio_rx_conf_section.set_offset( ptr );
+ radio_rx_conf_section.write_to_buffer(m_image);
+ }
+
+ ptr += NEXT_PTR( (1<<13) -1 ); //Force the section size to be 8K
+ section_name = "radio_tx_conf2";
+ if (parser->get_section(section_name, 0, &iter1, false, false) )
+ {
+ // parser->update_section(iter1->second, *(iter2->second), false);
+ radio_tx_conf2_section.set_max_size( flash::SUB_SECTOR_SIZE * 2);
+ radio_tx_conf2_section.handle_ini_section(0, *(iter1->second));
+ radio_tx_conf2_section.set_offset( ptr );
+ radio_tx_conf2_section.write_to_buffer(m_image);
+ }
+
+ ptr += NEXT_PTR( (1<<13) -1 ); //Force the section size to be 8K
+ section_name = "radio_rx_conf2";
+ if (parser->get_section(section_name, 0, &iter1, false, false) )
+ {
+ // parser->update_section(iter1->second, *(iter2->second), false);
+ radio_rx_conf2_section.set_max_size( flash::SUB_SECTOR_SIZE * 2);
+ radio_rx_conf2_section.handle_ini_section(0, *(iter1->second));
+ radio_rx_conf2_section.set_offset( ptr );
+ radio_rx_conf2_section.write_to_buffer(m_image);
+ }
+
+ ptr += NEXT_PTR( (1<<13) -1 ); //Force the section size to be 8K
+ }
+ section_name = "raw_data";
+ if (parser->get_section(section_name, 0, &iter1, false, false) )
+ {
+ // data_raw limit to 4K
+ raw_data_section.set_max_size( flash::SUB_SECTOR_SIZE);
+ raw_data_section.handle_ini_section( *(iter1->second));
+ raw_data_section.set_offset( ptr );
+ raw_data_section.write_to_buffer(m_image);
+
+ }
+
+ }
+
+ // At the end write the pointer section
+ pointer_section.set_offset( 0 );
+
+ if (full_image)
+ pointer_section.write_to_buffer(m_image);
+
+}
+
diff --git a/debug-tools/wiburn/flash_image.h b/debug-tools/wiburn/flash_image.h
new file mode 100644
index 0000000..167a6a0
--- /dev/null
+++ b/debug-tools/wiburn/flash_image.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _FLASH_IMAGE_H_
+#define _FLASH_IMAGE_H_
+
+#include "wiburn.h"
+#include "flash_sections.h"
+#include "ini_parser.h"
+#include "product.h"
+
+u_int16_t crc_16 (const u_int32_t *buffer, int size);
+
+template <class PRODUCT>
+class flash_image
+{
+public:
+ flash_image ();
+ ~flash_image ();
+ void init (ini_parser_base *parser, bool full_image, bool isReducedSip); // init from ini file
+ void init (const char *filename); // init from image file
+ void init_pointer_section (flash_base *fl); // init from flash
+ void init_hw_conf_section (flash_base *fl); // init from flash
+ // void init_radio_tx_conf_section (flash_base *fl); // init from flash
+ // void init_radio_rx_conf_section (flash_base *fl); // init from flash
+ // void init_radio_tx_conf2_section (flash_base *fl); // init from flash
+ // void init_radio_rx_conf2_section (flash_base *fl); // init from flash
+ void init_image_info_section (flash_base *fl); // init from flash
+ void init_ids_section (flash_base *fl, bool isReduced); // init from flash
+ void init_usb_info_section (flash_base *fl); // init from flash
+ void save (const char *filename);
+ const BYTE* get_image (void) const;
+ u_int32_t get_image_size (void) const;
+ const pointer_section_t <PRODUCT> & get_pointer_section(void) const;
+ const hw_section_t <PRODUCT> & get_hw_conf_section(void) const;
+ // const hw_section_t <marlon> & get_radio_tx_conf_section(void) const;
+ // const hw_section_t <marlon> & get_radio_rx_conf_section(void) const;
+ // const hw_section_t <marlon> & get_radio_tx_conf2_section(void) const;
+ // const hw_section_t <marlon> & get_radio_rx_conf2_section(void) const;
+ const image_info_section_t<PRODUCT>& get_image_info_section(void) const;
+ const usb_info_section_t<PRODUCT>& get_usb_info_section(void) const;
+ const ids_section_t<PRODUCT>& get_ids_section(void) const;
+ // const image_section_t<PRODUCT>& get_fw1_code_section () const;
+ // const image_section_t<PRODUCT>& get_fw2_code_section () const;
+private:
+ pointer_section_t <PRODUCT> pointer_section;
+ hw_section_t <PRODUCT> hw_conf_section;
+
+ image_section_t<PRODUCT> fw1_code_section;
+ image_section_t<PRODUCT> fw1_data_section;
+ fw_section_t <PRODUCT> fw1_static_conf_section;
+
+ image_section_t<PRODUCT> fw2_code_section;
+ image_section_t<PRODUCT> fw2_data_section;
+ fw_section_t <PRODUCT> fw2_static_conf_section;
+
+ system_config_section_t <PRODUCT> system_config_section;
+
+ hw_section_t <PRODUCT> production_section;
+ fw_section_t <PRODUCT> user_conf_section;
+
+ image_info_section_t<PRODUCT> image_info_section;
+ ids_section_t<PRODUCT> ids_section;
+
+ usb_section_t usb_section;
+ usb_info_section_t<PRODUCT> usb_info_section;
+
+ hw_section_t <marlon> radio_tx_conf_section;
+ hw_section_t <marlon> radio_rx_conf_section;
+ hw_section_t <marlon> radio_tx_conf2_section;
+ hw_section_t <marlon> radio_rx_conf2_section;
+
+ image_section_t<PRODUCT> raw_data_section;
+
+ IProduct* proxy_product;
+
+private:
+#ifdef FLASH_256KB
+ BYTE m_image [(1<<21)/8]; //2Mbits - 256KB
+#else
+ BYTE m_image [1024*512]; //1MB
+ // TALYN BYTE m_image [1024*4*512]; //1MB
+#endif
+};
+
+#endif //#ifndef _FLASH_IMAGE_H_
diff --git a/debug-tools/wiburn/flash_sections.cpp b/debug-tools/wiburn/flash_sections.cpp
new file mode 100644
index 0000000..1080832
--- /dev/null
+++ b/debug-tools/wiburn/flash_sections.cpp
@@ -0,0 +1,1382 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "flash_sections.h"
+#include "ini_parser.h"
+#include "flash_image.h"
+#include <fstream>
+#include <iostream>
+#include <iomanip>
+
+//extern class ini_parser g_parser;
+//extern ini_parser g_parser;
+
+u_int64_t current_fw_build = 999999;
+
+void format_version_tag_t::disp(const char *name)
+{
+ printf("%s : %d\n", name, format_version);
+}
+
+void version_tag_t::disp(const char *name)
+{
+ printf("%s : %02d.%02d.%02d.%02d\n",name, major, minor, sub_minor, build);
+}
+
+void timestamp_tag_t::disp(const char *name)
+{
+ printf("%s (D/M/Y H:M:S) : %02d/%02d/%04d %02d:%02d:%02d\n"
+ ,name, day, month, year, hour, min, sec );
+}
+
+void configuration_id_tag_t::disp(const char *name)
+{
+ //unused param
+ (void)name;
+ BYTE *null_terminated_buffer = new BYTE [sizeof (id) + 1];
+ memcpy(null_terminated_buffer, id, sizeof (id));
+ null_terminated_buffer[sizeof (id)] = 0;
+ printf("CONFIGURATION_ID = %s\n", null_terminated_buffer);
+ delete[] null_terminated_buffer;
+
+ //printf("CONFIGURATION_ID = ");
+ //print_buffer(id, sizeof id);
+ //printf("\n");
+}
+
+void device_id_tag_t::disp(const char *name)
+{
+ //unused param
+ (void)name;
+ cout << "device_id :" << endl;
+ cout << " device_id = " << (int)device_id << endl;
+ cout << " revision_id = " << (int)revision_id << endl;
+ cout << " misc = " << (int)misc << endl;
+}
+
+void hw_id_tag_t::disp(const char *name)
+{
+ //unused param
+ (void)name;
+ cout << "hw_id :" << endl;
+ cout << " digital_soc_id = " << (int)digital_soc_id << endl;
+ cout << " board_id = " << (int)board_id<< endl;
+ cout << " antenna_id = " << (int)antenna_id<< endl;
+ cout << " rf_id = " << (int)rf_id<< endl;
+ cout << " serial_id = " << (int)serial_id<< endl;
+}
+
+void end_tag_t::disp(const char *name)
+{
+ //unused param
+ (void)name;
+}
+
+//
+// TAG
+//
+tag_base_t::tag_base_t (BYTE id, const char *name)
+{
+ m_header.reserved = 0;
+ m_header.tag_id = id;
+ this->m_name = name;
+}
+
+template <typename Tag>
+tag_t <Tag> ::tag_t (BYTE id, const char* name)
+ :tag_base_t(id, name)
+{
+ m_header.tag_size = sizeof(Tag);
+ memset(&m_tag, 0, sizeof(Tag));
+}
+
+template <typename Tag>
+char *tag_t <Tag>::get_tag()
+{
+ return (char*)&m_tag;
+};
+
+template <typename Tag>
+void tag_t<Tag>::disp()
+{
+ m_tag.disp(this->m_name);
+}
+
+
+//
+// FLASH section
+//
+flash_section::flash_section (const char *name)
+{
+ this->m_name = name;
+ this->m_size = 0;
+ m_offset = 0;
+ this->m_crc = 0;
+ this->m_max_size = 0;
+}
+
+int flash_section::size () const
+{
+ return this->m_size;
+}
+
+int flash_section::get_max_size () const
+{
+ return this->m_max_size;
+}
+
+void flash_section::set_max_size ( u_int32_t max_size ) {
+ this->m_max_size = max_size;
+}
+
+void flash_section::set_offset( u_int32_t offset )
+{
+ m_offset = offset;
+}
+
+u_int32_t flash_section::get_offset () const
+{
+ return m_offset;
+}
+
+//
+// POINTER section
+//
+template <class PRODUCT>
+pointer_section_t<PRODUCT>::pointer_section_t (const char *name)
+ : flash_section(name)
+{
+ memset(&m_pointers, -1, sizeof (m_pointers));
+ m_pointers.signature = 0x40;
+ this->m_size = sizeof (m_pointers);
+}
+
+template <class PRODUCT>
+void pointer_section_t<PRODUCT>::init (flash_base *fl)
+{
+ fl->read(0, this->m_size, (BYTE*)&m_pointers);
+}
+
+template <class PRODUCT>
+bool pointer_section_t<PRODUCT>::operator == (const pointer_section_t <PRODUCT> &r_side) const
+{
+ int res = memcmp(&m_pointers, &(r_side.m_pointers), sizeof (m_pointers));
+ return (res == 0);
+}
+
+template <class PRODUCT>
+void pointer_section_t<PRODUCT>::write_to_buffer( BYTE *buffer )
+{
+ INFO("%s: Writing section of size 0x%04x at offset 0x%04x\n",this->m_name, this->m_size, m_offset);
+ int current_offset = m_offset;
+ memcpy(buffer + current_offset, &m_pointers, sizeof (m_pointers));
+ current_offset += sizeof (m_pointers);
+
+// this->m_crc = crc_16((u_int32_t*)(buffer+m_offset), this->m_size - sizeof (this->m_crc));
+ this->m_crc = m_CalcCRC.CalcCRC((UCHAR*)(buffer+m_offset), this->m_size - sizeof (this->m_crc));
+ memcpy(buffer+current_offset, &this->m_crc, sizeof (this->m_crc));
+}
+
+//
+// ID section
+//
+//id_section::id_section (const char *name, BYTE id, u_int16_t *ptr_low, u_int16_t* ptr_high)
+id_section::id_section (const char *name, BYTE id, ADDRESS32 *ptr)
+ : flash_section(name)
+{
+ this->header.reserved = 0;
+ this->header.section_id = id;
+// m_ptr_low = ptr_low;
+// m_ptr_high = ptr_high;
+ this->m_ptr = ptr;
+ this->m_size = sizeof(section_header_t);
+};
+
+void id_section::set_offset (int offset)
+{
+ flash_section::set_offset(offset);
+ offset += sizeof(section_header_t);
+ //*m_ptr_low = (u_int16_t)offset;
+ //*m_ptr_high = (u_int16_t)(offset>>16);
+ *this->m_ptr = offset;
+}
+
+//
+// VARIABLE section
+//variable_section_t::variable_section_t (const char *name, BYTE id, u_int16_t *ptr_low, u_int16_t* ptr_high)
+//: id_section( name, id, ptr_low, ptr_high)
+variable_section_t::variable_section_t (const char *name, BYTE id, ADDRESS32* ptr)
+ : id_section( name, id, ptr)
+{
+ //nothing to do
+}
+
+variable_section_t::~variable_section_t ()
+{
+ //nothing to do
+}
+
+//
+// HW SECTION
+//
+template <class PRODUCT>
+//hw_section_t<PRODUCT>::hw_section_t (const char *name, BYTE id, u_int16_t *ptr_low , u_int16_t *ptr_high)
+//: variable_section_t(name, id, ptr_low, ptr_high)
+hw_section_t<PRODUCT>::hw_section_t (const char *name, BYTE id, ADDRESS32 *ptr)
+ : variable_section_t(name, id, ptr)
+{
+ m_termination[0] = -1;
+ m_termination[1] = -1;
+ m_buffer = 0;
+}
+
+template <class PRODUCT>
+void hw_section_t<PRODUCT>::write_to_buffer( BYTE *buffer )
+{
+ INFO("%s: Writing section of size 0x%04x at offset 0x%04x\n",this->m_name, this->m_size, m_offset);
+
+ int current_offset = m_offset;
+ memcpy(buffer + current_offset, &this->header, sizeof(this->header));
+ current_offset += sizeof(this->header);
+ memcpy(buffer + current_offset, m_buffer, m_buffer_size);
+ current_offset += m_buffer_size;
+
+ memcpy(buffer + current_offset, (char*)&m_termination, sizeof(m_termination));
+ current_offset += sizeof (m_termination);
+
+// this->m_crc = crc_16((u_int32_t*)(buffer+m_offset), this->m_size - sizeof (this->m_crc));
+ this->m_crc = m_CalcCRC.CalcCRC((UCHAR*)(buffer+m_offset), this->m_size - sizeof (this->m_crc));
+ memcpy(buffer+current_offset, &this->m_crc, sizeof (this->m_crc));
+}
+
+template <class PRODUCT>
+void hw_section_t<PRODUCT>::handle_ini_section (u_int8_t translation_map_bits, const ini_section_t &ini_section)
+{
+ int size = ini_section.size();
+ m_buffer = new address_value_t<PRODUCT> [size];
+ m_buffer_size = size * (sizeof (address_value_t<PRODUCT>));
+ memset((void*)m_buffer, -1, m_buffer_size);
+ // buffer + this->header + FFFFs
+ this->m_size += m_buffer_size + sizeof (m_termination) + sizeof (this->m_crc);
+ this->header.section_size = (u_int16_t)this->m_size;
+ this->header.section_size -= sizeof (this->m_crc); //TBD remove - FW does not support CRC yet
+
+ ini_section_t::const_iterator sec_iter;
+ sec_iter = ini_section.begin();
+ int index = 0;
+ typename PRODUCT::ADDRESS temp_address;
+ typename PRODUCT::REG temp_value;
+ while (sec_iter != ini_section.end())
+ {
+ ini_parser<PRODUCT>::get_resolved_address_data(translation_map_bits,
+ sec_iter,
+ &temp_address,
+ &temp_value);
+
+ m_buffer[index].address = temp_address;
+ m_buffer[index].value = temp_value;
+
+ index++;
+ sec_iter++;
+ }
+
+ if (this->m_size > this->m_max_size) {
+ ERR("Section %s with size %d exceeds maximum section size of %d\n",
+ this->m_name, this->m_size, this->m_max_size );
+ EXIT (-1);
+ }
+}
+
+template <class PRODUCT>
+void hw_section_t<PRODUCT>::init (flash_base *fl)
+{
+ //u_int32_t section_address = (*m_ptr_low | ((*m_ptr_high) << 16));
+ u_int32_t section_address = *this->m_ptr;
+ u_int32_t header_address = section_address - sizeof (section_header_t);
+
+ // get the section this->header
+ fl->read(header_address, sizeof (section_header_t), (BYTE*)&this->header);
+
+ // get the section
+ m_buffer_size = this->header.section_size - sizeof (section_header_t) - sizeof (this->m_crc) - sizeof (m_termination);
+ m_buffer_size += sizeof (this->m_crc); // TBD remove when CRC is supported by FW
+ m_buffer = new address_value_t<PRODUCT> [m_buffer_size / (sizeof (address_value_t<PRODUCT>))];
+ fl->read(section_address, m_buffer_size, (BYTE*)m_buffer);
+
+ // get the termination
+ fl->read(section_address+m_buffer_size, sizeof (m_termination), (BYTE*)&m_termination);
+ // get the CRC ???
+
+}
+
+template <class PRODUCT>
+bool hw_section_t<PRODUCT>::operator == (const hw_section_t <PRODUCT> &r_side) const
+{
+ int res = memcmp(&this->header, &r_side.header, sizeof (section_header_t));
+ res |= memcmp(m_buffer, r_side.m_buffer, m_buffer_size);
+ res |= memcmp(m_termination, r_side.m_termination, sizeof (m_termination));
+ return (res == 0);
+}
+
+template <class PRODUCT>
+hw_section_t<PRODUCT>::~hw_section_t ()
+{
+ delete m_buffer;
+};
+
+
+//
+// System Config Section
+//
+template <class PRODUCT>
+system_config_section_t<PRODUCT>::system_config_section_t (const char *name, ADDRESS32 *ptr)
+ : flash_section(name)
+{
+ this->m_ptr = ptr;
+}
+
+template <class PRODUCT>
+void system_config_section_t<PRODUCT>::write_to_buffer( BYTE *buffer )
+{
+ //unused param
+ (void)buffer;
+ INFO("%s: Preparing empty section at offset 0x%04x\n",this->m_name, m_offset);
+}
+
+template <class PRODUCT>
+void system_config_section_t<PRODUCT>::set_offset (int offset)
+{
+ this->m_offset = offset;
+
+ *this->m_ptr = offset;
+ //pointer_section.m_pointers.config_section_pointer = ptr;
+}
+
+
+//
+// FW section
+//
+template <class PRODUCT>
+//fw_section_t<PRODUCT>::fw_section_t (const char *name, BYTE id, u_int16_t *ptr_low , u_int16_t *ptr_high)
+//: variable_section_t(name, id, ptr_low , ptr_high)
+fw_section_t<PRODUCT>::fw_section_t (const char *name, BYTE id, ADDRESS32 *ptr)
+ : variable_section_t(name, id, ptr)
+{
+ m_buffer = 0;
+}
+
+template <class PRODUCT>
+void fw_section_t<PRODUCT>::write_to_buffer(BYTE *buffer )
+{
+ INFO("%s: Writing section of size 0x%04x at offset 0x%04x\n",this->m_name, this->m_size, m_offset);
+
+ int current_offset = m_offset;
+ memcpy(buffer + current_offset, &this->header, sizeof (this->header));
+ current_offset += sizeof (this->header);
+ memcpy(buffer + current_offset, m_buffer, m_buffer_size);
+ current_offset += m_buffer_size;
+
+// this->m_crc = crc_16((u_int32_t*)(buffer+m_offset), this->m_size - sizeof (this->m_crc));
+ this->m_crc = m_CalcCRC.CalcCRC((UCHAR*)(buffer+m_offset), this->m_size - sizeof (this->m_crc));
+ memcpy(buffer+current_offset, &this->m_crc, sizeof (this->m_crc));
+}
+
+template <class PRODUCT>
+void fw_section_t<PRODUCT>::handle_ini_section (u_int8_t translation_map_bits, const ini_section_t &ini_section)
+{
+ int size = ini_section.size();
+ m_buffer = new address_value_mask_t<PRODUCT> [size];
+ m_buffer_size = size * (sizeof (address_value_mask_t<PRODUCT>));
+ memset((void*)m_buffer, -1, m_buffer_size);
+ // buffer + this->header + CRC
+ this->m_size += m_buffer_size + sizeof (this->m_crc);
+ this->header.section_size = (u_int16_t)this->m_size;
+// this->header.section_size -= sizeof (this->m_crc); //TBD remove - FW does not support CRC yet
+
+ ini_section_t::const_iterator sec_iter;
+ sec_iter = ini_section.begin();
+ int index = 0;
+ typename PRODUCT::ADDRESS temp_address;
+ typename PRODUCT::REG temp_value;
+ int start, end;
+ while (sec_iter != ini_section.end())
+ {
+ ini_parser<PRODUCT>::get_resolved_address_data(
+ translation_map_bits,
+ sec_iter,
+ &temp_address,
+ &temp_value,
+ &start,
+ &end);
+ m_buffer[index].address = temp_address;
+ m_buffer[index].value = temp_value;
+ m_buffer[index].value <<= start;
+ m_buffer[index].mask = ~(((2 << (end - start)) - 1) << start);
+ index++;
+ sec_iter++;
+ }
+ if (this->m_size > this->m_max_size) {
+ ERR("Section %s with size %d exceeds maximum section size of %d\n",
+ this->m_name, this->m_size, this->m_max_size );
+ EXIT (-1);
+ }
+}
+
+template <class PRODUCT>
+fw_section_t<PRODUCT>::~fw_section_t ()
+{
+ delete m_buffer;
+};
+
+//
+// Image section
+//
+//image_section_t::image_section_t (const char *name, BYTE id, u_int16_t *ptr_low,
+// u_int16_t *ptr_high, u_int16_t *length)
+//: variable_section_t(name, id, ptr_low , ptr_high)
+template <class PRODUCT>
+image_section_t<PRODUCT>::image_section_t (const char *name, BYTE id, ADDRESS32 *ptr, typename PRODUCT::REG *length)
+ : variable_section_t(name, id, ptr)
+{
+ m_length = length;
+ m_buffer = 0;
+}
+
+template <class PRODUCT>
+void image_section_t<PRODUCT>::set_offset (int offset)
+{
+ id_section::set_offset(offset);
+ // length in pointer section is w/o the section this->header and w/o the CRC
+ *m_length = ( typename PRODUCT::REG)(this->m_size - sizeof (section_header_t) - sizeof (this->m_crc));
+}
+
+template <class PRODUCT>
+void image_section_t<PRODUCT>::write_to_buffer(BYTE *buffer)
+{
+ INFO("%s: Writing section of size 0x%04x at offset 0x%04x\n",this->m_name, this->m_size, m_offset);
+
+ int current_offset = m_offset;
+ memcpy(buffer + current_offset, &this->header, sizeof (this->header));
+ current_offset += sizeof (this->header);
+ memcpy(buffer + current_offset, m_buffer, m_buffer_size);
+ current_offset += m_buffer_size;
+
+// this->m_crc = crc_16((u_int32_t*)(buffer+m_offset), this->m_size - sizeof (this->m_crc));
+ this->m_crc = m_CalcCRC.CalcCRC((UCHAR*)(buffer+m_offset+sizeof (this->header)), m_buffer_size);
+ memcpy(buffer+current_offset, &this->m_crc, sizeof (this->m_crc));
+}
+
+template <class PRODUCT>
+void image_section_t<PRODUCT>::handle_ini_section (const ini_section_t &ini_section)
+{
+ int size = ini_section.size();
+ m_buffer = new IMAGE [size];
+ m_buffer_size = size * (sizeof (IMAGE));
+ memset((void*)m_buffer, -1, m_buffer_size);
+ // buffer + this->header + CRC
+ this->m_size += m_buffer_size + sizeof (this->m_crc);
+ this->header.section_size = (u_int16_t)this->m_size;
+// this->header.section_size -= sizeof (this->m_crc); //TBD remove - FW does not support CRC yet
+
+ ini_section_t::const_iterator sec_iter;
+ sec_iter = ini_section.begin();
+ int index = 0;
+ while (sec_iter != ini_section.end())
+ {
+ get_resolved_data(sec_iter, &m_buffer[index]);
+ index++;
+ sec_iter++;
+ }
+
+ if (this->m_size > this->m_max_size) {
+ ERR("Section %s with size %d exceeds maximum section size of %d\n",
+ this->m_name, this->m_size, this->m_max_size );
+ EXIT (-1);
+ }
+}
+
+template <class PRODUCT>
+image_section_t<PRODUCT>::~image_section_t ()
+{
+ delete m_buffer;
+};
+
+//
+// TAG section
+//
+
+//info_section_t::info_section_t (const char *name, BYTE id, u_int16_t *ptr_low , u_int16_t *ptr_high)
+//: variable_section_t(name, id, ptr_low , ptr_high)
+template <class PRODUCT>
+info_section_t<PRODUCT>::info_section_t (const char *name, BYTE id, ADDRESS32* ptr)
+ : variable_section_t(name, id, ptr)
+{
+ this->m_size += sizeof (this->m_crc); //for CRC
+}
+
+template <class PRODUCT>
+void info_section_t<PRODUCT>::write_to_buffer(BYTE *buffer)
+{
+ tag_t<end_tag_t> *tag = new tag_t<end_tag_t> (end_tag_id);
+ this->m_size += sizeof (end_tag_t) + sizeof (tag_header_t);
+ this->m_tags.insert(this->m_tags.end(), tag);
+ this->header.section_size = (u_int16_t)this->m_size;
+// this->header.section_size -= sizeof (this->m_crc); //TBD remove - FW does not support CRC yet
+
+ INFO("%s: Writing section of size 0x%04x at offset 0x%04x\n",this->m_name, this->m_size, m_offset);
+
+ int current_offset = m_offset;
+ memcpy(buffer + current_offset, &this->header, sizeof (this->header));
+ current_offset += sizeof (this->header);
+
+ tag_vector_t::const_iterator iter = this->m_tags.begin();
+ while (iter != this->m_tags.end()) {
+ tag_base_t *tag_base = *iter;
+ memcpy(buffer + current_offset, &(tag_base->m_header), sizeof (tag_header_t));
+ current_offset += sizeof (tag_header_t);
+
+ memcpy(buffer + current_offset, tag_base->get_tag(), tag_base->m_header.tag_size);
+ current_offset += tag_base->m_header.tag_size;
+ iter++;
+ }
+
+// this->m_crc = crc_16((u_int32_t*)(buffer+m_offset), this->m_size - sizeof (this->m_crc));
+ this->m_crc = m_CalcCRC.CalcCRC((UCHAR*)(buffer+m_offset), this->m_size - sizeof (this->m_crc));
+ memcpy(buffer+current_offset, &this->m_crc, sizeof (this->m_crc));
+}
+
+template <class PRODUCT>
+void info_section_t<PRODUCT>::disp() const
+{
+ tag_vector_t::const_iterator iter = this->m_tags.begin();
+ while (iter != this->m_tags.end()) {
+ tag_base_t *tag_base = *iter;
+ tag_base->disp();
+ iter++;
+ }
+}
+
+template <class PRODUCT>
+info_section_t<PRODUCT>::~info_section_t ()
+{
+ tag_vector_t::const_iterator iter = this->m_tags.begin();
+ while (iter != this->m_tags.end()) {
+ tag_base_t *tag_base = *iter;
+ delete tag_base;
+ iter++;
+ }
+}
+
+//
+// Image_info
+//
+//image_info_section_t::image_info_section_t (const char *name, BYTE id, u_int16_t *ptr_low , u_int16_t *ptr_high)
+//:info_section_t(name, id, ptr_low, ptr_high)
+template <class PRODUCT>
+image_info_section_t<PRODUCT>::image_info_section_t (const char *name, BYTE id, ADDRESS32 *ptr)
+ :info_section_t<PRODUCT>(name, id, ptr)
+{
+ // nothing to do
+}
+
+template <class PRODUCT>
+void image_info_section_t<PRODUCT>::handle_ini_section (const ini_section_t &ini_section,
+ const string &name)
+{
+ string key;
+ u_int64_t value;
+ if( "image_format_version" == name ) {
+ tag_t<format_version_tag_t> *tag = new tag_t<format_version_tag_t> (image_format_version_tag_id, name.data());
+ this->m_size += sizeof (format_version_tag_t) + sizeof (tag_header_t);
+ this->m_tags.insert(this->m_tags.end(), tag);
+ key = "format_version";
+ get_value(ini_section, key, &value );
+ tag->m_tag.format_version = (BYTE)value;
+ }
+ else if (( "fw_version" == name ) || ( "ucode_version" == name )){
+ tag_t<version_tag_t> *tag = new tag_t<version_tag_t> (fw_version_tag_id, name.data());
+ this->m_size += sizeof (version_tag_t) + sizeof (tag_header_t);
+ this->m_tags.insert(this->m_tags.end(), tag);
+ key = "build";
+ if( get_value(ini_section, key, &value )) {
+ tag->m_tag.build = value;
+ if ("fw_version" == name) {
+ // Remember the current fw build number for later use
+ current_fw_build = value;
+ }
+ }
+ else {
+ ERR("Missing key %s in tag %s\n", key.c_str(), name.c_str());
+ EXIT (-1);
+ }
+ key = "major";
+ if( get_value(ini_section, key, &value )) {
+ tag->m_tag.major = (BYTE)value;
+ }
+ else {
+ ERR("Missing key %s in tag %s\n", key.c_str(), name.c_str());
+ EXIT (-1);
+ }
+ key = "minor";
+ if( get_value(ini_section, key, &value )) {
+ tag->m_tag.minor = (BYTE)value;
+ }
+ else {
+ ERR("Missing key %s in tag %s\n", key.c_str(), name.c_str());
+ EXIT (-1);
+ }
+ key = "sub_minor";
+ if( get_value(ini_section, key, &value )) {
+ tag->m_tag.sub_minor = (BYTE)value;
+ }
+ else {
+ ERR("Missing key %s in tag %s\n", key.c_str(), name.c_str());
+ EXIT (-1);
+ }
+ }
+ else if (("fw_timestamp" == name ) || ( "ucode_timestamp" == name )) {
+ tag_t<timestamp_tag_t> *tag = new tag_t<timestamp_tag_t> (fw_timestamp_tag_id, name.data());
+ this->m_size += sizeof (timestamp_tag_t) + sizeof (tag_header_t);
+ this->m_tags.insert(this->m_tags.end(), tag);
+ key = "sec";
+ if( get_value(ini_section, key, &value )) {
+ tag->m_tag.sec = (BYTE)value;
+ }
+ else {
+ ERR("Missing key %s in tag %s\n", key.c_str(), name.c_str());
+ EXIT (-1);
+ }
+ key = "min";
+ if( get_value(ini_section, key, &value )) {
+ tag->m_tag.min = (BYTE)value;
+ }
+ else {
+ ERR("Missing key %s in tag %s\n", key.c_str(), name.c_str());
+ EXIT (-1);
+ }
+ key = "hour";
+ if( get_value(ini_section, key, &value )) {
+ tag->m_tag.hour = (BYTE)value;
+ }
+ else {
+ ERR("Missing key %s in tag %s\n", key.c_str(), name.c_str());
+ EXIT (-1);
+ }
+ key = "day";
+ if( get_value(ini_section, key, &value )) {
+ tag->m_tag.day = (BYTE)value;
+ }
+ else {
+ ERR("Missing key %s in tag %s\n", key.c_str(), name.c_str());
+ EXIT (-1);
+ }
+ key = "month";
+ if( get_value(ini_section, key, &value )) {
+ tag->m_tag.month = (BYTE)value;
+ }
+ else {
+ ERR("Missing key %s in tag %s\n", key.c_str(), name.c_str());
+ EXIT (-1);
+ }
+ key = "year";
+ if( get_value(ini_section, key, &value )) {
+ tag->m_tag.year = (u_int16_t)value;
+ }
+ else {
+ ERR("Missing key %s in tag %s\n", key.c_str(), name.c_str());
+ EXIT (-1);
+ }
+ }
+ else if ("configuration_id" == name ) {
+ tag_t<configuration_id_tag_t> *tag = new tag_t<configuration_id_tag_t> (configuration_id_tag_id, name.data());
+ this->m_size += sizeof (configuration_id_tag_t) + sizeof (tag_header_t);
+ this->m_tags.insert(this->m_tags.end(), tag);
+ key = "configuration_id";
+ get_string(ini_section, key, tag->m_tag.id, sizeof (tag->m_tag.id));
+ }
+ else if ("device_id" == name ) {
+ tag_t<device_id_tag_t> *tag = new tag_t<device_id_tag_t> (device_id_tag_id, name.data());
+ this->m_size += sizeof (device_id_tag_t) + sizeof (tag_header_t);
+ this->m_tags.insert(this->m_tags.end(), tag);
+ key = "device_id";
+ if( get_value(ini_section, key, &value )) {
+ tag->m_tag.device_id = (u_int16_t)value;
+ }
+ else {
+ ERR("Missing key %s in tag %s\n", key.c_str(), name.c_str());
+ EXIT (-1);
+ }
+ key = "misc";
+ if( get_value(ini_section, key, &value )) {
+ tag->m_tag.misc = (BYTE)value;
+ }
+ else {
+ ERR("Missing key %s in tag %s\n", key.c_str(), name.c_str());
+ EXIT (-1);
+ }
+ key = "revision_id";
+ if( get_value(ini_section, key, &value )) {
+ tag->m_tag.revision_id = (BYTE)value;
+ }
+ else {
+ ERR("Missing key %s in tag %s\n", key.c_str(), name.c_str());
+ EXIT (-1);
+ }
+ }
+ else if ("hw_id" == name ) {
+ tag_t<hw_id_tag_t> *tag = new tag_t<hw_id_tag_t> (hw_id_tag_id, name.data());
+ this->m_size += sizeof (hw_id_tag_t) + sizeof (tag_header_t);
+ this->m_tags.insert(this->m_tags.end(), tag);
+ key = "antenna_id";
+ if( get_value(ini_section, key, &value )) {
+ tag->m_tag.antenna_id = (BYTE)value;
+ }
+ else {
+ ERR("Missing key %s in tag %s\n", key.c_str(), name.c_str());
+ EXIT (-1);
+ }
+ key = "board_id";
+ if( get_value(ini_section, key, &value )) {
+ tag->m_tag.board_id = (BYTE)value;
+ }
+ else {
+ ERR("Missing key %s in tag %s\n", key.c_str(), name.c_str());
+ EXIT (-1);
+ }
+ key = "digital_soc_id";
+ if( get_value(ini_section, key, &value )) {
+ tag->m_tag.digital_soc_id = (BYTE)value;
+ }
+ else {
+ ERR("Missing key %s in tag %s\n", key.c_str(), name.c_str());
+ EXIT (-1);
+ }
+ key = "rf_id";
+ if( get_value(ini_section, key, &value )) {
+ tag->m_tag.rf_id = (BYTE)value;
+ }
+ else {
+ ERR("Missing key %s in tag %s\n", key.c_str(), name.c_str());
+ EXIT (-1);
+ }
+ key = "serial_id";
+ if( get_value(ini_section, key, &value )) {
+ tag->m_tag.serial_id = (u_int16_t)value;
+ }
+ else {
+ ERR("Missing key %s in tag %s\n", key.c_str(), name.c_str());
+ EXIT (-1);
+ }
+ } else {
+ ERR("Unknown tag name %s\n", name.c_str());
+ EXIT (-1);
+ }
+
+ this->header.section_size = (u_int16_t)this->m_size;
+ this->header.section_size -= sizeof (this->m_crc); //TBD remove - FW does not support CRC yet
+
+ if (this->m_size > this->m_max_size) {
+ ERR("Section %s with size %d exceeds maximum section size of %d\n",
+ this->m_name, this->m_size, this->m_max_size );
+ EXIT (-1);
+ }
+}
+
+template <class PRODUCT>
+void image_info_section_t<PRODUCT>::init(flash_base *fl)
+{
+ //u_int32_t section_address = (*m_ptr_low | ((*m_ptr_high) << 16));
+ u_int32_t section_address = *this->m_ptr;
+ u_int32_t header_address = section_address - sizeof (section_header_t);
+
+ // get the section header
+ fl->read(header_address, sizeof (section_header_t), (BYTE*)&this->header);
+ this->m_size = this->header.section_size;
+
+ u_int16_t offset = sizeof (section_header_t);
+ while (offset < this->header.section_size) {
+ tag_header_t tag_header;
+ fl->read(header_address+offset, sizeof (tag_header_t), (BYTE*)&tag_header);
+ offset += sizeof (tag_header_t);
+
+ tag_base_t *tag = NULL;
+ switch (tag_header.tag_id) {
+ case image_format_version_tag_id : {
+ tag = new tag_t<format_version_tag_t> (tag_header.tag_id, "image_format_version");
+ break;
+ }
+ case fw_version_tag_id : {
+ tag = new tag_t<version_tag_t> (tag_header.tag_id, "fw_version");
+ break;
+ }
+ case fw_timestamp_tag_id : {
+ tag = new tag_t<timestamp_tag_t> (tag_header.tag_id, "fw_timestamp");
+ break;
+ }
+ case configuration_id_tag_id : {
+ tag = new tag_t<configuration_id_tag_t> (tag_header.tag_id, "configuration_id");
+ break;
+ }
+ case device_id_tag_id : {
+ tag = new tag_t<device_id_tag_t> (tag_header.tag_id, "device_id");
+ break;
+ }
+ case hw_id_tag_id : {
+ tag = new tag_t<hw_id_tag_t> (tag_header.tag_id, "hw_id");
+ break;
+ }
+ case end_tag_id : {
+ tag = new tag_t<end_tag_t> (tag_header.tag_id);
+ break;
+ }
+ default: {
+ ERR("Unknown tag id %d\n", tag_header.tag_id);
+// EXIT (-1);
+ }
+ }
+
+ if (tag != NULL)
+ {
+ fl->read(header_address+offset, tag_header.tag_size, (BYTE*)tag->get_tag());
+ offset += tag_header.tag_size;
+
+ this->m_tags.insert(this->m_tags.end(), tag);
+ }
+ }
+}
+
+template <class PRODUCT>
+image_info_section_t<PRODUCT>::~image_info_section_t ()
+{
+ // nothing to do
+}
+
+//
+// USB_Info
+//
+//usb_info_section_t::usb_info_section_t (const char *name, BYTE id, u_int16_t *ptr_low , u_int16_t *ptr_high)
+//:info_section_t(name, id, ptr_low, ptr_high)
+template <class PRODUCT>
+usb_info_section_t<PRODUCT>::usb_info_section_t (const char *name, BYTE id, ADDRESS32 *ptr)
+ :info_section_t<PRODUCT>(name, id, ptr)
+{
+ // nothing to do
+}
+
+template <class PRODUCT>
+void usb_info_section_t<PRODUCT>::handle_ini_section (const ini_section_t &ini_section,
+ const string &name)
+{
+ string key;
+ u_int64_t value;
+ if( "usb_image_format_version" == name ) {
+ tag_t<format_version_tag_t> *tag = new tag_t<format_version_tag_t> (usb_format_version_tag_id, name.data());
+ this->m_size += sizeof (format_version_tag_t) + sizeof (tag_header_t);
+ this->m_tags.insert(this->m_tags.end(), tag);
+ key = "format_version";
+ get_value(ini_section, key, &value );
+ tag->m_tag.format_version = (BYTE)value;
+ }
+ else if( "usb_version" == name ) {
+ tag_t<version_tag_t> *tag = new tag_t<version_tag_t> (usb_version_tag_id, name.data());
+ this->m_size += sizeof (version_tag_t) + sizeof (tag_header_t);
+ this->m_tags.insert(this->m_tags.end(), tag);
+ key = "build";
+ if( get_value(ini_section, key, &value )) {
+ tag->m_tag.build = value;
+ }
+ else {
+ ERR("Missing key %s in tag %s\n", key.c_str(), name.c_str());
+ EXIT (-1);
+ }
+ key = "major";
+ if( get_value(ini_section, key, &value )) {
+ tag->m_tag.major = (BYTE)value;
+ }
+ else {
+ ERR("Missing key %s in tag %s\n", key.c_str(), name.c_str());
+ EXIT (-1);
+ }
+ key = "minor";
+ if( get_value(ini_section, key, &value )) {
+ tag->m_tag.minor = (BYTE)value;
+ }
+ else {
+ ERR("Missing key %s in tag %s\n", key.c_str(), name.c_str());
+ EXIT (-1);
+ }
+ key = "sub_minor";
+ if( get_value(ini_section, key, &value )) {
+ tag->m_tag.sub_minor = (BYTE)value;
+ }
+ else {
+ ERR("Missing key %s in tag %s\n", key.c_str(), name.c_str());
+ EXIT (-1);
+ }
+ }
+ else if ("usb_timestamp" == name ) {
+ tag_t<timestamp_tag_t> *tag = new tag_t<timestamp_tag_t> (usb_timestamp_tag_id, name.data());
+ this->m_size += sizeof (timestamp_tag_t) + sizeof (tag_header_t);
+ this->m_tags.insert(this->m_tags.end(), tag);
+ key = "sec";
+ if( get_value(ini_section, key, &value )) {
+ tag->m_tag.sec = (BYTE)value;
+ }
+ else {
+ ERR("Missing key %s in tag %s\n", key.c_str(), name.c_str());
+ EXIT (-1);
+ }
+ key = "min";
+ if( get_value(ini_section, key, &value )) {
+ tag->m_tag.min = (BYTE)value;
+ }
+ else {
+ ERR("Missing key %s in tag %s\n", key.c_str(), name.c_str());
+ EXIT (-1);
+ }
+ key = "hour";
+ if( get_value(ini_section, key, &value )) {
+ tag->m_tag.hour = (BYTE)value;
+ }
+ else {
+ ERR("Missing key %s in tag %s\n", key.c_str(), name.c_str());
+ EXIT (-1);
+ }
+ key = "day";
+ if( get_value(ini_section, key, &value )) {
+ tag->m_tag.day = (BYTE)value;
+ }
+ else {
+ ERR("Missing key %s in tag %s\n", key.c_str(), name.c_str());
+ EXIT (-1);
+ }
+ key = "month";
+ if( get_value(ini_section, key, &value )) {
+ tag->m_tag.month = (BYTE)value;
+ }
+ else {
+ ERR("Missing key %s in tag %s\n", key.c_str(), name.c_str());
+ EXIT (-1);
+ }
+ key = "year";
+ if( get_value(ini_section, key, &value )) {
+ tag->m_tag.year = (u_int16_t)value;
+ }
+ else {
+ ERR("Missing key %s in tag %s\n", key.c_str(), name.c_str());
+ EXIT (-1);
+ }
+ } else {
+ ERR("Unknown tag name %s\n", name.c_str());
+ EXIT (-1);
+ }
+
+ this->header.section_size = (u_int16_t)this->m_size;
+ this->header.section_size -= sizeof (this->m_crc); //TBD remove - FW does not support CRC yet
+
+ if (this->m_size > this->m_max_size) {
+ ERR("Section %s with size %d exceeds maximum section size of %d\n",
+ this->m_name, this->m_size, this->m_max_size );
+ EXIT (-1);
+ }
+}
+
+template <class PRODUCT>
+void usb_info_section_t<PRODUCT>::init(flash_base *fl)
+{
+ //u_int32_t section_address = (*m_ptr_low | ((*m_ptr_high) << 16));
+ u_int32_t section_address = *this->m_ptr;
+ u_int32_t header_address = section_address - sizeof (section_header_t);
+
+ // get the section header
+ fl->read(header_address, sizeof (section_header_t), (BYTE*)&this->header);
+ this->m_size = this->header.section_size;
+
+ u_int16_t offset = sizeof (section_header_t);
+ while (offset < this->header.section_size) {
+ tag_header_t tag_header;
+ fl->read(header_address+offset, sizeof (tag_header_t), (BYTE*)&tag_header);
+ offset += sizeof (tag_header_t);
+
+ tag_base_t *tag = nullptr;
+ switch (tag_header.tag_id) {
+ case usb_format_version_tag_id: {
+ tag = new tag_t<format_version_tag_t> (tag_header.tag_id, "usb_format_version");
+ break;
+ }
+ case usb_version_tag_id : {
+ tag = new tag_t<version_tag_t> (tag_header.tag_id, "usb_version");
+ break;
+ }
+ case usb_timestamp_tag_id : {
+ tag = new tag_t<timestamp_tag_t> (tag_header.tag_id, "usb_timestamp");
+ break;
+ }
+ case end_tag_id : {
+ tag = new tag_t<end_tag_t> (tag_header.tag_id);
+ break;
+ }
+ default: {
+ ERR("Unknown tag id %d\n", tag_header.tag_id);
+ return;
+ }
+ }
+
+ fl->read(header_address+offset, tag_header.tag_size, (BYTE*)tag->get_tag());
+ offset += tag_header.tag_size;
+
+ this->m_tags.insert(this->m_tags.end(), tag);
+ }
+}
+
+template <class PRODUCT>
+usb_info_section_t<PRODUCT>::~usb_info_section_t ()
+{
+ // nothing to do
+}
+
+
+//
+// Const section
+//
+template <typename T, class PRODUCT>
+//const_section_t<T>::const_section_t (const char *name, BYTE id, u_int16_t *ptr_low, u_int16_t* ptr_high)
+//: id_section(name, id, ptr_low, ptr_high)
+const_section_t<T,PRODUCT>::const_section_t (const char *name, BYTE id, ADDRESS32 *ptr)
+ : id_section(name, id, ptr)
+{
+ memset(&this->m_section, 0, sizeof (T));
+ this->m_size += sizeof (T) + sizeof (this->m_crc);
+ this->header.section_size = (u_int16_t)this->m_size;
+}
+
+template <typename T, class PRODUCT>
+void const_section_t<T,PRODUCT>::write_to_buffer(BYTE *buffer )
+{
+ INFO("%s: Writing section of size 0x%04x at offset 0x%04x\n",this->m_name, this->m_size, m_offset);
+ int current_offset = m_offset;
+
+ memcpy(buffer + current_offset, &this->header, sizeof (this->header));
+ current_offset += sizeof (this->header);
+
+ memcpy(buffer + current_offset, &this->m_section, sizeof (T));
+ current_offset += sizeof (T);
+
+ this->m_crc = crc_16((u_int32_t*)(buffer+m_offset), this->m_size - sizeof (this->m_crc));
+ memcpy(buffer+current_offset, &this->m_crc, sizeof (this->m_crc));
+}
+
+template <typename T, class PRODUCT>
+void const_section_t<T,PRODUCT>::init(flash_base *fl)
+{
+ //u_int32_t section_address = (*m_ptr_low | ((*m_ptr_high) << 16));
+ u_int32_t section_address = *this->m_ptr;
+ fl->read(section_address, sizeof (this->m_section), (BYTE*)&this->m_section);
+}
+
+template <typename T, class PRODUCT>
+void const_section_t<T,PRODUCT>::initReduced(flash_base *fl, int reductionSize)
+{
+ //u_int32_t section_address = (*m_ptr_low | ((*m_ptr_high) << 16));
+ u_int32_t section_address = *this->m_ptr - reductionSize;
+ fl->read(section_address, sizeof (this->m_section), (BYTE*)&this->m_section);
+}
+
+
+//
+// IDs section
+//
+//ids_section_t::ids_section_t (const char *name, BYTE id, u_int16_t *ptr_low, u_int16_t* ptr_high)
+//: const_section_t(name, id, ptr_low, ptr_high)
+template <class PRODUCT>
+ids_section_t<PRODUCT>::ids_section_t (const char *name, BYTE id, ADDRESS32 *ptr)
+ : const_section_t<ids_section,PRODUCT>(name, id, ptr)
+{
+ //nothing to do
+}
+
+template <class PRODUCT>
+void ids_section_t<PRODUCT>::handle_ini_section (const ini_section_t &ini_section)
+{
+ u_int64_t value;
+
+ get_value(ini_section, "version", &value);
+ this->m_section.version = (BYTE)value;
+
+ get_value(ini_section, "mac_address" , &value);
+ memcpy(&this->m_section.mac_address, &value, sizeof (this->m_section.mac_address));
+
+ get_string(ini_section, "ssid" , &this->m_section.ssid, sizeof (this->m_section.ssid));
+
+ get_value(ini_section, "local", &value);
+ this->m_section.local = (u_int16_t)value;
+
+ get_value(ini_section, "ppm", &value);
+ this->m_section.ppm = (u_int16_t)value;
+
+ get_value(ini_section, "board", &value);
+ this->m_section.board_type = (u_int32_t)value;
+
+ get_value(ini_section, "lo_power_xif_gc", &value);
+ this->m_section.lo_power_xif_gc = (u_int16_t)value;
+
+ get_value(ini_section, "lo_power_stg2_bias", &value);
+ this->m_section.lo_power_stg2_bias = (u_int16_t)value;
+
+ get_value(ini_section, "vga_bias", &value);
+ this->m_section.vga_bias = (u_int16_t)value;
+
+ get_value(ini_section, "vga_stg1_fine_bias", &value);
+ this->m_section.vga_stg1_fine_bias = (u_int16_t)value;
+
+ get_value(ini_section, "ats_ver", &value);
+ this->m_section.ats_ver = (u_int16_t)value;
+
+ get_value(ini_section, "mlt_ver", &value);
+ this->m_section.mlt_ver = (u_int16_t)value;
+
+ get_value(ini_section, "bl_ver", &value);
+ this->m_section.bl_ver = (u_int16_t)value;
+
+ get_value(ini_section, "lo_power_gc_ctrl", &value);
+ this->m_section.lo_power_gc_ctrl = (u_int16_t)value;
+
+ get_value(ini_section, "production1", &value);
+ this->m_section.production1 = (u_int16_t)value;
+
+ get_value(ini_section, "production2", &value);
+ this->m_section.production2 = (u_int16_t)value;
+
+ get_value(ini_section, "production3", &value);
+ this->m_section.production3 = (u_int16_t)value;
+
+ get_value(ini_section, "production4", &value);
+ this->m_section.production4 = (u_int16_t)value;
+
+ get_value(ini_section, "production5", &value);
+ this->m_section.production5 = (u_int16_t)value;
+
+ get_value(ini_section, "production6", &value);
+ this->m_section.production6 = (u_int16_t)value;
+
+ get_value(ini_section, "production7", &value);
+ this->m_section.production7 = (u_int16_t)value;
+
+ get_value(ini_section, "production8", &value);
+ this->m_section.production8 = (u_int16_t)value;
+
+ get_value(ini_section, "production9", &value);
+ this->m_section.production9 = (u_int16_t)value;
+
+ get_value(ini_section, "production10", &value);
+ this->m_section.production10 = (u_int16_t)value;
+
+ get_value(ini_section, "production11", &value);
+ this->m_section.production11 = (u_int16_t)value;
+
+ get_value(ini_section, "production12", &value);
+ this->m_section.production12 = (u_int16_t)value;
+
+ get_value(ini_section, "production13", &value);
+ this->m_section.production13 = (u_int16_t)value;
+
+ get_value(ini_section, "production14", &value);
+ this->m_section.production14 = (u_int16_t)value;
+
+ get_value(ini_section, "production15", &value);
+ this->m_section.production15 = (u_int16_t)value;
+
+ get_value(ini_section, "production16", &value);
+ this->m_section.production16 = (u_int16_t)value;
+
+
+ if (this->m_size > this->m_max_size) {
+ ERR("Section %s with size %d exceeds maximum section size of %d\n",
+ this->m_name, this->m_size, this->m_max_size );
+ EXIT (-1);
+ }
+}
+
+template <class PRODUCT>
+void ids_section_t<PRODUCT>::disp() const
+{
+ printf("version = %d\n",this->m_section.version);
+ printf("MAC address = 0x%02x%02x%02x%02x%02x%02x\n", this->m_section.mac_address[5],
+ this->m_section.mac_address[4],
+ this->m_section.mac_address[3],
+ this->m_section.mac_address[2],
+ this->m_section.mac_address[1],
+ this->m_section.mac_address[0]);
+ printf("SSID = ");
+ print_buffer(&this->m_section.ssid, sizeof (this->m_section.ssid));
+ printf("\n");
+ printf("local = %d\n",this->m_section.local);
+ printf("ppm = %d\n",this->m_section.ppm);
+ printf("board = %d\n",this->m_section.board_type);
+ printf("lo_power_xif_gc = %d\n",this->m_section.lo_power_xif_gc);
+ printf("lo_power_stg2_bias = %d\n",this->m_section.lo_power_stg2_bias);
+ printf("vga_bias = %d\n",this->m_section.vga_bias);
+ printf("vga_stg1_fine_bias = %d\n",this->m_section.vga_stg1_fine_bias);
+ printf("ats_ver = %d\n",this->m_section.ats_ver);
+ printf("mlt_ver = %d\n",this->m_section.mlt_ver);
+ printf("bl_ver = %d\n",this->m_section.bl_ver);
+ printf("lo_power_gc_ctrl = %d\n",this->m_section.lo_power_gc_ctrl);
+ printf("production1 = %d\n",this->m_section.production1);
+ printf("production2 = %d\n",this->m_section.production2);
+ printf("production3 = %d\n",this->m_section.production3);
+ printf("production4 = %d\n",this->m_section.production4);
+ printf("production5 = %d\n",this->m_section.production5);
+ printf("production6 = %d\n",this->m_section.production6);
+ printf("production7 = %d\n",this->m_section.production7);
+ printf("production8 = %d\n",this->m_section.production8);
+ printf("production9 = %d\n",this->m_section.production9);
+ printf("production10 = %d\n",this->m_section.production10);
+ printf("production11 = %d\n",this->m_section.production11);
+ printf("production12 = %d\n",this->m_section.production12);
+ printf("production13 = %d\n",this->m_section.production13);
+ printf("production14 = %d\n",this->m_section.production14);
+ printf("production15 = %d\n",this->m_section.production15);
+ printf("production16 = %d\n",this->m_section.production16);
+}
+
+template <class PRODUCT>
+void ids_section_t<PRODUCT>::disp_to_file(const char* ids_ini_file) const
+{
+ std::ofstream fs(ids_ini_file);
+
+ if(!fs)
+ {
+ printf("Cannot open the output file\n");
+ return;
+ }
+
+
+ fs << "[IDS]" << endl;
+ fs << "version = " << (int)(this->m_section.version) << endl;
+
+ // Mac address
+ fs << "mac_address = 0x" ;
+ fs << hex << std::setw(2) << std::setfill('0') << (int)(this->m_section.mac_address[5]);
+ fs << hex << std::setw(2) << std::setfill('0') << (int)(this->m_section.mac_address[4]);
+ fs << hex << std::setw(2) << std::setfill('0') << (int)(this->m_section.mac_address[3]);
+ fs << hex << std::setw(2) << std::setfill('0') << (int)(this->m_section.mac_address[2]);
+ fs << hex << std::setw(2) << std::setfill('0') << (int)(this->m_section.mac_address[1]);
+ fs << hex << std::setw(2) << std::setfill('0') << (int)(this->m_section.mac_address[0]);
+ fs << endl;
+
+
+ fs << std::setbase(10);
+ fs << "local = " << (int)(this->m_section.local) << endl;
+ fs << "ssid = " << this->m_section.ssid << endl;
+ fs << "ppm = " << this->m_section.ppm << endl;
+ fs << "board = " << this->m_section.board_type << endl;
+ fs << "lo_power_xif_gc = " << this->m_section.lo_power_xif_gc << endl;
+ fs << "lo_power_stg2_bias = " << this->m_section.lo_power_stg2_bias << endl;
+ fs << "vga_bias = " << this->m_section.vga_bias << endl;
+ fs << "vga_stg1_fine_bias = " << this->m_section.vga_stg1_fine_bias << endl;
+ fs << "ats_ver = " << this->m_section.ats_ver << endl;
+ fs << "mlt_ver = " << this->m_section.mlt_ver << endl;
+ fs << "bl_ver = " << this->m_section.bl_ver << endl;
+ fs << "lo_power_gc_ctrl = " << this->m_section.lo_power_gc_ctrl << endl;
+ fs << "production1 = " << this->m_section.production1 << endl;
+ fs << "production2 = " << this->m_section.production2 << endl;
+ fs << "production3 = " << this->m_section.production3 << endl;
+ fs << "production4 = " << this->m_section.production4 << endl;
+ fs << "production5 = " << this->m_section.production5 << endl;
+ fs << "production6 = " << this->m_section.production6 << endl;
+ fs << "production7 = " << this->m_section.production7 << endl;
+ fs << "production8 = " << this->m_section.production8 << endl;
+ fs << "production9 = " << this->m_section.production9 << endl;
+ fs << "production10 = " << this->m_section.production10 << endl;
+ fs << "production11 = " << this->m_section.production11 << endl;
+ fs << "production12 = " << this->m_section.production12 << endl;
+ fs << "production13 = " << this->m_section.production13 << endl;
+ fs << "production14 = " << this->m_section.production14 << endl;
+ fs << "production15 = " << this->m_section.production15 << endl;
+ fs << "production16 = " << this->m_section.production16 << endl;
+ fs << std::setbase(16);
+ fs.close();
+}
+
+//usb_section_t::usb_section_t (const char *name, u_int16_t *ptr_low, u_int16_t* ptr_high)
+usb_section_t::usb_section_t (const char *name, ADDRESS32 *ptr)
+ :flash_section(name)
+{
+ //m_ptr_low = ptr_low;
+ //m_ptr_high = ptr_high;
+ this->m_ptr = ptr;
+ this->m_size = 0;
+ m_buffer = 0;
+}
+
+void usb_section_t::write_to_buffer(BYTE *buffer )
+{
+ INFO("%s: Writing section of size 0x%04x at offset 0x%04x\n",this->m_name, this->m_size, m_offset);
+
+ memcpy(buffer + m_offset, m_buffer, this->m_size);
+}
+
+void usb_section_t::handle_ini_section (const ini_section_t &ini_section)
+{
+ this->m_size = ini_section.size() * sizeof (IMAGE);
+ m_buffer = new IMAGE [ini_section.size()];
+ memset((void*)m_buffer, -1, this->m_size);
+
+ ini_section_t::const_iterator sec_iter;
+ sec_iter = ini_section.begin();
+ int index = 0;
+ while (sec_iter != ini_section.end())
+ {
+ get_resolved_data(sec_iter, &m_buffer[index]);
+ index++;
+ sec_iter++;
+ }
+
+ if (this->m_size > this->m_max_size) {
+ ERR("Section %s with size %d exceeds maximum section size of %d\n",
+ this->m_name, this->m_size, this->m_max_size );
+ EXIT (-1);
+ }
+}
+
+void usb_section_t::set_offset (int offset)
+{
+ flash_section::set_offset(offset);
+ //*m_ptr_low = (u_int16_t)offset;
+ //*m_ptr_high = (u_int16_t)(offset>>16);
+ *this->m_ptr = offset;
+}
+
+usb_section_t::~usb_section_t()
+{
+ delete m_buffer;
+}
+
+//template class pointer_section_t<u_int16_t>;
+//template class pointer_section_t<u_int32_t>;
diff --git a/debug-tools/wiburn/flash_sections.h b/debug-tools/wiburn/flash_sections.h
new file mode 100644
index 0000000..9d7b543
--- /dev/null
+++ b/debug-tools/wiburn/flash_sections.h
@@ -0,0 +1,464 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _FLASH_SECTIONS_H_
+#define _FLASH_SECTIONS_H_
+
+#include "wiburn.h"
+#include "ini_parser_types.h"
+#include "flash.h"
+#include "CCRC32.h"
+
+enum tag_ids {
+ image_format_version_tag_id = 0x1,
+ fw_version_tag_id = 0x2,
+ fw_timestamp_tag_id = 0x3,
+ usb_format_version_tag_id = 0x1,
+ usb_version_tag_id = 0x2,
+ usb_timestamp_tag_id = 0x3,
+ configuration_id_tag_id = 0x4,
+ device_id_tag_id = 0x5,
+ hw_id_tag_id = 0x6,
+ end_tag_id = 0xff
+};
+
+#pragma pack(push, 1)
+template <class PRODUCT>
+struct pointers_t
+{
+ typename PRODUCT::REG signature;
+ ADDRESS32 hw_pointer;
+ ADDRESS32 fw1_pointer;
+ typename PRODUCT::REG fw1_length;
+ ADDRESS32 fw1_data_pointer;
+ typename PRODUCT::REG fw1_data_length;
+ ADDRESS32 fw2_pointer;
+ typename PRODUCT::REG fw2_length;
+ ADDRESS32 fw2_data_pointer;
+ typename PRODUCT::REG fw2_data_length;
+ ADDRESS32 production_pointer;
+ ADDRESS32 ids_pointer;
+ typename PRODUCT::REG pointer_section_version;
+ ADDRESS32 fw1_static_conf_pointer;
+ ADDRESS32 fw2_static_conf_pointer;
+ ADDRESS32 config_section_pointer;
+ ADDRESS32 image_info_pointer;
+ ADDRESS32 radio_tx_cnf_pointer;
+ ADDRESS32 radio_rx_cnf_pointer;
+ ADDRESS32 radio_tx_cnf2_pointer;
+ ADDRESS32 radio_rx_cnf2_pointer;
+ ADDRESS32 raw_data_pointer;
+ typename PRODUCT::REG raw_data_length;
+
+ // Unused
+ ADDRESS32 usb_pointer;
+ ADDRESS32 usb_info_pointer;
+ ADDRESS32 user_pointer;
+};
+#pragma pack(pop)
+
+#pragma pack(push, 1)
+template <class PRODUCT>
+struct address_value_t
+{
+ typename PRODUCT::ADDRESS address;
+ typename PRODUCT::REG value;
+};
+#pragma pack(pop)
+
+#pragma pack(push, 1)
+template <class PRODUCT>
+struct address_value_mask_t
+{
+ typename PRODUCT::ADDRESS address;
+ typename PRODUCT::REG value;
+ typename PRODUCT::REG mask;
+};
+#pragma pack(pop)
+
+
+#pragma pack(push, 1)
+struct tag_header_t
+{
+ BYTE reserved;
+ BYTE tag_id;
+ u_int16_t tag_size;
+ void disp(const char *name);
+};
+#pragma pack(pop)
+
+#pragma pack(push, 1)
+struct format_version_tag_t
+{
+ BYTE format_version;
+ BYTE reserved [3];
+ void disp(const char *name);
+};
+#pragma pack(pop)
+
+#pragma pack(push, 1)
+struct version_tag_t
+{
+ u_int32_t minor : 8;
+ u_int32_t major : 8;
+ u_int32_t build : 13;
+ u_int32_t sub_minor : 3;
+ void disp(const char *name);
+};
+#pragma pack(pop)
+
+#pragma pack(push, 1)
+struct timestamp_tag_t
+{
+ BYTE min;
+ BYTE hour;
+ BYTE reserved1;
+ BYTE sec;
+ BYTE month;
+ BYTE day;
+ u_int16_t year;
+ void disp(const char *name);
+};
+#pragma pack(pop)
+
+#pragma pack(push, 1)
+struct configuration_id_tag_t
+{
+ BYTE id [16];
+ void disp(const char *name);
+};
+#pragma pack(pop)
+
+#pragma pack(push, 1)
+struct device_id_tag_t
+{
+ u_int16_t device_id;
+ BYTE revision_id;
+ BYTE misc;
+ void disp(const char *name);
+};
+#pragma pack(pop)
+
+#pragma pack(push, 1)
+struct hw_id_tag_t
+{
+ BYTE digital_soc_id;
+ BYTE board_id;
+ BYTE antenna_id;
+ BYTE rf_id;
+ u_int16_t serial_id;
+ u_int16_t reserved;
+ void disp(const char *name);
+};
+#pragma pack(pop)
+
+#pragma pack(push, 1)
+struct end_tag_t
+{
+ u_int16_t reserved1;
+ u_int16_t reserved2;
+ void disp(const char *name);
+};
+#pragma pack(pop)
+
+class tag_base_t
+{
+public:
+ virtual char *get_tag() = 0;
+ tag_base_t (BYTE id, const char* name);
+ virtual ~tag_base_t() {};
+ virtual void disp() = 0;
+public:
+ tag_header_t m_header;
+ const char *m_name;
+};
+
+template <class Tag>
+class tag_t: public tag_base_t
+{
+public:
+ char *get_tag();
+ tag_t (BYTE id, const char* name = 0);
+ virtual ~tag_t() {};
+ void disp();
+public:
+ Tag m_tag;
+};
+
+
+#pragma pack(push, 1)
+struct section_header_t
+{
+ BYTE reserved;
+ BYTE section_id;
+ u_int16_t section_size;
+};
+#pragma pack(pop)
+
+class flash_section
+{
+public:
+ flash_section (const char *name);
+ virtual void write_to_buffer(BYTE *buffer ) = 0;
+ int size () const;
+ int get_max_size () const;
+ void set_max_size ( u_int32_t max_size );
+ void set_offset (u_int32_t offset);
+ u_int32_t get_offset () const;
+ virtual ~flash_section() {};
+protected:
+ u_int32_t m_size;
+ u_int32_t m_max_size;
+ u_int32_t m_offset;
+ const char *m_name;
+ u_int32_t m_crc;
+ CCRC32 m_CalcCRC;
+};
+
+class usb_section_t : public flash_section
+{
+public:
+ //usb_section_t (const char *name, u_int16_t *ptr_low, u_int16_t* ptr_high);
+ usb_section_t (const char *name, ADDRESS32 *ptr);
+ void write_to_buffer(BYTE *buffer ) ;
+ void handle_ini_section (const ini_section_t &ini_section);
+ void set_offset (int offset);
+ ~usb_section_t();
+public:
+ IMAGE *m_buffer;
+// u_int16_t *m_ptr_low;
+// u_int16_t *m_ptr_high;
+ ADDRESS32 *m_ptr;
+};
+
+class id_section : public flash_section
+{
+public:
+ //id_section (const char *name, BYTE id, u_int16_t *ptr_low, u_int16_t* ptr_high);
+ id_section (const char *name, BYTE id, ADDRESS32 *ptr);
+ void set_offset (int offset);
+
+public:
+ section_header_t header;
+// u_int16_t *m_ptr_low;
+// u_int16_t *m_ptr_high;
+ ADDRESS32 *m_ptr;
+};
+
+class variable_section_t : public id_section
+{
+public:
+// variable_section_t (const char *name, BYTE id, u_int16_t *ptr_low, u_int16_t *ptr_high);
+ variable_section_t (const char *name, BYTE id, ADDRESS32 *ptr);
+ ~variable_section_t ();
+protected:
+ int m_buffer_size;
+};
+
+template <class PRODUCT>
+class hw_section_t : public variable_section_t
+{
+public:
+// hw_section_t (const char *name, BYTE id, u_int16_t *ptr_low, u_int16_t *ptr_high);
+ hw_section_t (const char *name, BYTE id, ADDRESS32 *ptr);
+public:
+ void handle_ini_section (u_int8_t translation_map_bits, const ini_section_t &ini_section);
+ void init (flash_base *flash);
+ bool operator == (const hw_section_t &r_side) const;
+ void write_to_buffer(BYTE *buffer ) ;
+ ~hw_section_t ();
+ address_value_t <PRODUCT> *m_buffer;
+ u_int16_t *m_length;
+ u_int32_t m_termination [2];
+
+};
+
+template <class PRODUCT>
+class fw_section_t : public variable_section_t
+{
+public:
+ //fw_section_t (const char *name, BYTE id, u_int16_t *ptr_low, u_int16_t *ptr_high);
+ fw_section_t (const char *name, BYTE id, ADDRESS32 *ptr);
+public:
+ void handle_ini_section (u_int8_t translation_map_bits, const ini_section_t &ini_section);
+ void write_to_buffer(BYTE *buffer ) ;
+ ~fw_section_t ();
+ address_value_mask_t <PRODUCT> *m_buffer;
+};
+
+template <class PRODUCT>
+class image_section_t : public variable_section_t
+{
+public:
+ //image_section_t (const char *name, BYTE id, u_int16_t *ptr_low, u_int16_t *ptr_high, u_int16_t *length);
+ image_section_t (const char *name, BYTE id, ADDRESS32 *ptr, typename PRODUCT::REG *length);
+ void handle_ini_section (const ini_section_t &ini_section);
+ void write_to_buffer(BYTE *buffer ) ;
+ void set_offset (int offset);
+ ~image_section_t ();
+public:
+ IMAGE *m_buffer;
+ //u_int16_t *m_length;
+ typename PRODUCT::REG *m_length;
+};
+
+template <class PRODUCT>
+class pointer_section_t : public flash_section
+{
+public:
+ pointer_section_t (const char *name);
+ void init (flash_base *fl);
+ void write_to_buffer(BYTE *buffer ) ;
+ bool operator == (const pointer_section_t <PRODUCT> &r_side) const;
+public:
+ pointers_t <PRODUCT> m_pointers;
+};
+
+template <class PRODUCT>
+class info_section_t : public variable_section_t
+{
+public:
+ typedef vector <tag_base_t*> tag_vector_t;
+public:
+// info_section_t (const char *name, BYTE id, u_int16_t *ptr_low, u_int16_t *ptr_high);
+ info_section_t (const char *name, BYTE id, ADDRESS32 *ptr);
+ virtual void handle_ini_section (const ini_section_t &ini_section,
+ const string &name) = 0;
+ virtual void init (flash_base *flash) = 0;
+ void write_to_buffer(BYTE *buffer ) ;
+ ~info_section_t ();
+ void disp() const;
+
+public:
+ tag_vector_t m_tags;
+ u_int16_t *m_length;
+};
+
+template <class PRODUCT>
+class image_info_section_t : public info_section_t<PRODUCT>
+{
+public:
+ //image_info_section_t (const char *name, BYTE id, u_int16_t *ptr_low, u_int16_t *ptr_high);
+ image_info_section_t (const char *name, BYTE id, ADDRESS32 *ptr);
+ void handle_ini_section (const ini_section_t &ini_section,
+ const string &name);
+ void init (flash_base *fl);
+ ~image_info_section_t ();
+};
+
+template <class PRODUCT>
+class usb_info_section_t : public info_section_t<PRODUCT>
+{
+public:
+// usb_info_section_t (const char *name, BYTE id, u_int16_t *ptr_low, u_int16_t *ptr_high);
+ usb_info_section_t (const char *name, BYTE id, ADDRESS32 *ptr);
+ void handle_ini_section (const ini_section_t &ini_section,
+ const string &name);
+ void init (flash_base *fl);
+ ~usb_info_section_t ();
+};
+
+template <class PRODUCT>
+class system_config_section_t : public flash_section
+{
+public:
+ system_config_section_t (const char *name, ADDRESS32 *ptr);
+ void set_offset (int offset);
+ void write_to_buffer(BYTE *buffer ) ;
+
+public:
+ ADDRESS32 *m_ptr;
+};
+
+
+#pragma pack(push, 1)
+struct ids_section
+{
+ BYTE reserved1;
+ BYTE version;
+ BYTE mac_address [6];
+ BYTE ssid [32];
+ u_int16_t local;
+ u_int16_t reserved2;
+ u_int16_t ppm;
+ u_int16_t reserved3;
+ u_int32_t board_type;
+ u_int16_t lo_power_xif_gc;
+ u_int16_t lo_power_stg2_bias;
+ u_int16_t vga_bias;
+ u_int16_t vga_stg1_fine_bias;
+ u_int16_t ats_ver;
+ u_int16_t mlt_ver;
+ u_int16_t bl_ver;
+ u_int16_t lo_power_gc_ctrl;
+ u_int16_t production1;
+ u_int16_t production2;
+ u_int16_t production3;
+ u_int16_t production4;
+ u_int16_t production5;
+ u_int16_t production6;
+ u_int16_t production7;
+ u_int16_t production8;
+ u_int16_t production9;
+ u_int16_t production10;
+ u_int16_t production11;
+ u_int16_t production12;
+ u_int16_t production13;
+ u_int16_t production14;
+ u_int16_t production15;
+ u_int16_t production16;
+};
+#pragma pack(pop)
+
+template <typename T, class PRODUCT>
+ struct const_section_t: public id_section
+{
+public:
+// const_section_t (const char *name, BYTE id, u_int16_t *ptr_low, u_int16_t* ptr_high);
+ const_section_t (const char *name, BYTE id, ADDRESS32 *ptr);
+ virtual void handle_ini_section (const ini_section_t &ini_section) = 0;
+ void write_to_buffer(BYTE *buffer ) ;
+ virtual void init (flash_base *fl);
+ virtual void initReduced (flash_base *fl, int reductionSize);
+public:
+ T m_section;
+};
+
+
+template <class PRODUCT>
+struct ids_section_t: public const_section_t <ids_section, PRODUCT>
+{
+public:
+// ids_section_t (const char *name, BYTE id, u_int16_t *ptr_low, u_int16_t* ptr_high);
+ ids_section_t (const char *name, BYTE id, ADDRESS32 *ptr);
+ void handle_ini_section (const ini_section_t &ini_section);
+ void disp() const;
+ void disp_to_file(const char* ids_ini_file) const;
+};
+#endif //#ifndef _FLASH_SECTIONS_H_
diff --git a/debug-tools/wiburn/ini_parser.cpp b/debug-tools/wiburn/ini_parser.cpp
new file mode 100644
index 0000000..4783f60
--- /dev/null
+++ b/debug-tools/wiburn/ini_parser.cpp
@@ -0,0 +1,483 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "ini_parser.h"
+#include <algorithm>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+
+template <class PRODUCT>
+void ini_parser<PRODUCT>::update_section(u_int8_t translation_map_bits, ini_section_t *orig, const ini_section_t &update, bool is_string)
+{
+ if (*orig == update) {
+ return;
+ }
+
+ ini_section_t::const_iterator update_iter = update.begin();
+ ini_section_t::iterator orig_iter;
+ while (update_iter != update.end() ) {
+ orig_iter = find(translation_map_bits, update_iter, *orig, is_string);
+ if (orig_iter == orig->end() ) {
+ if (g_debug) DBG("Appending key %s value %s\n", update_iter->first.c_str(), update_iter->second.c_str());
+ orig->insert(orig->end(), *update_iter); // append entry from the update section
+ } else {
+ if (g_debug) DBG("Replacing Key %s value %s with key %s value %s\n"
+ , orig_iter->first.c_str()
+ , orig_iter->second.c_str()
+ , update_iter->first.c_str()
+ , update_iter->second.c_str());
+ *orig_iter = *update_iter; // replace the original entry with the entry from the update section
+ }
+ update_iter++;
+ }
+}
+
+template <class PRODUCT>
+ini_section_t::iterator ini_parser<PRODUCT>::find(
+ u_int8_t translation_map_bits,
+ ini_section_t::const_iterator &lside,
+ ini_section_t &ini_section,
+ bool is_string) const
+{
+ //u_int8_t translation_map_bits = 1;
+ typename PRODUCT::ADDRESS laddress,raddress;
+ typename PRODUCT::REG lvalue, rvalue;
+ int lstart, lend, rstart, rend;
+ if (!is_string) {
+ get_resolved_address_data(translation_map_bits, lside, &laddress, &lvalue, &lstart, &lend);
+ }
+
+ ini_section_t::iterator rside = ini_section.begin();
+ while (rside != ini_section.end() ) {
+ if (is_string) {
+ if (lside->first == rside->first) {
+ break;
+ }
+ } else {
+ get_resolved_address_data(translation_map_bits, rside, &raddress, &rvalue, &rstart, &rend);
+ if (laddress == raddress && lstart == rstart && lend == rend ) {
+ break;
+ }
+ }
+ rside++;
+ }
+ return rside;
+}
+
+//bool ini_parser::get_value (const ini_section_t &ini_section,
+//const string &key,
+//u_int64_t *value,
+//bool must_be) const
+bool get_value (const ini_section_t &ini_section,
+ const string &key,
+ u_int64_t *value,
+ bool must_be)
+{
+ ini_section_t::const_iterator iter = ini_section.begin();
+ while( ini_section.end() != iter ) {
+ if( iter->first == key ) {
+ char *end_ptr;
+ *value = STRTOULL(iter->second.c_str(), &end_ptr, 0);
+ if(*end_ptr != 0) {
+ ERR("Key %s: Failed converting value %s\n", key.c_str(), iter->second.c_str());
+ EXIT (-1);
+ }
+ return true;
+ }
+ iter++;
+ }
+
+ if(must_be) {
+ ERR("Could not find key %s\n", key.c_str());
+ EXIT (-1);
+ }
+
+ return false;
+}
+
+
+//bool ini_parser::get_string(const ini_section_t &ini_section,
+//const string &key,
+//void *str,
+//u_int32_t max_length,
+//bool must_be) const
+bool get_string(const ini_section_t &ini_section,
+ const string &key,
+ void *str,
+ u_int32_t max_length,
+ bool must_be)
+{
+ ini_section_t::const_iterator iter = ini_section.begin();
+ while( ini_section.end() != iter ) {
+ if( iter->first == key ) {
+ if (iter->second.size() > max_length ) {
+ ERR("Key %s: length %lu exceeded maximal length of %u\n", key.c_str(), (unsigned long)iter->second.size(), max_length);
+ EXIT (-1);
+ }
+
+ iter->second.copy((char*)str, max_length);
+
+ return true;
+ }
+ iter++;
+ }
+
+ if(must_be) {
+ ERR("Could not find key %s\n", key.c_str());
+ EXIT (-1);
+ }
+
+ return false;
+}
+
+template <class PRODUCT>
+void ini_parser<PRODUCT>::get_resolved_address_data (
+ u_int8_t translation_map_bits,
+ ini_section_t::const_iterator sec_iter,
+ typename PRODUCT::ADDRESS *address,
+ typename PRODUCT::REG *value,
+ bool word_addresses)
+{
+ int start, end;
+ get_resolved_address_data(translation_map_bits, sec_iter, address, value, &start, &end, word_addresses);
+}
+
+template <class PRODUCT>
+void ini_parser<PRODUCT>::get_resolved_address_data (
+ u_int8_t translation_map_bits,
+ ini_section_t::const_iterator sec_iter,
+ typename PRODUCT::ADDRESS *address,
+ typename PRODUCT::REG *value,
+ int *start,
+ int *end,
+ bool word_addresses
+ )
+{
+ char *end_ptr;
+ if(g_debug) DBG( "Dumping address %s value %s\n", sec_iter->first.c_str(),sec_iter->second.c_str());
+ *address = ( typename PRODUCT::ADDRESS)strtoul(sec_iter->first.c_str(), &end_ptr, 0);
+ if (0 != *end_ptr) // it was a pathname
+ {
+ if(g_debug) DBG("Converting %s to ", sec_iter->first.c_str());
+ u_int32_t temp_address;
+ bool found = false;
+ if (!found && (translation_map_bits & TRANSLATION_MAP_REGTREE))
+ {
+ found = g_reg_tree_t_map.get_from_translation_map(sec_iter->first.c_str(), &temp_address, start, end);
+ }
+ if (!found && (translation_map_bits & TRANSLATION_MAP_FW))
+ {
+ found = g_fw_t_map.get_from_translation_map(sec_iter->first.c_str(), &temp_address, start, end);
+ }
+ if (!found && (translation_map_bits & TRANSLATION_MAP_UCODE))
+ {
+ found = g_ucode_t_map.get_from_translation_map(sec_iter->first.c_str(), &temp_address, start, end);
+ }
+
+// bool found = ::g_t_map.get_from_translation_map(sec_iter->first.c_str(), &temp_address, start, end);
+ *address = ( typename PRODUCT::ADDRESS)temp_address;
+ if (!found) {
+ ERR("Could not find %s in translation map. Make sure that it is in the REG_TREE section in your INI file\n",
+ sec_iter->first.c_str());
+ EXIT (-1);
+ }
+ if (word_addresses) {
+ if (*address & 0x1) {
+ ERR("%s was converted to 0x%04x, which is not dword aligned\n",
+ sec_iter->first.c_str(),
+ *address );
+ EXIT (-1);
+ }
+
+ *address = *address / 2;
+ }
+ }
+ else
+ {
+ *start = 0;
+ *end = sizeof ( typename PRODUCT::REG) * 8 - 1;
+ }
+
+ *value = ( typename PRODUCT::REG)strtoul(sec_iter->second.c_str(), &end_ptr, 0);
+
+ if(g_debug) DBG( "Address %0#4x value %0#4x start %d end %d\n", *address, *value, *start, *end);
+}
+
+//void ini_parser::get_resolved_data (ini_section_t::const_iterator sec_iter,
+// IMAGE *value) const
+void get_resolved_data (ini_section_t::const_iterator sec_iter,
+ IMAGE *value)
+{
+ char *end_ptr;
+ *value = strtoul(sec_iter->second.c_str(), &end_ptr, 0);
+ if(g_debug) DBG( "Image %0#4x\n", *value);
+}
+
+template <class PRODUCT>
+ini_parser<PRODUCT>::ini_parser ()
+{
+ this ->hadProductionSeciton = false;
+ //nothing to do
+}
+
+template <class PRODUCT>
+bool ini_parser<PRODUCT>::init (const char *filename, u_int32_t option)
+{
+ FILE *stream;
+ printf("%s\n", filename);
+ stream = fopen( filename, "r" );
+ if( stream == NULL )
+ {
+// char cwd[1024];
+// if (getcwd(cwd, sizeof(cwd)) != NULL)
+// fprintf(stdout, "Current working dir: %s\n", cwd);
+ printf("%s\n", strerror(errno));
+ ERR( "Failed opening file %s \n", filename );
+ EXIT (-1);
+ }
+ else
+ {
+ int reg_tree_section_index = 0;
+ bool skip_section = false;
+ char buffer [1100];
+ char a1 [1000];
+ char a2 [256];
+ char a3 [256];
+ char a4 [256];
+
+ int ch;
+ int num;
+ u_int8_t translation_map_bits = TRANSLATION_MAP_NONE;
+
+ do
+ {
+ ch = get_clean_line (stream, buffer, sizeof buffer);
+
+ num = sscanf(buffer, "%999s %256s %256s %256s", a1, a2, a3, a4);
+ switch (num)
+ {
+ case 1:
+ {
+ INFO( "Section [%s]\n", a1 );
+ string section = a1;
+
+ if (section == "production")
+ {
+ if (hadProductionSeciton == true)
+ {
+ ERR( "Only one PRODUCTION Section is allowed in one burn command ! \n");
+ EXIT (-1);
+ }
+ hadProductionSeciton = true;
+ }
+
+ if (option == 1)
+ {
+ if (section == "radio_tx_conf")
+ {
+ section += "2";
+ }
+ if (section == "radio_rx_conf")
+ {
+ section += "2";
+ }
+ }
+
+ skip_section = false;
+
+ if (section == "fw_symbols")
+ {
+ translation_map_bits = TRANSLATION_MAP_FW;
+ }
+ else if (section == "ucode_symbols")
+ {
+ translation_map_bits = TRANSLATION_MAP_UCODE;
+ }
+ else if (section == "reg_tree")
+ {
+ translation_map_bits = TRANSLATION_MAP_REGTREE;
+ // if [REG_TREE] section appear more then once then do not process
+ // its key, values
+ reg_tree_section_index++;
+ if (reg_tree_section_index > 1)
+ {
+ skip_section = true;
+ }
+ }
+ if (section != "reg_tree")
+ {
+ if(g_debug) DBG("Adding ini section\n");
+ ini_section_t *sec = new ini_section_t;
+ pair <string, ini_section_t*> p (section, sec);
+ current_ini_section = ini_file.insert(p);
+ }
+ break;
+ }
+ case 2:
+ {
+ if(g_debug) DBG( "Address %s Value %s\n", a1, a2 );
+ key_value_t entry (a1, a2);
+ pair <ini_section_t::iterator, bool> ret;
+ ini_section_t *sec = this->current_ini_section->second;
+ sec->push_back(entry);
+ break;
+ }
+ case 3:
+ {
+ if(g_debug) DBG( "Address %s[%s] Value %s\n", a1, a3, a2 );
+ string temp = a1;
+ temp += '#';
+ temp.append(a3);
+ key_value_t entry (temp, a2);
+ pair <ini_section_t::iterator, bool> ret;
+ ini_section_t *sec = this->current_ini_section->second;
+ sec->push_back(entry);
+ break;
+ }
+
+ case 4:
+ {
+ if (!skip_section)
+ {
+ bool bInsert = false;
+
+ if(g_debug) DBG ("path %s address %s start %s end %s\n", a1, a2, a3, a4);
+
+ if (translation_map_bits == TRANSLATION_MAP_REGTREE)
+ {
+ bInsert = g_reg_tree_t_map.add_to_translation_map(a1, a2, a3, a4);
+ }
+ else if (translation_map_bits == TRANSLATION_MAP_FW)
+ {
+ bInsert = g_fw_t_map.add_to_translation_map(a1, a2, a3, a4);
+ }
+ else if (translation_map_bits == TRANSLATION_MAP_UCODE)
+ {
+ bInsert = g_ucode_t_map.add_to_translation_map(a1, a2, a3, a4);
+ }
+
+ // if( !g_t_map.add_to_translation_map(a1, a2, a3, a4) )
+ if (!bInsert)
+ {
+ ERR("Failed adding to translation map: path %s address %s start %s end %s\n", a1, a2, a3, a4);
+ EXIT (-1);
+ };
+ }
+ break;
+ }
+ default : if(g_debug) DBG( "empty line or comment line\n" );break;
+ }
+ } while (EOF != ch);
+
+ fclose(stream);
+ }
+ return true;
+}
+
+template <class PRODUCT>
+int ini_parser<PRODUCT>::get_clean_line (FILE *stream, char *buffer, const int buffer_size) const
+{
+ int i;
+ int ch=0;
+ bool alpha_detected = false;
+ bool section_detected = false;
+
+ for (i = 0; i < buffer_size; i++)
+ {
+ ch = getc(stream);
+ if( ch >= 'A' && ch <= 'Z' )
+ {
+ ch = ch - 'A' + 'a'; // change to lower case
+ }
+
+ alpha_detected = alpha_detected | (ch >= 'a' && ch <= 'z') ;
+
+ if (EOF == ch || '\n' == ch)
+ {
+ buffer[i] = '\0';
+ break;
+ }
+ else if ('[' == ch && !alpha_detected)
+ {
+ section_detected = true;
+ buffer[i] = ' ';
+ }
+ else if (']' == ch && section_detected)
+ {
+ buffer[i] = ' ';
+ }
+ else if ( '=' == ch)
+ {
+ buffer[i] = ' ';
+ }
+ else if ('#' == ch || ';' == ch)
+ {
+ buffer[i] = '\0';
+ } else
+ {
+ buffer[i] = (char)ch;
+ }
+ }
+ return ch;
+}
+template <class PRODUCT>
+bool ini_parser<PRODUCT>::get_section(const string §ion_name, u_int8_t translation_map_bits, ini_file_t::iterator *iter1, bool is_string, bool must_be)
+{
+ //unused param
+ (void)must_be;
+
+ ini_file_t::iterator iter = ini_file.begin();
+ *iter1 = ini_file.end();
+ while (iter != ini_file.end() ) {
+ if (iter->first == section_name ) {
+ if (*iter1 == ini_file.end()){
+ *iter1 = iter;
+ }else{
+ this->update_section(translation_map_bits, (*iter1)->second, *(iter->second), is_string);
+ }
+ }
+ iter++;
+ }
+
+ //
+ // adding this lines cause the application stop running if the section must_be and did not find
+ // in other words, this function always return true
+ // if you decide to remove these lines, you should handle the return code in the caller function
+ //
+ /*if (must_be && *iter1 == ini_file.end()) {
+ ERR("Could not find mandatory section %s\n", section_name.c_str() );
+ EXIT (-1);
+ }*/
+
+ return (*iter1 != ini_file.end() );
+}
+
diff --git a/debug-tools/wiburn/ini_parser.h b/debug-tools/wiburn/ini_parser.h
new file mode 100644
index 0000000..01e625c
--- /dev/null
+++ b/debug-tools/wiburn/ini_parser.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _INI_PARSER_H_
+#define _INI_PARSER_H_
+
+#include "wiburn.h"
+#include "ini_parser_types.h"
+//#include "flash_sections.h"
+#include "translation_map.h"
+
+extern translation_map g_reg_tree_t_map;
+extern translation_map g_ucode_t_map;
+extern translation_map g_fw_t_map;
+
+typedef enum _TRANSLATION_MAP_BITS
+{
+ TRANSLATION_MAP_NONE = 0,
+ TRANSLATION_MAP_REGTREE = 1,
+ TRANSLATION_MAP_FW = 2,
+ TRANSLATION_MAP_UCODE = 4,
+
+} TRANSLATION_MAP_BITS;
+
+bool get_value(const ini_section_t &ini_section,
+ const string &key,
+ u_int64_t *value,
+ bool must_be = true);
+
+bool get_string(const ini_section_t &ini_section,
+ const string &key,
+ void *string,
+ u_int32_t max_length,
+ bool must_be = true);
+
+
+
+void get_resolved_data (ini_section_t::const_iterator sec_iter,
+ IMAGE *value);
+
+
+class ini_parser_base
+{
+public:
+ ini_parser_base () {};
+ virtual ~ini_parser_base () {};
+ virtual bool init (const char *filename, u_int32_t option = 0) = 0;
+ virtual bool get_section(const string §ion_name, u_int8_t translation_map_bits, ini_file_t::iterator *iter1, bool is_string, bool must_be) = 0;
+ virtual void update_section(u_int8_t translation_map_bits, ini_section_t *orig, const ini_section_t &update, bool is_string) = 0;
+};
+
+template <class PRODUCT>
+class ini_parser: public ini_parser_base
+{
+private:
+ ini_file_t ini_file;
+ ini_file_t::iterator current_ini_section;
+
+public:
+ ini_parser ();
+ bool init (const char *filename, u_int32_t option = 0);
+ bool get_section(const string §ion_name, u_int8_t translation_map_bits, ini_file_t::iterator *iter1, bool is_string, bool must_be);
+
+ //bool get_value(const ini_section_t &ini_section,
+ // const string &key,
+ // u_int64_t *value,
+ // bool must_be = true) const;
+ //bool get_string(const ini_section_t &ini_section,
+ // const string &key,
+ // void *string,
+ // u_int32_t max_length,
+ // bool must_be = true) const;
+
+ static void get_resolved_address_data (
+ u_int8_t translation_map_bits,
+ ini_section_t::const_iterator sec_iter,
+ typename PRODUCT::ADDRESS *address,
+ typename PRODUCT::REG *value,
+ bool word_addresses = false);
+
+ static void get_resolved_address_data (
+ u_int8_t translation_map_bits,
+ ini_section_t::const_iterator sec_iter,
+ typename PRODUCT::ADDRESS *address,
+ typename PRODUCT::REG *value,
+ int *start,
+ int *end,
+ bool word_addresses = false);
+
+ //void get_resolved_data (ini_section_t::const_iterator sec_iter,
+ // IMAGE *value) const;
+
+ void update_section(u_int8_t translation_map_bits, ini_section_t *orig, const ini_section_t &update, bool is_string);
+private:
+ ini_section_t::iterator find(
+ u_int8_t translation_map_bits,
+ ini_section_t::const_iterator &lside,
+ ini_section_t &ini_section,
+ bool is_string) const;
+ int get_clean_line (FILE *stream, char *buffer, const int buffer_size) const;
+
+ bool hadProductionSeciton;
+
+};
+
+
+#endif// #ifndef _INI_PARSER_H_
diff --git a/debug-tools/wiburn/ini_parser_types.h b/debug-tools/wiburn/ini_parser_types.h
new file mode 100644
index 0000000..96fd562
--- /dev/null
+++ b/debug-tools/wiburn/ini_parser_types.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _INI_PARSER_TYPES_H_
+#define _INI_PARSER_TYPES_H_
+
+#include <string>
+#include <map>
+#include <vector>
+
+using namespace std;
+
+typedef pair <string,string> key_value_t;
+typedef vector <key_value_t> ini_section_t;
+typedef multimap <string, ini_section_t*> ini_file_t;
+
+enum section_id_t {
+ production_section_id = 0,
+ ids_section_id = 1,
+ hw_conf_section_id = 2,
+ fw1_code_section_id = 3,
+ fw1_data_section_id = 4,
+ fw2_code_section_id = 5,
+ fw2_data_section_id = 6,
+ fw1_static_conf_section_id = 7,
+ fw2_static_conf_section_id = 8,
+ config_section_id = 9,
+ image_info_section_id = 10,
+ radio_tx_conf_section_id = 11,
+ radio_rx_conf_section_id = 12,
+ radio_tx_conf2_section_id = 13,
+ radio_rx_conf2_section_id = 14,
+ raw_data_section_id = 15,
+
+ // The Following is unused !
+ usb_info_section_id = 16,
+ user_conf_section_id = 17,
+ usb_section_id = 18,
+};
+
+#endif //#ifndef _INI_PARSER_TYPES_H_
diff --git a/debug-tools/wiburn/product.h b/debug-tools/wiburn/product.h
new file mode 100644
index 0000000..e163c2f
--- /dev/null
+++ b/debug-tools/wiburn/product.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _PRODUCT_H_
+#define _PRODUCT_H_
+
+#include "wiburn.h"
+
+#define MARLON_ID 612072
+#define SPARROW_ID 632072
+#define TALYN_ID 642072
+
+class IProduct
+{
+public:
+ IProduct(){}
+ virtual ~IProduct(void){}
+ virtual int Section2ID() = 0;
+};
+
+class talyn : public IProduct
+{
+public:
+ typedef u_int32_t REG;
+ typedef u_int32_t ADDRESS;
+ static const u_int64_t id = TALYN_ID;
+
+ virtual int Section2ID() {return 0;}
+};
+
+class sparrow : public IProduct
+{
+public:
+ typedef u_int32_t REG;
+ typedef u_int32_t ADDRESS;
+ static const u_int64_t id = SPARROW_ID;
+
+ virtual int Section2ID() {return 0;}
+};
+
+class marlon : public IProduct
+{
+public:
+ typedef u_int32_t REG;
+ typedef u_int32_t ADDRESS;
+ static const u_int64_t id = MARLON_ID;
+
+ virtual int Section2ID() {return 0;}
+};
+
+#endif //#ifndef _PRODUCT_H_
diff --git a/debug-tools/wiburn/template_inst.cpp b/debug-tools/wiburn/template_inst.cpp
new file mode 100644
index 0000000..c1cdf42
--- /dev/null
+++ b/debug-tools/wiburn/template_inst.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _TEMPLATE_INST_
+#define _TEMPLATE_INST_
+
+#include "product.h"
+
+#include "flash_sections.cpp"
+template class pointer_section_t<talyn>;
+template class pointer_section_t<sparrow>;
+template class pointer_section_t<marlon>;
+
+template class hw_section_t<talyn>;
+template class hw_section_t<sparrow>;
+template class hw_section_t<marlon>;
+
+template struct ids_section_t<talyn>;
+template struct ids_section_t<sparrow>;
+template struct ids_section_t<marlon>;
+
+template class info_section_t<talyn>;
+template class info_section_t<sparrow>;
+template class info_section_t<marlon>;
+
+
+#include "flash_image.cpp"
+template class flash_image<talyn>;
+template class flash_image<sparrow>;
+template class flash_image<marlon>;
+
+#include "ini_parser.cpp"
+template class ini_parser<talyn>;
+template class ini_parser<sparrow>;
+template class ini_parser<marlon>;
+
+//#include "flash.cpp"
+// template class flash<sparrow>;
+// template class flash<marlon>;
+// template class flash_file<sparrow>;
+// template class flash_file<marlon>;
+
+#endif
diff --git a/debug-tools/wiburn/translation_map.cpp b/debug-tools/wiburn/translation_map.cpp
new file mode 100644
index 0000000..627eacc
--- /dev/null
+++ b/debug-tools/wiburn/translation_map.cpp
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "translation_map.h"
+
+#include "wlct_os.h"
+
+translation_map::translation_map ()
+{
+ //nothing to do
+}
+
+translation_map::~translation_map ()
+{
+ //nothing to do
+}
+
+bool translation_map::add_to_translation_map (const char* key, const char* address, const char* start, const char* end)
+{
+ u_int32_t int_address;
+ int int_start, int_end;
+ char *end_ptr;
+
+ int_address = (u_int32_t)strtoul(address, &end_ptr, 0);
+ if (0 != *end_ptr) {
+ ERR("Error converting %s to int\n", address);
+ EXIT (-1);
+ }
+
+ int_start = strtoul(start, &end_ptr, 0);
+ if (0 != *end_ptr) {
+ ERR("Error converting %s to int\n", start);
+ EXIT (-1);
+ }
+
+ int_end = strtoul(end, &end_ptr, 0);
+ if (0 != *end_ptr) {
+ ERR("Error converting %s to int\n", end);
+ EXIT (-1);
+ }
+
+ return add_to_translation_map(key, int_address, int_start, int_end);
+}
+
+
+bool translation_map::add_to_translation_map (const char* key, const u_int32_t address, const int start, const int end)
+{
+ full_address_t temp_address = {address, start, end};
+ string temp_string (key);
+ translation_map_t::value_type entry (key, temp_address);
+ pair <translation_map_t::iterator, bool> ret;
+ ret = m_map.insert(entry);
+ return (ret.second);
+}
+
+bool translation_map::get_from_translation_map (const char* key, u_int32_t *address, int *start, int *end) const
+{
+ translation_map_t::const_iterator iter;
+ string temp_string (key);
+ iter = m_map.find(temp_string);
+ if ( iter == m_map.end( ) )
+ {
+ return false;
+ } else {
+ *address = iter->second.address;
+ *start = iter->second.start;
+ *end = iter->second.end;
+ return true;
+ }
+}
+
diff --git a/debug-tools/wiburn/translation_map.h b/debug-tools/wiburn/translation_map.h
new file mode 100644
index 0000000..d7bd823
--- /dev/null
+++ b/debug-tools/wiburn/translation_map.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _TRANSLATION_MAP_H
+#define _TRANSLATION_MAP_H
+
+#include <map>
+#include <string>
+#include "wiburn.h"
+using namespace std;
+
+class translation_map
+{
+private:
+ typedef struct {
+ u_int32_t address;
+ int start;
+ int end;
+ } full_address_t;
+
+ typedef map <string, full_address_t> translation_map_t;
+
+private:
+ translation_map_t m_map;
+
+public:
+ translation_map ();
+ ~translation_map ();
+ bool add_to_translation_map (const char* key, const u_int32_t address, const int start, const int end);
+ bool add_to_translation_map (const char* key, const char* address, const char* start, const char* end);
+ bool get_from_translation_map (const char* key, u_int32_t *address, int *start, int *end) const;
+};
+
+#endif //#ifndef _TRANSLATION_MAP_H
diff --git a/debug-tools/wiburn/wiburn.cpp b/debug-tools/wiburn/wiburn.cpp
new file mode 100644
index 0000000..97f4268
--- /dev/null
+++ b/debug-tools/wiburn/wiburn.cpp
@@ -0,0 +1,707 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "flash.h"
+#include "translation_map.h"
+#include "flash_image.h"
+#include <signal.h>
+#include "ParameterParser.h"
+#include "product.h"
+#include <iostream>
+
+#ifdef _WINDOWS
+bool g_debug = false;
+#else
+extern bool g_debug;
+#endif
+translation_map g_reg_tree_t_map;
+translation_map g_ucode_t_map;
+translation_map g_fw_t_map;
+
+extern u_int64_t current_fw_build;
+
+ini_parser_base *g_parser = 0;
+flash_base *g_flash = 0;
+
+volatile bool g_exit = false;
+
+int g_signals_for_termination[] = {
+ SIGINT,
+ SIGTERM
+};
+
+bool IsReduced();
+
+
+void EXIT (int val) {
+ delete g_flash;
+ exit (val);
+}
+
+bool get_interface (string *name) {
+ INFO("Acquiring available interfaces. Please wait...\n");
+ INTERFACE_LIST interfaces;
+ int num_items;
+ int res;
+ res = GetInterfaces(&interfaces, &num_items);
+ INFO("\n");
+
+ if (res != 0 || num_items == 0) {
+ return false;
+ }
+
+ if (num_items == 1 ) {
+ *name = interfaces.list[0].ifName;
+ INFO("Using the single available interface %s\n", interfaces.list[0].ifName);
+ return true;
+ }
+
+ printf("Please choose interface index:\n");
+ for (int i = 0; i < num_items; i++) {
+ std::cout << "[" << i << "] " << interfaces.list[i].ifName << std::endl;
+ }
+
+ u_int32_t index;
+ std::cin >> index;
+
+ if (!std::cin.good() || index >= (u_int32_t)num_items ) {
+ ERR("Invalid interface chosen\n");
+ EXIT (-1);
+ }
+
+ *name = interfaces.list[index].ifName;
+ return true;
+}
+
+void print_buffer(const void *buffer, int length)
+{
+ for(int i=0; i< length; i++) {
+ putchar(*((char*)(buffer) + i));
+ }
+}
+
+void set_exit_flag(bool bExit)
+{
+ g_exit = bExit;
+ if (g_flash)
+ {
+ g_flash->set_exit_flag(bExit);
+ }
+}
+
+void TerminationHandler (int signum)
+{
+ static int termination_cnt = 0;
+ if (signum == 0) {
+ INFO ("\nTrying to exit...\n");
+ set_exit_flag(true);
+ return;
+ }
+
+ termination_cnt++;
+
+ if (termination_cnt == 2) {
+ INFO ("\nTrying to exit...\n");
+ set_exit_flag(true);
+ }
+ else {
+ INFO ("\nWarning: Please wait for program normal termination or press ^C again to exit.\n");
+ signal(signum, TerminationHandler);
+ return;
+ }
+}
+
+void compatibility_check() {
+ /* const u_int64_t minimal_ver_supported = 2026;
+ if (current_fw_build < minimal_ver_supported) {
+ ERR("Current INI file is older than %lu and is not supported by this wiburn version !\n", (long unsigned int)minimal_ver_supported);
+ //EXIT (-1);
+ }*/
+}
+
+void param_parsing (ParameterParser *opt)
+{
+ opt->addFlag( "-debug" ); /* a flag (takes no argument), supporting long and short form */
+ opt->addFlag( "-verify" ); /* a flag (takes no argument), supporting long and short form */
+ opt->addFlag( "-help" ); /* a flag (takes no argument), supporting long and short form */
+ opt->addFlag( "-save"); /* a flag (takes no argument), supporting long and short form */
+ opt->addFlag( "-burn" ); /* a flag (takes no argument), supporting long and short form */
+ opt->addFlag( "-read" ); /* a flag (takes no argument), supporting long and short form */
+ opt->addFlag( "-read_formatted" ); /* a flag (takes no argument), supporting long and short form */
+ opt->addFlag( "-query" ); /* a flag (takes no argument), supporting long and short form */
+ opt->addFlag( "-erase"); /* a flag (takes no argument), supporting long and short form */
+ opt->addFlag( "-force"); /* a flag (takes no argument), supporting long and short form */
+ opt->addFlag( "-ignore_lock"); /* a flag (takes no argument), supporting long and short form */
+ opt->addFlag( "-read_ids_to_file"); /* a flag (takes no argument), supporting long and short form */
+
+ opt->addParam( "-bin" );/* an option (takes an argument), supporting long and short form */
+ opt->addParam( "-fw" );/* an option (takes an argument), supporting long and short form */
+ opt->addParam( "-board" );/* an option (takes an argument), supporting long and short form */
+ opt->addParam( "-board2" );/* an option (takes an argument), supporting long and short form */
+ opt->addParam( "-board3" );/* an option (takes an argument), supporting long and short form */
+ opt->addParam( "-setup_ini" );/* an option (takes an argument), supporting long and short form */
+ opt->addParam( "-ids" );/* an option (takes an argument), supporting long and short form */
+ opt->addParam( "-production" );/* an option (takes an argument), supporting long and short form */
+ opt->addParam( "-usb" );/* an option (takes an argument), supporting long and short form */
+ opt->addParam( "-interface" );/* an option (takes an argument), supporting long and short form */
+ opt->addParam( "-device" );/* an option (takes an argument), supporting long and short form */
+ opt->addParam( "-offset" );/* an option (takes an argument), supporting long and short form */
+ opt->addParam( "-length" );/* an option (takes an argument), supporting long and short form */
+}
+
+template <typename PRODUCT>
+void sub_main(bool burn,
+ bool erase,
+ bool burn_full_image,
+ bool query,
+ bool verify,
+ bool read,
+ bool read_formatted,
+ bool read_ids_to_file,
+ bool force,
+ const char* offset,
+ const char* length,
+ const char* bin_file,
+ const char* fw_ini_file,
+ const char* ids_ini_file,
+ const char* production_ini_file,
+ const char* board_ini_file,
+ const char* board_ini_file2,
+ const char* board_ini_file3,
+ const char* setup_ini_file,
+ const char* usb_ini_file)
+{
+ flash_image<PRODUCT>* new_flash_image = 0;
+ flash_image<PRODUCT>* old_flash_image = 0;
+
+ bool reducedSip = IsReduced();
+
+ if (reducedSip)
+ {
+ INFO("SIP type: REDUCED");
+ }
+ else
+ {
+ INFO("SIP type: FULL");
+ }
+
+ old_flash_image = new flash_image<PRODUCT>;
+ old_flash_image->init_pointer_section(g_flash);
+ old_flash_image->init_ids_section(g_flash, reducedSip);
+ const ids_section_t<PRODUCT> &ids = old_flash_image->get_ids_section();
+
+ if( read_ids_to_file ) {
+ INFO("\nReading current IDS section into file: %s\n", ids_ini_file);
+ ids.disp();
+ ids.disp_to_file( ids_ini_file );
+ }
+
+ // parse INI file if needed
+ if( burn ) {
+ new_flash_image = new flash_image<PRODUCT>;
+ if( bin_file ) {
+ INFO("\n######### Initializing from BIN file %s ###########\n", bin_file);
+ new_flash_image->init(bin_file);
+ } else {
+ if( fw_ini_file ) {
+ INFO("\n######### Initializing from FW INI file %s ###########\n", fw_ini_file);
+ g_parser->init(fw_ini_file);
+ }
+ if( ids_ini_file ) {
+ INFO("\n######### Initializing from IDs INI file %s ###########\n", ids_ini_file);
+ g_parser->init(ids_ini_file);
+ }
+ else
+ {
+ INFO("\n######### Taking IDs section from flash ###########\n");
+ new_flash_image->init_ids_section( g_flash, reducedSip );
+ }
+
+ if( production_ini_file ) {
+ INFO("\n######### Initializing from Production INI file %s ###########\n", production_ini_file);
+ g_parser->init(production_ini_file);
+ }
+ if( board_ini_file ) {
+ INFO("\n######### Initializing from Board INI file %s ###########\n", board_ini_file);
+ g_parser->init(board_ini_file);
+ }
+ if( board_ini_file2 ) {
+ INFO("\n######### Initializing from Board2 INI file %s ###########\n", board_ini_file2);
+ g_parser->init(board_ini_file2, 1);
+ }
+ if( board_ini_file3 ) {
+ INFO("\n######### Initializing from Board3 INI file %s ###########\n", board_ini_file3);
+ g_parser->init(board_ini_file3, 1);
+ }
+ if( setup_ini_file ) {
+ INFO("\n######### Initializing from setup_ini INI file %s ###########\n", setup_ini_file);
+ g_parser->init(setup_ini_file);
+ }
+ if( usb_ini_file ) {
+ INFO("\n######### Initializing from USB INI file %s ###########\n", usb_ini_file);
+ g_parser->init(usb_ini_file);
+ }
+ INFO("\n######### Building flash sections ###########\n");
+
+ if (!erase) {
+ new_flash_image->init_pointer_section(g_flash);
+ }
+
+ new_flash_image->init(g_parser, burn_full_image, reducedSip);
+ INFO("\n######### Flash sections are ready ###########\n");
+ }
+ }
+
+ if( query ) {
+ old_flash_image = new flash_image<PRODUCT>;
+ old_flash_image->init_pointer_section( g_flash );
+ old_flash_image->init_image_info_section( g_flash );
+ old_flash_image->init_ids_section( g_flash, reducedSip );
+// old_flash_image->init_usb_info_section( g_flash );
+ const image_info_section_t<PRODUCT> &info = old_flash_image->get_image_info_section();
+ info.disp();
+ const ids_section_t<PRODUCT> &ids = old_flash_image->get_ids_section();
+ ids.disp();
+ const usb_info_section_t<PRODUCT> &usb_info = old_flash_image->get_usb_info_section();
+ usb_info.disp();
+ }
+
+ if( erase ) {
+ compatibility_check();
+ INFO("Erasing flash ...");
+ g_flash->erase();
+ INFO("done\n");
+ }
+
+ if( burn ) {
+ compatibility_check();
+ if (erase) {// Full image burn
+ INFO("Burning image...\n");
+ int res = g_flash->program(4, new_flash_image->get_image_size() - 4, new_flash_image->get_image() + 4, verify);
+
+ if (res != 0) {
+ ERR("\nBurning failed !\n\n");
+ EXIT (-1);
+ }
+
+ INFO("Burning signature...\n");
+ g_flash->program(0, 4, new_flash_image->get_image(), verify);
+ INFO("Burning done\n");
+
+ } else {
+ flash_image<PRODUCT> *old_flash_image = new flash_image<PRODUCT>;
+ old_flash_image->init_pointer_section( g_flash );
+ const pointer_section_t<PRODUCT> &new_pointer_section = new_flash_image->get_pointer_section();
+ if( !(old_flash_image->get_pointer_section() == new_pointer_section )) {
+ ERR("Current INI file will cause changes in the pointer section."
+ " Changes in pointer section are not supported\n");
+ //EXIT (-1);
+ }
+
+ ini_file_t::iterator dummy1;
+ ini_file_t::const_iterator dummy2;
+
+ const hw_section_t<PRODUCT> &new_hw_conf_section = new_flash_image->get_hw_conf_section();
+ const hw_section_t<PRODUCT> &old_hw_conf_section = old_flash_image->get_hw_conf_section();
+ if (!force ) {
+ string section_name = "hw_config";
+ if (g_parser->get_section(section_name, TRANSLATION_MAP_REGTREE, &dummy1, false, false)) {
+ //if (g_parser->get_section(section_name, &dummy1, &dummy2, false)) {
+ old_flash_image->init_hw_conf_section( g_flash );
+ if( !(old_hw_conf_section == new_hw_conf_section ) ) {
+ ERR("Current INI file will cause changes in the hw_configuration "
+ "section. These changes may leave the device in an unstable state."
+ " Use -force option to force the operation.\n");
+ EXIT(-1);
+ }
+ }
+ }
+
+ INFO("Burning image...\n");
+ // write all sections following the pointer_section.
+ // Only modified sections will be written.
+ // Unmodified sections will be skipped
+ u_int32_t start_offset = new_pointer_section.size() + sizeof(u_int32_t); //For CRC
+ g_flash->program(start_offset,
+ new_flash_image->get_image_size() - start_offset,
+ new_flash_image->get_image() + start_offset,
+ verify);
+
+ INFO("Burning done\n");
+ }
+ }
+
+ if(read | read_formatted) {
+ char *end_ptr;
+ int int_offset = strtoul(offset, &end_ptr, 0);
+ if (*end_ptr != 0 ) {
+ ERR("Expected offset and got %s\n", offset);
+ EXIT(-1);
+ }
+ int int_length = strtoul(length, &end_ptr, 0);
+ if (*end_ptr != 0 ) {
+ ERR("Expected length and got %s\n", length);
+ EXIT(-1);
+ }
+
+ BYTE *tmp_buffer = new BYTE [int_length];
+ g_flash->read(int_offset, int_length, tmp_buffer);
+
+ if (read_formatted) {
+ int step = 16;
+ for(int i = 0; i < int_length; i += step) {
+ printf("0x%05x:", int_offset+i);
+ for( int j = 0; j < min(step, int_length - i); j += 2 ) {
+ printf(" 0x%04x", *(u_int16_t*)(tmp_buffer+i+j));
+ }
+ printf("\n");
+ }
+ } else {
+ for(int i = 0; i < int_length; i += 2) {
+ printf("0x%04x ", *(u_int16_t*)(tmp_buffer+i));
+ }
+ printf("\n");
+ }
+ delete[] tmp_buffer;
+
+ }
+
+ delete old_flash_image;
+ delete new_flash_image;
+
+ EXIT(0);
+}
+
+bool IsReduced()
+{
+ u_int32_t verifyAddress = 256 * 1024;
+
+ BYTE testSequence[8] = {0x52, 0x65, 0x64, 0x75, 0x63, 0x65, 0x64, 0x21}; // ASCII for "Reduced!"
+ BYTE verifySequence[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+ BYTE originalData[4096] = {1};
+ BYTE manipulatedData[4096] = {2};
+
+ // Save the original data to be restored later
+ g_flash->read(verifyAddress, sizeof(originalData), originalData);
+ //INFO("1. %d %d %d\n", verifyAddress, sizeof(originalData), originalData);
+
+ memcpy(manipulatedData, originalData, sizeof(originalData));
+ memcpy(manipulatedData, testSequence, sizeof(testSequence));
+ //INFO("%s\n",manipulatedData);
+
+ // We are writing the testSequence to an address which will not exist in reduced SIP (which is 64K) with verify set to true
+ g_flash->program(verifyAddress /*This address will not exist in reduced SIP*/, sizeof(manipulatedData), manipulatedData, true);
+
+ //INFO("2. %d %d %d\n", verifyAddress, sizeof(manipulatedData), manipulatedData);
+ g_flash->read(verifyAddress & ((64 * 1024) - 1), sizeof(verifySequence), verifySequence);
+
+ // Restore the original data
+ g_flash->clear_erased(verifyAddress);
+ g_flash->program(verifyAddress, sizeof(originalData), originalData, true);
+ //INFO("3. %d %d %d\n", verifyAddress, sizeof(originalData), originalData);
+
+ if (0 == memcmp(testSequence, verifySequence, sizeof(testSequence)))
+ {
+ return true;
+ }
+ //else
+ {
+ return false;
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ const char *fw_ini_file;
+ const char *bin_file;
+ const char *board_ini_file;
+ const char *board_ini_file2;
+ const char *board_ini_file3;
+ const char *setup_ini_file;
+ const char *ids_ini_file;
+ const char *production_ini_file;
+ const char *usb_ini_file;
+ const char *flash_image_file;
+ const char *interface_name;
+ const char *device_type_string;
+ DType device_type = MST_NONE;
+ string str_interface_name;
+ const char *offset;
+ const char *length;
+ bool erase, verify, save, burn, read, read_formatted, query, force, read_ids_to_file;
+ bool ignore_lock, burn_full_image;
+
+// printf("Press enter to debug ErezK..");
+// getchar();
+
+ //
+ // Map termination signal handlers
+ //
+ //int i;
+// for (i = 0 ; i < (int)(sizeof(g_signals_for_termination)/sizeof(g_signals_for_termination[0])) ; i++ ) {
+// signal (g_signals_for_termination[i], TerminationHandler);
+// }
+
+ //
+ // command line parsing
+ //
+ ParameterParser *opt = new ParameterParser();
+ param_parsing(opt);
+ if (opt->processCommandArgs( argc, argv ) != 0) {
+ EXIT (-1);
+ }
+
+ if( opt->getFlag( "-help" ) ) {
+ opt->printUsage();
+ EXIT(0);
+ }
+
+ flash_image_file = opt->getValue( "-bin" );
+ fw_ini_file = opt->getValue( "-fw" );
+ bin_file = opt->getValue( "-bin" );
+ ids_ini_file = opt->getValue( "-ids" );
+ production_ini_file = opt->getValue( "-production" );
+ board_ini_file = opt->getValue( "-board" );
+ board_ini_file2 = opt->getValue( "-board2" );
+ board_ini_file3 = opt->getValue( "-board3" );
+ setup_ini_file = opt->getValue( "-setup_ini" );
+ usb_ini_file = opt->getValue( "-usb" );
+ interface_name = opt->getValue( "-interface" );
+ device_type_string = opt->getValue( "-device" );
+ offset = opt->getValue( "-offset" );
+ length = opt->getValue( "-length" );
+ g_debug = opt->getFlag( "-debug" );
+ erase = opt->getFlag( "-erase" );
+ verify = opt->getFlag( "-verify" );// | opt->getFlag( 'v' );
+ save = opt->getFlag( "-save" );
+ burn = opt->getFlag( "-burn" );// | opt->getFlag( 'b' );
+ read = opt->getFlag( "-read" ); //| opt->getFlag( 'r' );
+ read_formatted = opt->getFlag( "-read_formatted" ); //| opt->getFlag( 'r' );
+ query = opt->getFlag( "-query" );
+ force = opt->getFlag( "-force" );
+ ignore_lock = opt->getFlag ("-ignore_lock" );
+ read_ids_to_file = opt->getFlag ("-read_ids_to_file" );
+
+ WLCT_UNREFERENCED_PARAM(flash_image_file);
+ WLCT_UNREFERENCED_PARAM(save);
+
+ //
+ // check missing/extra params
+ //
+ bool has_ini_file = fw_ini_file != 0 || ids_ini_file != 0 || usb_ini_file != 0 || board_ini_file != 0 || board_ini_file2 != 0 || board_ini_file3 != 0 || production_ini_file != 0;
+ bool has_bin_file = bin_file != 0;
+ bool missing_ini_file = board_ini_file == 0 && board_ini_file2 != 0 && board_ini_file3 != 0;
+
+ if ( burn ) {
+ if ( !(has_ini_file | has_bin_file)) {
+ ERR("option -burn require INI or BIN file name\nUse wiburn -h for usage info\n");
+ EXIT(-1);
+ }
+ if ( has_ini_file && has_bin_file) {
+ ERR("option -burn require INI or BIN file name. Not both\nUse wiburn -h for usage info\n");
+ EXIT(-1);
+ }
+ if ( missing_ini_file ) {
+ ERR("option -board2/-board3 require -board.\nUse wiburn -h for usage info\n");
+ EXIT(-1);
+ }
+ }
+
+ if (read_ids_to_file) {
+ if (ids_ini_file == 0) {
+ ERR("option -read_ids_to_file require IDS file name.\nUse wiburn -h for usage info\n");
+ EXIT(-1);
+ }
+ if(burn){
+ INFO("\nCurrent IDS section will not be changed !\n\n");
+ }
+ }
+
+ if ( burn | erase | read | read_formatted | query | read_ids_to_file) {
+ if (interface_name == 0) {
+ if( get_interface(&str_interface_name) == false ) {
+ ERR("Missing interface name\nUse wiburn -h for usage info\n");
+ EXIT(-1);
+ } else {
+ interface_name = str_interface_name.c_str();
+ }
+ }
+ }
+
+ if (read | read_formatted) {
+ if( length == 0 || offset == 0 ) {
+ ERR("Missing length or offset\nUse wiburn -h for usage info\n");
+ EXIT(-1);
+ }
+ }
+
+
+
+ burn_full_image = burn && erase;
+
+ //
+ // DLL info
+ //
+ WLCT_DLL_VERSION dll_ver;
+ GetMyVersion(&dll_ver);
+ INFO("Using DLL version %d.%d.%d.%d\n",
+ dll_ver.major,
+ dll_ver.minor,
+ dll_ver.maintenance,
+ dll_ver.build );
+
+ if (device_type_string == 0) {
+ ERR("Missing device type\nUse wiburn -h for usage info\n");
+ EXIT(-1);
+ }
+ else
+ {
+ if( strcmp("MARLON", device_type_string) == 0 )
+ {
+ device_type = MST_MARLON;
+ }
+ else if( strcmp("SPARROW", device_type_string) == 0 )
+ {
+ device_type = MST_SPARROW;
+ }
+ else if( strcmp("TALYN", device_type_string) == 0 )
+ {
+ device_type = MST_TALYN;
+ }
+ else
+ {
+ ERR("Unknown device type %s. Supported device types are SPARROW and MARLON\n", device_type_string);
+ EXIT(-1);
+ }
+ }
+
+ //
+ // Start executing
+ //
+ if ( burn | erase | query)
+ {
+ if( device_type == MST_MARLON )
+ {
+ g_parser = new ini_parser<marlon>;
+ }
+ else if( device_type == MST_SPARROW )
+ {
+ g_parser = new ini_parser<sparrow>;
+ }
+ else if( device_type == MST_TALYN )
+ {
+ g_parser = new ini_parser<talyn>;
+ }
+ else {
+ ERR("Unknown device type %s. Supported device types are SPARROW and MARLON\n", device_type_string);
+ EXIT(-1);
+ }
+ }
+
+ if (burn | erase | read | read_formatted | query | read_ids_to_file) {
+ if (strchr(interface_name, '.') != NULL) {
+ g_flash = new flash_file(device_type);
+ } else {
+ g_flash = new flash(device_type);
+ }
+ if (g_flash->open(interface_name, device_type, ignore_lock) != 0)
+ {
+ ERR("Can't open device %s with specified type %s.\n", interface_name, device_type_string);
+ EXIT(-1);
+ }
+ }
+
+ if (device_type == MST_TALYN) {
+ sub_main<talyn> (burn,
+ erase,
+ burn_full_image,
+ query,
+ verify,
+ read,
+ read_formatted,
+ read_ids_to_file,
+ force,
+ offset,
+ length,
+ bin_file,
+ fw_ini_file,
+ ids_ini_file,
+ production_ini_file,
+ board_ini_file,
+ board_ini_file2,
+ board_ini_file3,
+ setup_ini_file,
+ usb_ini_file);
+ }
+ if (device_type == MST_SPARROW) {
+ sub_main<sparrow> (burn,
+ erase,
+ burn_full_image,
+ query,
+ verify,
+ read,
+ read_formatted,
+ read_ids_to_file,
+ force,
+ offset,
+ length,
+ bin_file,
+ fw_ini_file,
+ ids_ini_file,
+ production_ini_file,
+ board_ini_file,
+ board_ini_file2,
+ board_ini_file3,
+ setup_ini_file,
+ usb_ini_file);
+ } else {
+ sub_main<marlon> (burn,
+ erase,
+ burn_full_image,
+ query,
+ verify,
+ read,
+ read_formatted,
+ read_ids_to_file,
+ force,
+ offset,
+ length,
+ bin_file,
+ fw_ini_file,
+ ids_ini_file,
+ production_ini_file,
+ board_ini_file,
+ board_ini_file2,
+ board_ini_file3,
+ setup_ini_file,
+ usb_ini_file);
+ }
+
+}
+
diff --git a/debug-tools/wiburn/wiburn.h b/debug-tools/wiburn/wiburn.h
new file mode 100644
index 0000000..bd195f6
--- /dev/null
+++ b/debug-tools/wiburn/wiburn.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _WIBURN_H_
+#define _WIBURN_H_
+
+extern bool g_debug;
+extern volatile bool g_exit;
+
+#ifdef _WINDOWS
+#include <windows.h>
+
+#define STRTOULL _strtoui64
+
+typedef unsigned __int8 u_int8_t;
+typedef unsigned __int16 u_int16_t;
+typedef unsigned __int32 u_int32_t;
+typedef unsigned __int64 u_int64_t;
+#if (defined(_MSC_VER) && (_MSC_VER < 1900))
+typedef __int8 int8_t;
+#endif
+typedef __int16 int16_t;
+typedef __int32 int32_t;
+typedef __int64 int64_t;
+
+#else //#ifdef _WINDOWS
+
+#define STRTOULL strtoull
+
+#include <sys/types.h>
+typedef u_int8_t u_int8_t;
+typedef u_int16_t u_int16_t;
+typedef u_int32_t u_int32_t;
+typedef u_int64_t u_int64_t;
+typedef int8_t int8_t;
+typedef int16_t int16_t;
+typedef int32_t int32_t;
+typedef int64_t int64_t;
+#endif //#ifdef _WINDOWS
+
+typedef u_int32_t ADDRESS32;
+
+typedef u_int8_t BYTE;
+typedef u_int32_t IMAGE;
+
+
+#define PAGE 256
+#define FLASH_PAGE_MASK 0xffffff00
+#define SUB_SECTOR (16*PAGE) // 4KB
+#define SUB_SECTOR_MASK 0xfffff000
+#define SECTOR (16*SUB_SECTOR) // 64KB
+
+#define ERR printf
+#define DBG printf
+#define INFO printf
+
+void EXIT( int val );
+
+void print_buffer(const void *buffer, int length);
+#endif //#ifndef _WIBURN_H_