A simple command line program to query and set properties. Usage
<programname>
Lists options, supported interfaces and detected devices
<programname> <device>
Lists all top level properties of the device
<programname> <device> <property_name>
Query specified Property with name 'property'. Children are displayed as well as its value, if applicable.
<programname> <device> <property> <value>
Set specified Property with name 'property' to value 'value'. Illegal values are caught.
#include <stdio.h> #include <stdlib.h> #include "devlib.h" #include "devlib_error.h" // PROTOS extern const char version_string[]; int list_children(DEVICE d, TOKEN t, int recursive); int print_type(DEVICE d, TOKEN t); int handleError(error) { const char *s; s = dcGetErrorString(error); if (error < 0) { printf("Error %d: %s\n", error, s); } else { printf("Warning %d: %s\n", error, s); } return error; } int list_children(DEVICE d, TOKEN t, int recursive) { int error; char propname[32]; DCValue val; TOKEN child; int i; error = dcProperty_Select(d, t, t, &child); while (error == 0) { val.type = DC_BUFFER; error = dcProperty_GetProto(d, child, &val); if (error < 0) { printf("failed to get Property prototype\n"); handleError(error); break; } val.value.p = (char *) propname; val.len = sizeof(propname); dcProperty_GetName(d, child, &val); // Use val.value.p rather than propname in next line, because // callee may have changed it (e.g. for static port descriptors) i = recursive; for (i = 0; i < recursive; i++) { printf(" "); } printf("Child: [%08x] '%s'\n", child, (char *) val.value.p); if (recursive) { list_children(d, child, recursive + 1); } error = dcProperty_Select(d, t, child, &child); // iterate to next if (error < 0) break; } return error; } static char *g_types[] = { "Invalid value", "ROOT NODE", "Integer", "Float", "Boolean", "Mode", "Register", "String", "Buffer", "{Struct}", "{Array}", "[Command]", "[Event]", "<unknown>" }; int print_type(DEVICE d, TOKEN t) { int error; DCValue v; unsigned short tp; int n = sizeof(g_types) / (sizeof(char *)); v.value.p = NULL; // do not query name error = dcProperty_GetProto(d, t, &v); if (error == 0) { tp = v.type; printf("Type : "); if (tp == DC_STRING || tp == DC_BUFFER) { printf("%s[%lu] [%c%c%c]\n", g_types[tp], v.len, (v.flags & F_WO) ? '.' : 'R', (v.flags & F_RO) ? '.' : 'W', (v.flags & F_VOLATILE) ? 'V' : '.'); } else { if (tp & DC_UNSIGNED) { printf("Unsigned "); } tp &= ~DC_UNSIGNED; if (tp >= n) tp = n-1; printf("%s [%c%c%c]\n", g_types[tp & 0xf], (v.flags & F_WO) ? '.' : 'R', (v.flags & F_RO) ? '.' : 'W', (v.flags & F_VOLATILE) ? 'V' : '.'); } } return error; } int value_as_string(DEVICE d, TOKEN p, char *str, int len) { int error; DCValue val; int warn = 0; char *buf; buf = (char *) malloc(len); if (!buf) return DCERR_MALLOC; val.value.p = buf; val.len = len; error = dcDevice_GetProperty(d, p, &val); if (error < 0) { if (error == DCERR_PROPERTY_SIZE_MATCH && ( val.type == DC_STRING || val.type == DC_BUFFER)) printf("Large buffer access not supported\n"); } else { warn = error; error = dcValue_ToString(&val, str, len); } free(buf); if (error < 0) return error; return warn; } int value_from_string(DEVICE d, TOKEN p, const char *str) { int error; DCValue val; error = dcProperty_GetProto(d, p, &val); if (error < 0) return error; error = DCERR_PROPERTY_HANDLER; switch (val.type) { case DC_BOOL: case DC_UINT: case DC_INT: case DC_COMMAND: if ( sscanf(str, "0x%lx", &val.value.i) == 1 || sscanf(str, "%ld", &val.value.i) == 1 ) { error = 0; } break; case DC_MODE: if (sscanf(str, "%ld", &val.value.i) == 1 ) { error = 0; } break; case DC_FLOAT: if (sscanf(str, "%f", &val.value.f)) { error = 0; } printf("Set: %f\n", val.value.f); break; case DC_STRING: val.value.p = (void *) str; val.len = strlen(str) + 1; error = 0; break; case DC_BUFFER: printf("Buffer size: %lu\n", val.len); break; default: printf("(YET) Unsupported data type\n"); } if (error == 0) { error = dcDevice_SetProperty(d, p, &val); } return error; } int proplist_crc(DEVICE d) { int error; DCValue val; error = dcDevice_GetProperty(d, TOKEN_CHECK, &val); if (error < 0) { printf("Peer does not have checksum feature\n"); } else { printf("Checksum: %04x\n", (unsigned short) val.value.i); } return 0; } int main(int argc, char **argv) { int error; char data[64]; TOKEN t, root; DCValue val; DEVICE d; if (argc < 2) { fprintf(stderr, "\nnetpp version %s\n", version_string); fprintf(stderr, "\nUsage: %s [<target>] [<property>] [<value>]\n", argv[0]); fprintf(stderr, " <target> : <hub>:<port> e.g. TCP:127.0.0.1:2008\n"); fprintf(stderr, " <property> : a property name\n"); fprintf(stderr, " <value> : a value. The format of the value must\n" " match its type, see below.\n\n"); fprintf(stderr, "Depending on the number of arguments passed, this test program\n" "has the following functionality:\n" "[0] Show usage and list available hubs/ports\n" "[1] Show property list of specified target\n" "[2] Get value of specified property\n" "[3] Set property to specified value\n\n"); printf("Available interfaces/hubs:\n"); list_children(DC_PORT_ROOT, INVALID_TOKEN, 1); return 0; } // open Device error = dcDeviceOpen(argv[1], &d); if (error < 0) { handleError(error); return -1; } error = dcDevice_GetRoot(d, &root); if (error < 0) { printf("Failed to get device root node\n"); handleError(error); goto abort; } error = proplist_crc(d); if (error < 0) { handleError(error); goto abort; } if (argc >= 3) { // Preinitialize, we don't know what we get in argv: t = INVALID_TOKEN; error = dcProperty_ParseName(d, argv[2], &t); if (error) { printf("Property not found or bad index\n"); goto abort; } else { error = print_type(d, t); if (error) handleError(error); } if (argc == 3) { error = list_children(d, t, 0); error = 0; if (!error) { error = value_as_string(d, t, data, 64); } if (error) { if (error == DCERR_PROPERTY_HANDLER) { printf("This property has no handler\n"); } else { handleError(error); } goto abort; } printf("Value: %s\n", data); } else if (argc == 4) { error = value_from_string(d, t, argv[3]); if (error) { handleError(error); goto abort; } } else { fprintf(stderr, "Wrong number of arguments\n"); } goto abort; } else { const char *name; error = dcDevice_GetHubName(d, &name); if (error < 0) { handleError(error); goto abort; } val.value.p = data; val.len = 32; dcProperty_GetName(d, root, &val); printf("Properties of Device '%s' associated with Hub '%s':\n", (char *) val.value.p, name); error = list_children(d, root, 0); if (error < 0) { handleError(error); goto abort; } } abort: dcDeviceClose(d); return 0; }