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/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;
+}