master.c

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

Generated on Thu Feb 24 13:50:16 2011 for Device Control library by  doxygen 1.6.1