Code from pmc.c will be reused by new snmpd.c in later commit.
Signed-off-by: Anders Selhammer <[email protected]>
---
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 6f23167..35b1d96 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,
@@ -881,7 +586,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 fcb9c8e..0246fea 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 {
UInteger16 sequence_id;
UInteger8 boundary_hops;
@@ -359,3 +613,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 bb3a1f1..b1fdcd6 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,
@@ -46,4 +52,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
[email protected]
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel