Example #1
0
/** function to generate a People "object" from a preferences description */
static NftResult _people_from_prefs(NftPrefs *p, void **newObj, NftPrefsNode *node, void *userptr)
{
        people.people_count = sizeof(persons)/sizeof(struct Person);

        /* call toObj() of child objects */
        NftPrefsNode *child;
        size_t i = 0;
        for(child = nft_prefs_node_get_first_child(node);
            child;
            child = nft_prefs_node_get_next(child))
        {
                if(i >= sizeof(persons)/sizeof(struct Person))
                {
                        NFT_LOG(L_ERROR, "more persons in prefs file than expected");
                        return NFT_FAILURE;
                }

                /* call toObj function of child node (should be a <person> node) */
                if(!(people.people[i++] = nft_prefs_obj_from_node(p, child, userptr)))
                {
                        NFT_LOG(L_ERROR, "Failed to create object from preference node");
                        return NFT_FAILURE;
                }
        }

        /* save pointer to new object */
        *newObj = &people;

        return NFT_SUCCESS;
}
Example #2
0
/**
 * register object class
 *
 * @param p NftPrefs context where new class should be registered to
 * @param className unique name of new class
 * @param toObj pointer to NftPrefsToObjFunc used by the new class
 * @param fromObj pointer to NftPrefsFromObjFunc used by the new class
 * @result NFT_SUCCESS or NFT_FAILURE
 */
NftResult nft_prefs_class_register(NftPrefs * p, const char *className,
                                   NftPrefsToObjFunc * toObj,
                                   NftPrefsFromObjFunc * fromObj)
{
        if(!p || !className)
                NFT_LOG_NULL(NFT_FAILURE);


        if(strlen(className) == 0)
        {
                NFT_LOG(L_ERROR, "class name may not be empty");
                return NFT_FAILURE;
        }

        /** check if class is already registered */
        NFT_LOG(L_DEBUG,
                "Checking if another class \"%s\" is already registered...",
                className);
        if(prefs_class_find_by_name(prefs_classes(p), className))
        {
                NFT_LOG(L_ERROR, "class named \"%s\" already registered",
                        className);
                return NFT_FAILURE;
        }

        /** allocate new slot in class array */
        NftArraySlot s;
        if(!(nft_array_slot_alloc(prefs_classes(p), &s)))
        {
                NFT_LOG(L_ERROR, "Failed to allocate new slot");
                return NFT_FAILURE;
        }

        /* get empty array element */
        NftPrefsClass *n;
        if(!(n = nft_array_get_element(prefs_classes(p), s)))
        {
                NFT_LOG(L_ERROR, "Failed to get element from array");
                goto _pcr_error;
        }

        /* register new class */
        strncpy(n->name, className, NFT_PREFS_MAX_CLASSNAME);
        n->toObj = toObj;
        n->fromObj = fromObj;
        n->slot = s;

        return NFT_SUCCESS;

_pcr_error:
        nft_array_slot_free(prefs_classes(p), s);
        return NFT_FAILURE;
}
Example #3
0
/** function to update a Person prefs-node from version 0 to version 1 */
NftResult _update_person(NftPrefsNode *node, unsigned int version, void *userptr)
{
		/* get "email" property from node */
		char *email;
		if(!(email = nft_prefs_node_prop_string_get(node, "email")))
		{
				NFT_LOG(L_ERROR,
				        "failed to get \"email\" property from node \"%s\"",
				        nft_prefs_node_get_name(node));
				return NFT_FAILURE;
		}

		/* function result */
		NftResult result = NFT_FAILURE;

		/* split "email" property into "email_user" and "email_host" */
		char *email_user = strtok(email, "@");
		char *email_host = strtok(NULL, "@");
		NFT_LOG(L_NOTICE, "Extracted email_host: \"%s\" and email_user: \"%s\"",
		       email_user, email_host);

		/* add new "email_user" property to node */
		if(!(nft_prefs_node_prop_string_set(node, "email_user", email_user)))
		{
				NFT_LOG(L_ERROR, "failed to set \"email_user\" property to \"%s\"",
				        email_user);

				goto _up_exit;
		}

		/* add new "email_user" property to node */
		if(!(nft_prefs_node_prop_string_set(node, "email_host", email_host)))
		{
				NFT_LOG(L_ERROR, "failed to set \"email_host\" property to \"%s\"",
				        email_host);
				goto _up_exit;
		}

		/* remove old "email" property */
		if(!(nft_prefs_node_prop_unset(node, "email")))
		{
				NFT_LOG(L_ERROR, "failed to remove \"email\" property from node.");
				goto _up_exit;
		}

		result = NFT_SUCCESS;

_up_exit:
		/* free string */
		nft_prefs_free(email);
		return result;
}
Example #4
0
/** function to generate a Person "object" from a preferences description */
static NftResult _person_from_prefs(NftPrefs *p, void **newObj, NftPrefsNode *node, void *userptr)
{
        static size_t i;

        /* only fill reserved space, not more */
        if(i >= sizeof(persons)/sizeof(struct Person))
                return NFT_FAILURE;

        char *name;
		if(!(name = nft_prefs_node_prop_string_get(node, "name")))
		{
				NFT_LOG(L_ERROR, "failed to get property \"name\" from prefs-node");
				return NFT_FAILURE;
		}

        char *email;
		if(!(email = nft_prefs_node_prop_string_get(node, "email")))
		{
				NFT_LOG(L_ERROR, "failed to get property \"email\" from prefs-node");
				return NFT_FAILURE;
		}

        int age;
        if(!nft_prefs_node_prop_int_get(node, "age", &age))
		{
				NFT_LOG(L_ERROR, "failed to get property \"age\" from prefs-node");
				return NFT_FAILURE;
		}

		bool alive;
		if(!nft_prefs_node_prop_boolean_get(node, "alive", &alive))
		{
				NFT_LOG(L_ERROR, "failed to get property \"alive\" from prefs-node");
				return NFT_FAILURE;
		}
		
        strncpy(persons[i].name, name, sizeof(persons[i].name));
        strncpy(persons[i].email, email, sizeof(persons[i].email));
        persons[i].age = age;
		persons[i].alive = alive;
		
        /* free strings */
        nft_prefs_free(name);
        nft_prefs_free(email);

        /* save pointer to new object */
        *newObj = &persons[i++];


        return NFT_SUCCESS;
}
Example #5
0
/**
 * create new NftPrefsNode from preferences file
 *
 * @param p NftPrefs context
 * @param filename full path of file
 * @result newly created NftPrefsNode or NULL
 */
NftPrefsNode *nft_prefs_node_from_file(NftPrefs *p, const char *filename)
{
        if(!filename)
                NFT_LOG_NULL(NULL);


        /* parse XML */
        xmlDocPtr doc;
        if(!(doc = xmlReadFile(filename, NULL, 0)))
        {
                NFT_LOG(L_ERROR, "Failed to xmlReadFile(\"%s\")", filename);
                return NULL;
        }

        /* parse XInclude stuff */
        int xinc_res;
        if((xinc_res = xmlXIncludeProcess(doc)) == -1)
        {
                NFT_LOG(L_ERROR, "XInclude parsing failed.");
                goto _npnff_error;
        }
        NFT_LOG(L_DEBUG, "%d XInclude substitutions done", xinc_res);


        /* get node */
        xmlNode *node;
        if(!(node = xmlDocGetRootElement(doc)))
        {
                NFT_LOG(L_ERROR, "No root element found in XML");
                goto _npnff_error;
        }

		/* update node */
		if(!_updater_node_process(p, node))
		{
				NFT_LOG(L_ERROR, "Preference update failed for node \"%s\". This is a fatal bug. Aborting.",
				        nft_prefs_node_get_name(node));
				goto _npnff_error;
		}

		/* return node */
        return node;


_npnff_error:
		xmlFreeDoc(doc);
        return NULL;
}
Example #6
0
/**
 * create preferences minimal buffer from NftPrefsNode - compared to
 * nft_prefs_node_to_buffer, this doesn't include any encapsulation or headers.
 * Just the bare information contained in the node. This should be used to
 * export single nodes, e.g. for copying them to a clipboard 
 *
 * @param p NftPrefs context  
 * @param n NftPrefsNode
 * @result string holding xml representation of object (use free() to deallocate)
 * @note s. @ref nft_prefs_node_to_file for description
 */
char *nft_prefs_node_to_buffer_minimal(NftPrefs *p, NftPrefsNode * n)
{
        if(!n)
                NFT_LOG_NULL(NULL);

        /* result pointer (xml dump) */
        char *dump = NULL;

        /* add prefs version to node */
        if(!(_updater_node_add_version(p, n)))
        {
                NFT_LOG(L_ERROR, "failed to add version to node \"%s\"",
                        nft_prefs_node_get_name(n));
                return NULL;
        }

        /* create buffer */
        xmlBufferPtr buf;
        if(!(buf = xmlBufferCreate()))
        {
                NFT_LOG(L_ERROR, "failed to xmlBufferCreate()");
                return NULL;
        }

        /* dump node */
        if(xmlNodeDump(buf, n->doc, n, 0, true) < 0)
        {
                NFT_LOG(L_ERROR, "xmlNodeDump() failed");
                goto _pntb_exit;
        }

        /* allocate buffer */
        size_t length = xmlBufferLength(buf);
        if(!(dump = malloc(length + 1)))
        {
                NFT_LOG_PERROR("malloc()");
                goto _pntb_exit;
        }

        /* copy buffer */
        strncpy(dump, (char *) xmlBufferContent(buf), length);
        dump[length] = '\0';

_pntb_exit:
        xmlBufferFree(buf);

        return dump;
}
Example #7
0
/**
 * called upon plugin load
 */
static NftResult _init(void **privdata, LedHardware * h)
{
        NFT_LOG(L_INFO, "Initializing plugin...");


        /* allocate private structure */
        struct priv *p;
        if(!(p = calloc(1, sizeof(struct priv))))
        {
                NFT_LOG_PERROR("calloc");
                return NFT_FAILURE;
        }


        /* register our config-structure */
        *privdata = p;

        /* save our hardware descriptor */
        p->hw = h;





        // ~ /* register dynamic property for artnet address */
        // ~ if(!led_hardware_plugin_prop_register(h, "address",
        // LED_HW_CUSTOM_PROP_STRING))
        // ~ return NFT_FAILURE;
        // ~ /* register dynamic property for artnet port / universe */
        // ~ if(!led_hardware_plugin_prop_register(h, "port",
        // LED_HW_CUSTOM_PROP_INT))
        // ~ return NFT_FAILURE;

        return NFT_SUCCESS;
}
Example #8
0
/**
 * capture image
 */
static NftResult _capture(LedFrame *frame, LedFrameCord x, LedFrameCord y)
{
        if(!frame)
                NFT_LOG_NULL(NFT_FAILURE);


        /* get screen-portion from X server */
        XImage *image = NULL;
        if(!(image = XGetImage(_c.display, RootWindow(_c.display, _c.screen),
                       x, y,
                       led_frame_get_width(frame), led_frame_get_height(frame),
                       AllPlanes, ZPixmap)))
        {
                NFT_LOG(L_ERROR, "XGetImage() failed");
                return NFT_FAILURE;
        }

        /* copy framebuffer */
        memcpy(led_frame_get_buffer(frame), image->data, led_frame_get_buffersize(frame));

        /* destroy images */
        XDestroyImage(image);
        
        return NFT_SUCCESS;
}
Example #9
0
/**
 * plugin getter - this will be called if core wants to get stuff
 */
NftResult _get_handler(void *privdata, LedPluginParam o,
                       LedPluginParamData * data)
{
        Niftylino *n = privdata;

        /** decide about object to give back to the core (s. hardware.h) */
        switch (o)
        {
                case LED_HW_ID:
                {
                        data->id = n->id;
                        return NFT_SUCCESS;
                }

                case LED_HW_LEDCOUNT:
                {
                        data->ledcount = n->ledcount;
                        return NFT_SUCCESS;
                }

                default:
                {
                        NFT_LOG(L_ERROR,
                                "Request to get unhandled object from plugin");
                        return NFT_FAILURE;
                }
        }

        return NFT_FAILURE;
}
Example #10
0
/**
 * determine format that ImageMagick should provide
 */
NftResult im_format(struct Ledcat *c, LedPixelFormat *format)
{
#if HAVE_IMAGEMAGICK == 1

    /* determine map format for MagickGetImagePixels */
    strncpy(c->map, led_pixel_format_colorspace_to_string(format), sizeof(c->map));

    /* determine storage format for MagickGetImagePixels */
    char type[16];
    strncpy(type, led_pixel_format_get_component_type(format, 0), sizeof(type));
    if(strncmp(type, "u8", sizeof(type)) == 0)
        c->storage = CharPixel;
    else if(strncmp(type, "u16", sizeof(type)) == 0)
        c->storage = ShortPixel;
    else if(strncmp(type, "u32", sizeof(type)) == 0)
        c->storage = IntegerPixel;
    else if(strncmp(type, "u64", sizeof(type)) == 0)
        c->storage = LongPixel;
    else if(strncmp(type, "double", sizeof(type)) == 0)
        c->storage = DoublePixel;
    else if(strncmp(type, "float", sizeof(type)) == 0)
        c->storage = FloatPixel;
    else
    {
        NFT_LOG(L_ERROR, "Unhandled pixel-format: \"%s\"", type);
        return FALSE;
    }
#endif

    return TRUE;
}
Example #11
0
/** menuitem "save" selected */
G_MODULE_EXPORT void on_action_setup_save_activate(GtkAction * a, gpointer u)
{
        if(!ui_setup_save(NULL))
        {
                NFT_LOG(L_ERROR, "Error while saving current setup.");
                return;
        }
}
/**
 * trigger hardware to show data
 *
 * - if you previously uploaded your data to your hardware, output it now to LEDs
 * - if you can't do this, try to send all data except last bit/value/... in 
 *   _send() so that sent data is not immediately visible. Then send last portion here
 * - if you can't do this, send all data here as quick as possible :)
 */
NftResult _show(void *privdata)
{
        NFT_LOG(L_DEBUG, "Showing arduino-max72xx data");

        struct priv *p = privdata;

        ad_latch(p);

        return NFT_SUCCESS;
}
Example #13
0
/**
 * deinitialize hardware
 */
static void _spi_deinit(void *privdata)
{
        NFT_LOG(L_DEBUG, "Deinitializing LDP8806 hardware");

        struct priv *p = privdata;

        close(p->fd);

        /* free buffer */
        // free(p->txBuffer);
}
Example #14
0
/**
 * ImageMagick error-handler
 */
void im_error(MagickWand *wand)
{
#if HAVE_IMAGEMAGICK == 1
    char *description;
    ExceptionType  severity;

    description = MagickGetException(wand, &severity);
    NFT_LOG(L_ERROR, "%s %s %lu %s\n", GetMagickModule(), description);
    description = (char *) MagickRelinquishMemory(description);
#endif
}
Example #15
0
/**
 * trigger hardware to show data
 *
 * - if you previously uploaded your data to your hardware, output it now to LEDs
 * - if you can't do this, try to send all data except last bit/value/... in 
 *   _send() so that sent data is not immediately visible. Then send last portion here
 * - if you can't do this, send all data here as quick as possible :)
 */
NftResult _show(void *privdata)
{
        NFT_LOG(L_DEBUG, "Showing LDP8806 data");

        struct priv *p = privdata;

        /* send zero byte to latch */
        uint8_t latch = 0;

        return spiTxData(p->fd, &latch, 1);
}
Example #16
0
/**
 * plugin setter - this will be called if core wants to set stuff
 */
NftResult _set_handler(void *privdata, LedPluginParam o,
                       LedPluginParamData * data)
{
        Niftylino *n = privdata;

        /** decide about type of data (s. hardware.h) */
        switch (o)
        {
                case LED_HW_GAIN:
                {
                        return _set_gain(n, data->gain.pos, data->gain.value);
                }

                case LED_HW_ID:
                {
                        NFT_LOG(L_DEBUG, "Setting \"%s\" ID: %s",
                                led_hardware_get_name(n->hw), data->id);
                        strncpy(n->id, data->id, sizeof(n->id));
                        return NFT_SUCCESS;
                }

                case LED_HW_LEDCOUNT:
                {
                        NFT_LOG(L_DEBUG, "Setting \"%s\" to ledcount: %d",
                                led_hardware_get_name(n->hw), data->ledcount);
                        if(!_set_ledcount(n, data->ledcount))
                                return NFT_FAILURE;

                        n->ledcount = data->ledcount;
                        return NFT_SUCCESS;
                }

                default:
                {
                        return NFT_SUCCESS;
                }
        }

        return NFT_FAILURE;
}
Example #17
0
/**
 * called upon plugin unload. Hardware will be deinitialized before that.
 * 
 * You should:
 * - unregister all properties you registered before 
 * - finally free all resources you needed 
 *
 */
static void _deinit(void *privdata)
{
        NFT_LOG(L_DEBUG, "Deinitializing LDP8806 plugin...");

        struct priv *p = privdata;

        /* unregister or settings-handlers */
        led_hardware_plugin_prop_unregister(p->hw, "spi_speed");
        led_hardware_plugin_prop_unregister(p->hw, "spi_delay");

        /* free structure we allocated in _init() */
        free(privdata);
}
Example #18
0
/**
 * called upon plugin unload. Hardware will be deinitialized before that.
 */
static void _deinit(void *privdata)
{
        NFT_LOG(L_INFO, "Deinitializing plugin...");

        // struct priv *p = privdata;

        /* unregister dynamic properties */
        // ~ led_hardware_plugin_prop_unregister(p->hw, "address");
        // ~ led_hardware_plugin_prop_unregister(p->hw, "port");

        /** free structure we allocated in _init() */
        free(privdata);
}
/**
 * deinitialize hardware
 */
static void _hw_deinit(void *privdata)
{
        NFT_LOG(L_DEBUG, "Deinitializing arduino-max72xx hardware");

        struct priv *p = privdata;

        /* restore old serial port settings */
        tcflush(p->fd, TCIFLUSH);
        tcsetattr(p->fd, TCSANOW, &p->oldtio);

        /* close serial port */
        close(p->fd);
}
Example #20
0
/** find class by name */
NftPrefsClass *prefs_class_find_by_name(NftPrefsClasses * c, const char *name)
{
        /* find class in array */
        NftArraySlot slot;
        if(!nft_array_find_slot
           (c, &slot, _class_find_by_name, (void *) name, NULL))
        {
                NFT_LOG(L_DEBUG, "Class \"%s\" not found", name);
                return NULL;
        }

        return nft_array_get_element(c, slot);
}
Example #21
0
/** "save" button in filechooser clicked */
G_MODULE_EXPORT void on_setup_save_save_clicked(GtkButton * b, gpointer u)
{
        char *filename;
        if(!(filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER
                                                      (_ui
                                                       ("filechooserdialog_save")))))
        {
                NFT_LOG(L_ERROR, "No filename received from dialog.");
                return;
        }

        if(!ui_setup_save(filename))
        {
                NFT_LOG(L_ERROR, "Error while saving file \"%s\"", filename);
                goto osssc_exit;
        }

        gtk_widget_hide(GTK_WIDGET(_ui("filechooserdialog_save")));

osssc_exit:
        g_free(filename);
}
Example #22
0
/**
 * get URI of document this node was parsed from (or NULL)
 *
 * @result URI of node origin or NULL if unset 
 */
const char *nft_prefs_node_get_uri(NftPrefsNode * n)
{
        if(!n)
                NFT_LOG_NULL(NULL);

		if(!n->doc)
		{
				NFT_LOG(L_DEBUG, "node \"%s\" has no uri set.",
				        nft_prefs_node_get_name(n));
				return NULL;
		}
	
        return (const char *) n->doc->URL;
}
/**
 * send data in chain to hardware (only use this if hardware doesn't show data right after
 * data is received to avoid blanking. If the data is shown immediately, you have
 * to transmit it in _show() 
 */
NftResult _send(void *privdata, LedChain * c, LedCount count, LedCount offset)
{
        NFT_LOG(L_DEBUG, "Sending arduino-max72xx data");

        struct priv *p = privdata;

        /* 8 bits-per-pixel buffer as given by niftyled */
        unsigned char *buffer = led_chain_get_buffer(c);
        /* 1 bit-per-pixel buffer as needed by arduino */
        unsigned char packed[64];

        /* clear buffer */
        memset(packed, 0, sizeof(packed));

        /* convert to 8bpp to 1bpp */
        LedCount i;
        for(i = 0; i < p->ledcount; i++)
        {
                packed[i / 8] = packed[i / 8] << 1;

                if(buffer[i] >= p->threshold)
                        packed[i / 8] |= 1;
        }


        NFT_LOG(L_NOISY, "Packed buffer: %x %x %x %x %x %x %x %x",
                packed[0], packed[1], packed[2], packed[3],
                packed[4], packed[5], packed[6], packed[7]);


        /* send buffer */
        ad_sendBuffer(p, packed,
                      (p->ledcount % 8 ==
                       0 ? p->ledcount / 8 : p->ledcount / 8 + 1));

        return NFT_SUCCESS;
}
Example #24
0
/**
 * initialize hardware
 */
static NftResult _hw_init(void *privdata, const char *id)
{
        NFT_LOG(L_DEBUG, "Initializing dummy hardware");

        // ~ struct priv *p = privdata;

        // ~ /* ... do checks ... */



        // ~ /* copy our id (and/or change it; check for "*" wildcard) */
        // ~ strncpy(p->id, id, sizeof(p->id));

        return NFT_SUCCESS;
}
Example #25
0
/** New setup */
G_MODULE_EXPORT void on_action_setup_new_activate(GtkAction * a, gpointer u)
{
        LedSetup *s;
        if(!(s = led_setup_new()))
        {
                NFT_LOG(L_ERROR, "Failed to create new settings descriptor.");
                return;
        }

        /* save new settings */
        setup_register_to_gui(s);
        setup_set_current_filename("Unnamed.xml");
        ui_setup_tree_clear();
        ui_renderer_all_queue_draw();
}
Example #26
0
/**
 * check if NftArraySlot is plausible
 *
 * @param a NftArray descriptor
 * @param s NftArraySlot
 * @result TRUE if slot is plausible, FALSE otherwise
 */
static bool _slot_is_valid(NftArray * a, NftArraySlot s)
{
        if(!a)
                NFT_LOG_NULL(FALSE);

        if(s >= a->arraysize)
        {
                NFT_LOG(L_ERROR,
                        "requested slot %d from array \"%s\" that only has %d slots",
                        s + 1, nft_array_get_name(a), a->arraysize);
                return FALSE;
        }

        return TRUE;
}
Example #27
0
/**
 * send data in chain to hardware (only use this if hardware doesn't show data right after
 * data is received to avoid blanking. If the data is shown immediately, you have
 * to transmit it in _show() 
 */
NftResult _send(void *privdata, LedChain * c, LedCount count, LedCount offset)
{
        NFT_LOG(L_DEBUG, "Sending LDP8806 data");

        struct priv *p = privdata;
        uint8_t *buf = led_chain_get_buffer(c);

        /* seek to offset */
        int bytes_per_component =
                led_chain_get_buffer_size(c) / led_chain_get_ledcount(c);
        buf += offset * bytes_per_component;

        /* send buffer */
        return spiTxData(p->fd, buf, bytes_per_component * count);
}
/**
 * called upon plugin unload. Hardware will be deinitialized before that.
 * 
 * You should:
 * - unregister all properties you registered before 
 * - finally free all resources you needed 
 *
 */
static void _deinit(void *privdata)
{
        NFT_LOG(L_DEBUG, "Deinitializing arduino-max72xx plugin...");

        struct priv *p = privdata;

        /* unregister or settings-handlers */
        led_hardware_plugin_prop_unregister(p->hw, "threshold");
        led_hardware_plugin_prop_unregister(p->hw, "scan_limit");

        /* free buffer */
        free(p->buffer);

        /* free structure we allocated in _init() */
        free(privdata);
}
Example #29
0
/**
 * generate LedChain from LedPrefsNode
 *
 * @param p LedPrefs context
 * @param n LedPrefsNode 
 * @result newly created LedChain
 */
LedChain *led_prefs_chain_from_node(LedPrefs * p, LedPrefsNode * n)
{
        if(!p || !n)
                NFT_LOG_NULL(NULL);

        /* check if node is of expected class */
        if(!led_prefs_is_chain_node(n))
        {
                NFT_LOG(L_ERROR,
                        "got wrong LedPrefsNode class. Expected \"%s\" but got \"%s\"",
                        LED_CHAIN_NAME, nft_prefs_node_get_name(n));
                return NULL;
        }

        return nft_prefs_obj_from_node(p, n, NULL);
}
Example #30
0
/**
 * generate LedHardware from LedPrefsNode
 *
 * @param p LedPrefs context
 * @param n LedPrefsNode
 * @result newly created LedHardware
 */
LedHardware *led_prefs_hardware_from_node(LedPrefs * p, LedPrefsNode * n)
{
        if(!p || !n)
                NFT_LOG_NULL(NULL);

        /* check if node is of expected class */
        if(strcmp(nft_prefs_node_get_name(n), LED_HARDWARE_NAME) != 0)
        {
                NFT_LOG(L_ERROR,
                        "got wrong LedPrefsNode class. Expected \"%s\" but got \"%s\"",
                        LED_HARDWARE_NAME, nft_prefs_node_get_name(n));
                return NULL;
        }

        return nft_prefs_obj_from_node(p, n, NULL);
}