Code from pmc.c will be reused by new snmpd.c in later commit.

Signed-off-by: Anders Selhammer <anders.selham...@est.tech>
---
 pmc.c        | 299 +----------------------------------------------------------
 pmc_common.c | 294 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 pmc_common.h |   9 ++
 3 files changed, 305 insertions(+), 297 deletions(-)

diff --git a/pmc.c b/pmc.c
index d7a10e5..5632a77 100644
--- a/pmc.c
+++ b/pmc.c
@@ -35,88 +35,8 @@
 #include "util.h"
 #include "version.h"
 
-#define BAD_ACTION   -1
-#define BAD_ID       -1
-#define AMBIGUOUS_ID -2
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
-#define P41 ((double)(1ULL << 41))
-
 static struct pmc *pmc;
 
-static void do_get_action(int action, int index, char *str);
-static void do_set_action(int action, int index, char *str);
-static void not_supported(int action, int index, char *str);
-static void null_management(int action, int index, char *str);
-
-struct management_id {
-       char name[64];
-       int code;
-       void (*func)(int action, int index, char *str);
-};
-
-struct management_id idtab[] = {
-/* Clock management ID values */
-       { "USER_DESCRIPTION", TLV_USER_DESCRIPTION, do_get_action },
-       { "SAVE_IN_NON_VOLATILE_STORAGE", TLV_SAVE_IN_NON_VOLATILE_STORAGE, 
not_supported },
-       { "RESET_NON_VOLATILE_STORAGE", TLV_RESET_NON_VOLATILE_STORAGE, 
not_supported },
-       { "INITIALIZE", TLV_INITIALIZE, not_supported },
-       { "FAULT_LOG", TLV_FAULT_LOG, not_supported },
-       { "FAULT_LOG_RESET", TLV_FAULT_LOG_RESET, not_supported },
-       { "DEFAULT_DATA_SET", TLV_DEFAULT_DATA_SET, do_get_action },
-       { "CURRENT_DATA_SET", TLV_CURRENT_DATA_SET, do_get_action },
-       { "PARENT_DATA_SET", TLV_PARENT_DATA_SET, do_get_action },
-       { "TIME_PROPERTIES_DATA_SET", TLV_TIME_PROPERTIES_DATA_SET, 
do_get_action },
-       { "PRIORITY1", TLV_PRIORITY1, do_set_action },
-       { "PRIORITY2", TLV_PRIORITY2, do_set_action },
-       { "DOMAIN", TLV_DOMAIN, do_get_action },
-       { "SLAVE_ONLY", TLV_SLAVE_ONLY, do_get_action },
-       { "TIME", TLV_TIME, not_supported },
-       { "CLOCK_ACCURACY", TLV_CLOCK_ACCURACY, do_get_action },
-       { "UTC_PROPERTIES", TLV_UTC_PROPERTIES, not_supported },
-       { "TRACEABILITY_PROPERTIES", TLV_TRACEABILITY_PROPERTIES, do_get_action 
},
-       { "TIMESCALE_PROPERTIES", TLV_TIMESCALE_PROPERTIES, do_get_action },
-       { "PATH_TRACE_LIST", TLV_PATH_TRACE_LIST, not_supported },
-       { "PATH_TRACE_ENABLE", TLV_PATH_TRACE_ENABLE, not_supported },
-       { "GRANDMASTER_CLUSTER_TABLE", TLV_GRANDMASTER_CLUSTER_TABLE, 
not_supported },
-       { "ACCEPTABLE_MASTER_TABLE", TLV_ACCEPTABLE_MASTER_TABLE, not_supported 
},
-       { "ACCEPTABLE_MASTER_MAX_TABLE_SIZE", 
TLV_ACCEPTABLE_MASTER_MAX_TABLE_SIZE, not_supported },
-       { "ALTERNATE_TIME_OFFSET_ENABLE", TLV_ALTERNATE_TIME_OFFSET_ENABLE, 
not_supported },
-       { "ALTERNATE_TIME_OFFSET_NAME", TLV_ALTERNATE_TIME_OFFSET_NAME, 
not_supported },
-       { "ALTERNATE_TIME_OFFSET_MAX_KEY", TLV_ALTERNATE_TIME_OFFSET_MAX_KEY, 
not_supported },
-       { "ALTERNATE_TIME_OFFSET_PROPERTIES", 
TLV_ALTERNATE_TIME_OFFSET_PROPERTIES, not_supported },
-       { "TRANSPARENT_CLOCK_DEFAULT_DATA_SET", 
TLV_TRANSPARENT_CLOCK_DEFAULT_DATA_SET, not_supported },
-       { "PRIMARY_DOMAIN", TLV_PRIMARY_DOMAIN, not_supported },
-       { "TIME_STATUS_NP", TLV_TIME_STATUS_NP, do_get_action },
-       { "GRANDMASTER_SETTINGS_NP", TLV_GRANDMASTER_SETTINGS_NP, do_set_action 
},
-/* Port management ID values */
-       { "NULL_MANAGEMENT", TLV_NULL_MANAGEMENT, null_management },
-       { "CLOCK_DESCRIPTION", TLV_CLOCK_DESCRIPTION, do_get_action },
-       { "PORT_DATA_SET", TLV_PORT_DATA_SET, do_get_action },
-       { "LOG_ANNOUNCE_INTERVAL", TLV_LOG_ANNOUNCE_INTERVAL, do_get_action },
-       { "ANNOUNCE_RECEIPT_TIMEOUT", TLV_ANNOUNCE_RECEIPT_TIMEOUT, 
do_get_action },
-       { "LOG_SYNC_INTERVAL", TLV_LOG_SYNC_INTERVAL, do_get_action },
-       { "VERSION_NUMBER", TLV_VERSION_NUMBER, do_get_action },
-       { "ENABLE_PORT", TLV_ENABLE_PORT, not_supported },
-       { "DISABLE_PORT", TLV_DISABLE_PORT, not_supported },
-       { "UNICAST_NEGOTIATION_ENABLE", TLV_UNICAST_NEGOTIATION_ENABLE, 
not_supported },
-       { "UNICAST_MASTER_TABLE", TLV_UNICAST_MASTER_TABLE, not_supported },
-       { "UNICAST_MASTER_MAX_TABLE_SIZE", TLV_UNICAST_MASTER_MAX_TABLE_SIZE, 
not_supported },
-       { "ACCEPTABLE_MASTER_TABLE_ENABLED", 
TLV_ACCEPTABLE_MASTER_TABLE_ENABLED, not_supported },
-       { "ALTERNATE_MASTER", TLV_ALTERNATE_MASTER, not_supported },
-       { "TRANSPARENT_CLOCK_PORT_DATA_SET", 
TLV_TRANSPARENT_CLOCK_PORT_DATA_SET, not_supported },
-       { "DELAY_MECHANISM", TLV_DELAY_MECHANISM, do_get_action },
-       { "LOG_MIN_PDELAY_REQ_INTERVAL", TLV_LOG_MIN_PDELAY_REQ_INTERVAL, 
do_get_action },
-       { "PORT_DATA_SET_NP", TLV_PORT_DATA_SET_NP, do_set_action },
-};
-
-static const char *action_string[] = {
-       "GET",
-       "SET",
-       "RESPONSE",
-       "COMMAND",
-       "ACKNOWLEDGE",
-};
-
 #define IFMT "\n\t\t"
 
 static char *text2str(struct PTPText *text)
@@ -159,7 +79,7 @@ static void pmc_show(struct ptp_message *msg, FILE *fp)
        }
        fprintf(fp, "\t%s seq %hu %s ",
                pid2str(&msg->header.sourcePortIdentity),
-               msg->header.sequenceId, action_string[action]);
+               msg->header.sequenceId, pmc_action_string(action));
        if (msg->tlv_count != 1) {
                goto out;
        }
@@ -438,221 +358,6 @@ out:
        fflush(fp);
 }
 
-static void do_get_action(int action, int index, char *str)
-{
-       if (action == GET)
-               pmc_send_get_action(pmc, idtab[index].code);
-       else
-               fprintf(stderr, "%s only allows GET\n", idtab[index].name);
-}
-
-static void do_set_action(int action, int index, char *str)
-{
-       struct grandmaster_settings_np gsn;
-       struct management_tlv_datum mtd;
-       struct port_ds_np pnp;
-       int cnt, code = idtab[index].code;
-       int leap_61, leap_59, utc_off_valid;
-       int ptp_timescale, time_traceable, freq_traceable;
-
-       switch (action) {
-       case GET:
-               pmc_send_get_action(pmc, code);
-               return;
-       case SET:
-               break;
-       case RESPONSE:
-       case COMMAND:
-       case ACKNOWLEDGE:
-       default:
-               fprintf(stderr, "%s only allows GET or SET\n",
-                       idtab[index].name);
-               return;
-       }
-       switch (code) {
-       case TLV_PRIORITY1:
-       case TLV_PRIORITY2:
-               cnt = sscanf(str,  " %*s %*s %hhu", &mtd.val);
-               if (cnt != 1) {
-                       fprintf(stderr, "%s SET needs 1 value\n",
-                               idtab[index].name);
-                       break;
-               }
-               pmc_send_set_action(pmc, code, &mtd, sizeof(mtd));
-               break;
-       case TLV_GRANDMASTER_SETTINGS_NP:
-               cnt = sscanf(str, " %*s %*s "
-                            "clockClass              %hhu "
-                            "clockAccuracy           %hhx "
-                            "offsetScaledLogVariance %hx "
-                            "currentUtcOffset        %hd "
-                            "leap61                  %d "
-                            "leap59                  %d "
-                            "currentUtcOffsetValid   %d "
-                            "ptpTimescale            %d "
-                            "timeTraceable           %d "
-                            "frequencyTraceable      %d "
-                            "timeSource              %hhx ",
-                            &gsn.clockQuality.clockClass,
-                            &gsn.clockQuality.clockAccuracy,
-                            &gsn.clockQuality.offsetScaledLogVariance,
-                            &gsn.utc_offset,
-                            &leap_61,
-                            &leap_59,
-                            &utc_off_valid,
-                            &ptp_timescale,
-                            &time_traceable,
-                            &freq_traceable,
-                            &gsn.time_source);
-               if (cnt != 11) {
-                       fprintf(stderr, "%s SET needs 11 values\n",
-                               idtab[index].name);
-                       break;
-               }
-               gsn.time_flags = 0;
-               if (leap_61)
-                       gsn.time_flags |= LEAP_61;
-               if (leap_59)
-                       gsn.time_flags |= LEAP_59;
-               if (utc_off_valid)
-                       gsn.time_flags |= UTC_OFF_VALID;
-               if (ptp_timescale)
-                       gsn.time_flags |= PTP_TIMESCALE;
-               if (time_traceable)
-                       gsn.time_flags |= TIME_TRACEABLE;
-               if (freq_traceable)
-                       gsn.time_flags |= FREQ_TRACEABLE;
-               pmc_send_set_action(pmc, code, &gsn, sizeof(gsn));
-               break;
-       case TLV_PORT_DATA_SET_NP:
-               cnt = sscanf(str, " %*s %*s "
-                            "neighborPropDelayThresh %u "
-                            "asCapable               %d ",
-                            &pnp.neighborPropDelayThresh,
-                            &pnp.asCapable);
-               if (cnt != 2) {
-                       fprintf(stderr, "%s SET needs 2 values\n",
-                               idtab[index].name);
-                       break;
-               }
-               pmc_send_set_action(pmc, code, &pnp, sizeof(pnp));
-               break;
-       }
-}
-
-static void not_supported(int action, int index, char *str)
-{
-       fprintf(stdout, "sorry, %s not supported yet\n", idtab[index].name);
-}
-
-static void null_management(int action, int index, char *str)
-{
-       if (action == GET)
-               pmc_send_get_action(pmc, idtab[index].code);
-       else
-               puts("non-get actions still todo");
-}
-
-static int parse_action(char *s)
-{
-       int len = strlen(s);
-       if (0 == strncasecmp(s, "GET", len))
-               return GET;
-       else if (0 == strncasecmp(s, "SET", len))
-               return SET;
-       else if (0 == strncasecmp(s, "CMD", len))
-               return COMMAND;
-       else if (0 == strncasecmp(s, "COMMAND", len))
-               return COMMAND;
-       return BAD_ACTION;
-}
-
-static int parse_id(char *s)
-{
-       int i, index = BAD_ID, len = strlen(s);
-       /* check for exact match */
-       for (i = 0; i < ARRAY_SIZE(idtab); i++) {
-               if (strcasecmp(s, idtab[i].name) == 0) {
-                       return i;
-               }
-       }
-       /* look for a unique prefix match */
-       for (i = 0; i < ARRAY_SIZE(idtab); i++) {
-               if (0 == strncasecmp(s, idtab[i].name, len)) {
-                       if (index == BAD_ID)
-                               index = i;
-                       else
-                               return AMBIGUOUS_ID;
-               }
-       }
-       return index;
-}
-
-static int parse_target(const char *str)
-{
-       struct PortIdentity pid;
-
-       if (str[0] == '*') {
-               memset(&pid, 0xff, sizeof(pid));
-       } else if (str2pid(str, &pid)) {
-               return -1;
-       }
-
-       return pmc_target(pmc, &pid);
-}
-
-static void print_help(FILE *fp)
-{
-       int i;
-       fprintf(fp, "\n");
-       for (i = 0; i < ARRAY_SIZE(idtab); i++) {
-               if (idtab[i].func != not_supported)
-                       fprintf(fp, "\t[action] %s\n", idtab[i].name);
-       }
-       fprintf(fp, "\n");
-       fprintf(fp, "\tThe [action] can be GET, SET, CMD, or COMMAND\n");
-       fprintf(fp, "\tCommands are case insensitive and may be 
abbreviated.\n");
-       fprintf(fp, "\n");
-       fprintf(fp, "\tTARGET [portIdentity]\n");
-       fprintf(fp, "\tTARGET *\n");
-       fprintf(fp, "\n");
-}
-
-static int do_command(char *str)
-{
-       int action, id;
-       char action_str[10+1] = {0}, id_str[64+1] = {0};
-
-       if (0 == strncasecmp(str, "HELP", strlen(str))) {
-               print_help(stdout);
-               return 0;
-       }
-
-       if (2 != sscanf(str, " %10s %64s", action_str, id_str))
-               return -1;
-
-       if (0 == strncasecmp(action_str, "TARGET", strlen(action_str)))
-               return parse_target(id_str);
-
-       action = parse_action(action_str);
-       id = parse_id(id_str);
-
-       if (action == BAD_ACTION || id == BAD_ID)
-               return -1;
-
-       if (id == AMBIGUOUS_ID) {
-               fprintf(stdout, "id %s is too ambiguous\n", id_str);
-               return 0;
-       }
-
-       fprintf(stdout, "sending: %s %s\n",
-               action_string[action], idtab[id].name);
-
-       idtab[id].func(action, id, str);
-
-       return 0;
-}
-
 static void usage(char *progname)
 {
        fprintf(stderr,
@@ -879,7 +584,7 @@ int main(int argc, char *argv[])
                        command = line;
                }
                if (pollfd[1].revents & POLLOUT) {
-                       if (do_command(command)) {
+                       if (pmc_do_command(pmc, command)) {
                                fprintf(stderr, "bad command: %s\n", command);
                        }
                        command = NULL;
diff --git a/pmc_common.c b/pmc_common.c
index b19f4fa..b14b99d 100644
--- a/pmc_common.c
+++ b/pmc_common.c
@@ -48,6 +48,260 @@
 /* Includes one extra byte to make length even. */
 #define EMPTY_PTP_TEXT 2
 
+static void do_get_action(struct pmc *pmc, int action, int index, char *str);
+static void do_set_action(struct pmc *pmc, int action, int index, char *str);
+static void not_supported(struct pmc *pmc, int action, int index, char *str);
+static void null_management(struct pmc *pmc, int action, int index, char *str);
+
+static const char *action_string[] = {
+       "GET",
+       "SET",
+       "RESPONSE",
+       "COMMAND",
+       "ACKNOWLEDGE",
+};
+
+struct management_id {
+       char name[64];
+       int code;
+       void (*func)(struct pmc *pmc, int action, int index, char *str);
+};
+
+struct management_id idtab[] = {
+/* Clock management ID values */
+       { "USER_DESCRIPTION", TLV_USER_DESCRIPTION, do_get_action },
+       { "SAVE_IN_NON_VOLATILE_STORAGE", TLV_SAVE_IN_NON_VOLATILE_STORAGE, 
not_supported },
+       { "RESET_NON_VOLATILE_STORAGE", TLV_RESET_NON_VOLATILE_STORAGE, 
not_supported },
+       { "INITIALIZE", TLV_INITIALIZE, not_supported },
+       { "FAULT_LOG", TLV_FAULT_LOG, not_supported },
+       { "FAULT_LOG_RESET", TLV_FAULT_LOG_RESET, not_supported },
+       { "DEFAULT_DATA_SET", TLV_DEFAULT_DATA_SET, do_get_action },
+       { "CURRENT_DATA_SET", TLV_CURRENT_DATA_SET, do_get_action },
+       { "PARENT_DATA_SET", TLV_PARENT_DATA_SET, do_get_action },
+       { "TIME_PROPERTIES_DATA_SET", TLV_TIME_PROPERTIES_DATA_SET, 
do_get_action },
+       { "PRIORITY1", TLV_PRIORITY1, do_set_action },
+       { "PRIORITY2", TLV_PRIORITY2, do_set_action },
+       { "DOMAIN", TLV_DOMAIN, do_get_action },
+       { "SLAVE_ONLY", TLV_SLAVE_ONLY, do_get_action },
+       { "TIME", TLV_TIME, not_supported },
+       { "CLOCK_ACCURACY", TLV_CLOCK_ACCURACY, do_get_action },
+       { "UTC_PROPERTIES", TLV_UTC_PROPERTIES, not_supported },
+       { "TRACEABILITY_PROPERTIES", TLV_TRACEABILITY_PROPERTIES, do_get_action 
},
+       { "TIMESCALE_PROPERTIES", TLV_TIMESCALE_PROPERTIES, do_get_action },
+       { "PATH_TRACE_LIST", TLV_PATH_TRACE_LIST, not_supported },
+       { "PATH_TRACE_ENABLE", TLV_PATH_TRACE_ENABLE, not_supported },
+       { "GRANDMASTER_CLUSTER_TABLE", TLV_GRANDMASTER_CLUSTER_TABLE, 
not_supported },
+       { "ACCEPTABLE_MASTER_TABLE", TLV_ACCEPTABLE_MASTER_TABLE, not_supported 
},
+       { "ACCEPTABLE_MASTER_MAX_TABLE_SIZE", 
TLV_ACCEPTABLE_MASTER_MAX_TABLE_SIZE, not_supported },
+       { "ALTERNATE_TIME_OFFSET_ENABLE", TLV_ALTERNATE_TIME_OFFSET_ENABLE, 
not_supported },
+       { "ALTERNATE_TIME_OFFSET_NAME", TLV_ALTERNATE_TIME_OFFSET_NAME, 
not_supported },
+       { "ALTERNATE_TIME_OFFSET_MAX_KEY", TLV_ALTERNATE_TIME_OFFSET_MAX_KEY, 
not_supported },
+       { "ALTERNATE_TIME_OFFSET_PROPERTIES", 
TLV_ALTERNATE_TIME_OFFSET_PROPERTIES, not_supported },
+       { "TRANSPARENT_CLOCK_DEFAULT_DATA_SET", 
TLV_TRANSPARENT_CLOCK_DEFAULT_DATA_SET, not_supported },
+       { "PRIMARY_DOMAIN", TLV_PRIMARY_DOMAIN, not_supported },
+       { "TIME_STATUS_NP", TLV_TIME_STATUS_NP, do_get_action },
+       { "GRANDMASTER_SETTINGS_NP", TLV_GRANDMASTER_SETTINGS_NP, do_set_action 
},
+/* Port management ID values */
+       { "NULL_MANAGEMENT", TLV_NULL_MANAGEMENT, null_management },
+       { "CLOCK_DESCRIPTION", TLV_CLOCK_DESCRIPTION, do_get_action },
+       { "PORT_DATA_SET", TLV_PORT_DATA_SET, do_get_action },
+       { "LOG_ANNOUNCE_INTERVAL", TLV_LOG_ANNOUNCE_INTERVAL, do_get_action },
+       { "ANNOUNCE_RECEIPT_TIMEOUT", TLV_ANNOUNCE_RECEIPT_TIMEOUT, 
do_get_action },
+       { "LOG_SYNC_INTERVAL", TLV_LOG_SYNC_INTERVAL, do_get_action },
+       { "VERSION_NUMBER", TLV_VERSION_NUMBER, do_get_action },
+       { "ENABLE_PORT", TLV_ENABLE_PORT, not_supported },
+       { "DISABLE_PORT", TLV_DISABLE_PORT, not_supported },
+       { "UNICAST_NEGOTIATION_ENABLE", TLV_UNICAST_NEGOTIATION_ENABLE, 
not_supported },
+       { "UNICAST_MASTER_TABLE", TLV_UNICAST_MASTER_TABLE, not_supported },
+       { "UNICAST_MASTER_MAX_TABLE_SIZE", TLV_UNICAST_MASTER_MAX_TABLE_SIZE, 
not_supported },
+       { "ACCEPTABLE_MASTER_TABLE_ENABLED", 
TLV_ACCEPTABLE_MASTER_TABLE_ENABLED, not_supported },
+       { "ALTERNATE_MASTER", TLV_ALTERNATE_MASTER, not_supported },
+       { "TRANSPARENT_CLOCK_PORT_DATA_SET", 
TLV_TRANSPARENT_CLOCK_PORT_DATA_SET, not_supported },
+       { "DELAY_MECHANISM", TLV_DELAY_MECHANISM, do_get_action },
+       { "LOG_MIN_PDELAY_REQ_INTERVAL", TLV_LOG_MIN_PDELAY_REQ_INTERVAL, 
do_get_action },
+       { "PORT_DATA_SET_NP", TLV_PORT_DATA_SET_NP, do_set_action },
+};
+
+static void do_get_action(struct pmc *pmc, int action, int index, char *str)
+{
+       if (action == GET)
+               pmc_send_get_action(pmc, idtab[index].code);
+       else
+               fprintf(stderr, "%s only allows GET\n", idtab[index].name);
+}
+
+static void do_set_action(struct pmc *pmc, int action, int index, char *str)
+{
+       struct grandmaster_settings_np gsn;
+       struct management_tlv_datum mtd;
+       struct port_ds_np pnp;
+       int cnt, code = idtab[index].code;
+       int leap_61, leap_59, utc_off_valid;
+       int ptp_timescale, time_traceable, freq_traceable;
+
+       switch (action) {
+       case GET:
+               pmc_send_get_action(pmc, code);
+               return;
+       case SET:
+               break;
+       case RESPONSE:
+       case COMMAND:
+       case ACKNOWLEDGE:
+       default:
+               fprintf(stderr, "%s only allows GET or SET\n",
+                       idtab[index].name);
+               return;
+       }
+       switch (code) {
+       case TLV_PRIORITY1:
+       case TLV_PRIORITY2:
+               cnt = sscanf(str,  " %*s %*s %hhu", &mtd.val);
+               if (cnt != 1) {
+                       fprintf(stderr, "%s SET needs 1 value\n",
+                               idtab[index].name);
+                       break;
+               }
+               pmc_send_set_action(pmc, code, &mtd, sizeof(mtd));
+               break;
+       case TLV_GRANDMASTER_SETTINGS_NP:
+               cnt = sscanf(str, " %*s %*s "
+                            "clockClass              %hhu "
+                            "clockAccuracy           %hhx "
+                            "offsetScaledLogVariance %hx "
+                            "currentUtcOffset        %hd "
+                            "leap61                  %d "
+                            "leap59                  %d "
+                            "currentUtcOffsetValid   %d "
+                            "ptpTimescale            %d "
+                            "timeTraceable           %d "
+                            "frequencyTraceable      %d "
+                            "timeSource              %hhx ",
+                            &gsn.clockQuality.clockClass,
+                            &gsn.clockQuality.clockAccuracy,
+                            &gsn.clockQuality.offsetScaledLogVariance,
+                            &gsn.utc_offset,
+                            &leap_61,
+                            &leap_59,
+                            &utc_off_valid,
+                            &ptp_timescale,
+                            &time_traceable,
+                            &freq_traceable,
+                            &gsn.time_source);
+               if (cnt != 11) {
+                       fprintf(stderr, "%s SET needs 11 values\n",
+                               idtab[index].name);
+                       break;
+               }
+               gsn.time_flags = 0;
+               if (leap_61)
+                       gsn.time_flags |= LEAP_61;
+               if (leap_59)
+                       gsn.time_flags |= LEAP_59;
+               if (utc_off_valid)
+                       gsn.time_flags |= UTC_OFF_VALID;
+               if (ptp_timescale)
+                       gsn.time_flags |= PTP_TIMESCALE;
+               if (time_traceable)
+                       gsn.time_flags |= TIME_TRACEABLE;
+               if (freq_traceable)
+                       gsn.time_flags |= FREQ_TRACEABLE;
+               pmc_send_set_action(pmc, code, &gsn, sizeof(gsn));
+               break;
+       case TLV_PORT_DATA_SET_NP:
+               cnt = sscanf(str, " %*s %*s "
+                            "neighborPropDelayThresh %u "
+                            "asCapable               %d ",
+                            &pnp.neighborPropDelayThresh,
+                            &pnp.asCapable);
+               if (cnt != 2) {
+                       fprintf(stderr, "%s SET needs 2 values\n",
+                               idtab[index].name);
+                       break;
+               }
+               pmc_send_set_action(pmc, code, &pnp, sizeof(pnp));
+               break;
+       }
+}
+
+static void not_supported(struct pmc *pmc, int action, int index, char *str)
+{
+       fprintf(stdout, "sorry, %s not supported yet\n", idtab[index].name);
+}
+
+static void null_management(struct pmc *pmc, int action, int index, char *str)
+{
+       if (action == GET)
+               pmc_send_get_action(pmc, idtab[index].code);
+       else
+               puts("non-get actions still todo");
+}
+
+static int parse_action(char *s)
+{
+       int len = strlen(s);
+       if (0 == strncasecmp(s, "GET", len))
+               return GET;
+       else if (0 == strncasecmp(s, "SET", len))
+               return SET;
+       else if (0 == strncasecmp(s, "CMD", len))
+               return COMMAND;
+       else if (0 == strncasecmp(s, "COMMAND", len))
+               return COMMAND;
+       return BAD_ACTION;
+}
+
+static int parse_id(char *s)
+{
+       int i, index = BAD_ID, len = strlen(s);
+       /* check for exact match */
+       for (i = 0; i < ARRAY_SIZE(idtab); i++) {
+               if (strcasecmp(s, idtab[i].name) == 0) {
+                       return i;
+               }
+       }
+       /* look for a unique prefix match */
+       for (i = 0; i < ARRAY_SIZE(idtab); i++) {
+               if (0 == strncasecmp(s, idtab[i].name, len)) {
+                       if (index == BAD_ID)
+                               index = i;
+                       else
+                               return AMBIGUOUS_ID;
+               }
+       }
+       return index;
+}
+
+static int parse_target(struct pmc *pmc, const char *str)
+{
+       struct PortIdentity pid;
+
+       if (str[0] == '*') {
+               memset(&pid, 0xff, sizeof(pid));
+       } else if (str2pid(str, &pid)) {
+               return -1;
+       }
+
+       return pmc_target(pmc, &pid);
+}
+
+static void print_help(FILE *fp)
+{
+       int i;
+       fprintf(fp, "\n");
+       for (i = 0; i < ARRAY_SIZE(idtab); i++) {
+               if (idtab[i].func != not_supported)
+                       fprintf(fp, "\t[action] %s\n", idtab[i].name);
+       }
+       fprintf(fp, "\n");
+       fprintf(fp, "\tThe [action] can be GET, SET, CMD, or COMMAND\n");
+       fprintf(fp, "\tCommands are case insensitive and may be 
abbreviated.\n");
+       fprintf(fp, "\n");
+       fprintf(fp, "\tTARGET [portIdentity]\n");
+       fprintf(fp, "\tTARGET *\n");
+       fprintf(fp, "\n");
+}
+
 struct pmc {
        struct config *cfg;
        UInteger16 sequence_id;
@@ -360,3 +614,43 @@ void pmc_target_all(struct pmc *pmc)
 {
        memset(&pmc->target, 0xff, sizeof(pmc->target));
 }
+
+const char *pmc_action_string(int action)
+{
+       return action_string[action];
+}
+
+int pmc_do_command(struct pmc *pmc, char *str)
+{
+       int action, id;
+       char action_str[10+1] = {0}, id_str[64+1] = {0};
+
+       if (0 == strncasecmp(str, "HELP", strlen(str))) {
+               print_help(stdout);
+               return 0;
+       }
+
+       if (2 != sscanf(str, " %10s %64s", action_str, id_str))
+               return -1;
+
+       if (0 == strncasecmp(action_str, "TARGET", strlen(action_str)))
+               return parse_target(pmc, id_str);
+
+       action = parse_action(action_str);
+       id = parse_id(id_str);
+
+       if (action == BAD_ACTION || id == BAD_ID)
+               return -1;
+
+       if (id == AMBIGUOUS_ID) {
+               fprintf(stdout, "id %s is too ambiguous\n", id_str);
+               return 0;
+       }
+
+       fprintf(stdout, "sending: %s %s\n",
+               action_string[action], idtab[id].name);
+
+       idtab[id].func(pmc, action, id, str);
+
+       return 0;
+}
diff --git a/pmc_common.h b/pmc_common.h
index 4fc9428..9004a1a 100644
--- a/pmc_common.h
+++ b/pmc_common.h
@@ -25,6 +25,12 @@
 #include "msg.h"
 #include "transport.h"
 
+#define BAD_ACTION   -1
+#define BAD_ID       -1
+#define AMBIGUOUS_ID -2
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+#define P41 ((double)(1ULL << 41))
+
 struct pmc;
 
 struct pmc *pmc_create(struct config *cfg, enum transport_type transport_type,
@@ -45,4 +51,7 @@ int pmc_target(struct pmc *pmc, struct PortIdentity *pid);
 void pmc_target_port(struct pmc *pmc, UInteger16 portNumber);
 void pmc_target_all(struct pmc *pmc);
 
+const char *pmc_action_string(int action);
+int pmc_do_command(struct pmc *pmc, char *str);
+
 #endif
-- 
1.8.3.1


---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel

Reply via email to