
This is our new RELEASE-4_0 branch which was taken from ansto/93d9a7c Conflicts: .gitignore SICSmain.c asynnet.c confvirtualmot.c counter.c devexec.c drive.c event.h exebuf.c exeman.c histmem.c interface.h motor.c motorlist.c motorsec.c multicounter.c napi.c napi.h napi4.c network.c nwatch.c nxscript.c nxxml.c nxxml.h ofac.c reflist.c scan.c sicshipadaba.c sicsobj.c site_ansto/docs/Copyright.txt site_ansto/instrument/lyrebird/config/tasmad/sicscommon/nxsupport.tcl site_ansto/instrument/lyrebird/config/tasmad/taspub_sics/tasscript.tcl statusfile.c tasdrive.c tasub.c tasub.h tasublib.c tasublib.h
480 lines
17 KiB
C
480 lines
17 KiB
C
/** @file
|
|
* Hipadaba is a hierarchical database of parameters. Parameters can be of
|
|
* various types. What happens when a parameter is being set, updated or read
|
|
* is largely determined through callbacks which can be registered on
|
|
* parameters. This can implement permission checking, range checking,
|
|
* automatic notifications and whatever comes up.
|
|
*
|
|
* There is some subtlety here between updating and setting a parameter. The
|
|
* issue is that in instrument control there are two types of parameters:
|
|
* Instant program parameters and external parameters like motors which are
|
|
* dependent on some possibly slow and inaccurate hardware. Let us consider
|
|
* the latter: Setting the parameter should do all necessary checks on the
|
|
* parameter and tell the hardware where to go. Some internal code may be
|
|
* watching the hardware; that code should use Update which justs sets a new value
|
|
* and invokes callbacks which notify interested parties about the new parameter
|
|
* value. For program parameters, a callback shall be installed which calls update
|
|
* directly after setting the parameter. Thus notification callbacks shall always be
|
|
* connected to the update chain.
|
|
*
|
|
* copyright: GPL
|
|
*
|
|
* Mark Koennecke, June 2006
|
|
*
|
|
* Added treeChange callback, Mark Koennecke, November 2006
|
|
*
|
|
* Added support for properties, Mark Koennecke, January 2007
|
|
*
|
|
* Refactored callback handling, Markus Zolliker, Mark Koennecke, March 2008
|
|
*
|
|
* Added property chnage events. Mark Koennecke, February 2015
|
|
*/
|
|
#ifndef HIPADABA
|
|
#define HIPADABA
|
|
#include <stringdict.h>
|
|
|
|
/*------- datatypes */
|
|
#define HIPNONE -1
|
|
#define HIPINT 0
|
|
#define HIPFLOAT 1
|
|
#define HIPTEXT 2
|
|
#define HIPINTAR 3
|
|
#define HIPFLOATAR 4
|
|
#define HIPINTVARAR 5
|
|
#define HIPFLOATVARAR 6
|
|
#define HIPOBJ 7
|
|
#define HIPFUNC 8
|
|
/*--------- error codes */
|
|
#define HDBTYPEMISMATCH -7701
|
|
#define HDBLENGTHMISMATCH -7702
|
|
/*===================== structure definitions ===================================*/
|
|
typedef void voidFunc(void);
|
|
|
|
typedef struct __hdbValue {
|
|
int dataType;
|
|
int arrayLength;
|
|
int doNotFree;
|
|
union __value {
|
|
int intValue;
|
|
double doubleValue;
|
|
char *text;
|
|
int *intArray;
|
|
double *floatArray;
|
|
voidFunc *func;
|
|
void *obj;
|
|
} v;
|
|
} hdbValue;
|
|
/*------------------------------------------------------------------------------*/
|
|
typedef struct __hipadaba {
|
|
int magic;
|
|
struct __hipadaba *mama;
|
|
struct __hipadaba *child;
|
|
struct __hipadaba *next;
|
|
struct __hdbcallback *callBackChain;
|
|
char *name;
|
|
char *path;
|
|
hdbValue value;
|
|
int iprotected;
|
|
pStringDict properties;
|
|
} Hdb, *pHdb;
|
|
/*-------------- return values for callback functions -------------------------*/
|
|
typedef enum {
|
|
hdbContinue,
|
|
hdbAbort,
|
|
hdbKill
|
|
} hdbCallbackReturn;
|
|
/*======================== Messages ===========================================*/
|
|
typedef struct __hdbMessage {
|
|
char *type;
|
|
} hdbMessage, *pHdbMessage;
|
|
/*-----------------------------------------------------------------------------*/
|
|
typedef struct {
|
|
char *type;
|
|
hdbValue *v;
|
|
void *callData;
|
|
} hdbDataMessage, *pHdbDataMessage;
|
|
/*-------------------------------------------------------------------------------*/
|
|
typedef struct {
|
|
char *type;
|
|
void *callData;
|
|
} hdbTreeChangeMessage, *pHdbTreeChangeMessage;
|
|
/*-------------------------------------------------------------------------------*/
|
|
typedef struct {
|
|
char *type;
|
|
void *testPtr;
|
|
void *result;
|
|
} hdbDataSearch, *pHdbDataSearch;
|
|
/*-------------------------------------------------------------------------------*/
|
|
typedef struct {
|
|
char *type;
|
|
char *key;
|
|
char *value;
|
|
} hdbPropertyChange, *pHdbPropertyChange;
|
|
/*-------------------------------------------------------------------------------*/
|
|
typedef hdbCallbackReturn(*hdbCallbackFunction) (pHdb currentNode,
|
|
void *userData,
|
|
pHdbMessage message);
|
|
|
|
typedef void (*killUserData) (void *data);
|
|
/*-------------------------------------------------------------------------------*/
|
|
typedef struct __hdbcallback {
|
|
void *userData;
|
|
killUserData killFunc;
|
|
hdbCallbackFunction userCallback;
|
|
int killFlag;
|
|
struct __hdbcallback *next;
|
|
struct __hdbcallback *previous;
|
|
} hdbCallback, *pHdbCallback;
|
|
/*============= Message Test Functions ==========================================*/
|
|
/**
|
|
* Test a message if it is a set message
|
|
* @param toTest The message to test.
|
|
* @return NULL if the message is no set message or a message pointer if it is.
|
|
*/
|
|
pHdbDataMessage GetHdbSetMessage(pHdbMessage toTest);
|
|
/**
|
|
* Test a message if it is a set message
|
|
* @param toTest The message to test.
|
|
* @return NULL if the message is no set message or a message pointer if it is.
|
|
*/
|
|
pHdbDataMessage GetHdbGetMessage(pHdbMessage toTest);
|
|
/**
|
|
* Test a message if it is a update message
|
|
* @param toTest The message to test.
|
|
* @return NULL if the message is no update message or a message pointer if
|
|
* it is.
|
|
*/
|
|
pHdbDataMessage GetHdbUpdateMessage(pHdbMessage toTest);
|
|
/**
|
|
* Test a message if it is a tree change message
|
|
* @param toTest The message to test.
|
|
* @return NULL if the message is no tree change message or a message
|
|
* pointer if it is.
|
|
*/
|
|
pHdbTreeChangeMessage GetHdbTreeChangeMessage(pHdbMessage toTest);
|
|
/**
|
|
* Test a message if it is a data search message
|
|
* @param toTest The message to test.
|
|
* @return NULL if the message is no data search message or a message
|
|
* pointer if it is.
|
|
*/
|
|
pHdbDataSearch GetHdbDataSearchMessage(pHdbMessage toTest);
|
|
/**
|
|
* Test a message if it is a kill node message
|
|
* @param toTest The message to test.
|
|
* @return NULL if the message is no kill node message or a message
|
|
* pointer if it is.
|
|
*/
|
|
pHdbMessage GetHdbKillNodeMessage(pHdbMessage toTest);
|
|
/**
|
|
* Test a message if it is a property change message
|
|
* @param toTest The message to test.
|
|
* @return NULL if the message is no property chnage message or a message
|
|
* pointer if it is.
|
|
*/
|
|
pHdbPropertyChange GetPropertyChangeMessage(pHdbMessage toTest);
|
|
|
|
/*======================== Function protoypes: hdbData ========================*/
|
|
/**
|
|
* make a hdbValue with the given datatype and length
|
|
* Do not initialise
|
|
* @param datatype The datatype of the hdbValue
|
|
* @param length The array length of the hdbValue
|
|
* @return a suitably defined hdbValue
|
|
*/
|
|
hdbValue makeHdbValue(int datatype, int length);
|
|
/**
|
|
* wrap an integer as an hdbValue
|
|
* @param initValue the initial value of the int
|
|
* @return: A properly initialized hdbValue structure
|
|
*/
|
|
hdbValue MakeHdbInt(int initValue);
|
|
/**
|
|
* wrap a float as an hdbValue
|
|
* @param initValue the initial value of the float
|
|
* @return: A properly initialized hdbValue structure
|
|
*/
|
|
hdbValue MakeHdbFloat(double initValue);
|
|
/**
|
|
* wrap a text string as an hdbValue
|
|
* @param initText the initial value of the text. WARNING: MakeHdbText does
|
|
* not copy the data. The Hdb code only copies data on updates. Normally this
|
|
* no problem; however in complicated cenarios it is better if initText points
|
|
* to dynamically allocated memory.
|
|
* @return: A properly initialized hdbValue structure
|
|
*/
|
|
hdbValue MakeHdbText(char *initText);
|
|
/**
|
|
* wrap a int array as an hdbValue
|
|
* @param length The length of the int array
|
|
* @param data the initial content of the int array. WARNING: MakeHdbIntArray
|
|
* does not copy the data. The Hdb code only copies data on updates. Normally
|
|
* this no problem; however in complicated scenarios it is better if
|
|
* data points to dynamically allocated memory.
|
|
* @return: A properly initialized hdbValue structure
|
|
*/
|
|
hdbValue MakeHdbIntArray(int length, int *data);
|
|
/**
|
|
* wrap a float array as an hdbValue
|
|
* @param length The length of the int array
|
|
* @param data the initial content of the float array. WARNING: MakeHdbFloatArray
|
|
* does not copy the data. The Hdb code only copies data on updates. Normally
|
|
* this no problem; however in complicated scenarios it is better if
|
|
* data points to dynamically allocated memory.
|
|
* @return: A properly initialized hdbValue structure
|
|
*/
|
|
hdbValue MakeHdbFloatArray(int length, double *data);
|
|
/**
|
|
* wrap a function as an hdbValue
|
|
* @param func the function
|
|
* @return: A properly initialized hdbValue structure
|
|
*/
|
|
hdbValue MakeHdbFunc(voidFunc * func);
|
|
/**
|
|
* wrap an object as an hdbValue
|
|
* @param obj the object
|
|
* @return: A properly initialized hdbValue structure
|
|
*/
|
|
hdbValue MakeHdbObj(void *obj);
|
|
/**
|
|
* release any dynamic memory associated with v
|
|
* @param v The hdbValue to check for dynamic memory allocation to be
|
|
* released.
|
|
*/
|
|
void ReleaseHdbValue(hdbValue * v);
|
|
/**
|
|
* copy a hipadaba value field. Takes care of memory allocation
|
|
* @param source The hdbValue to copy from
|
|
* @param target The hdbValue to copy to.
|
|
* @return 1 on success, 0 when out of memory or when type mismatch
|
|
*/
|
|
int copyHdbValue(hdbValue * source, hdbValue * target);
|
|
/**
|
|
* compares two hdbValues for identity
|
|
* @param v1 The first hdbValue
|
|
* @param v2 The second hdbValue
|
|
* @return 1 when identical, 0 else
|
|
*/
|
|
int compareHdbValue(hdbValue v1, hdbValue v2);
|
|
/**
|
|
* create a hdbValue structure with the identical properties
|
|
* as the one given as parameter. Datatypes are copied, memory is
|
|
* allocated etc. Data is copied, too
|
|
* @param source The hdbValue type to clone
|
|
* @param clone the target hdbValue structure
|
|
* @return 1 on success, 0 on when out of memory
|
|
*/
|
|
int cloneHdbValue(hdbValue * source, hdbValue * clone);
|
|
/**
|
|
* get the length of the hdbValue in bytes.
|
|
* @param v The hdbValue to calculate the length for
|
|
* @return the number of data bytes
|
|
*/
|
|
int getHdbValueLength(hdbValue v);
|
|
/**
|
|
* calculate a checksum of the data in val
|
|
* @param val The hdbValue to calcululate the checksum for
|
|
* @return The checksum
|
|
*/
|
|
unsigned short getHdbCheckSum(hdbValue *val);
|
|
/*========================== function protoypes: Nodes =======================*/
|
|
/**
|
|
* make a new hipadaba node
|
|
* @param name The name of the new node
|
|
* @param datatype The datatype of the new node
|
|
* @param length the array length
|
|
* @return a new node or NULL when out of memory
|
|
*/
|
|
pHdb MakeHipadabaNode(char *name, int datatype, int length);
|
|
/**
|
|
* add a child to a node at the end of the child list.
|
|
* @param parent The node to which to add the child
|
|
* @param child The node to add
|
|
* @param callData User data for the tree chnage callback. Can be NULL.
|
|
*/
|
|
void AddHipadabaChild(pHdb parent, pHdb child, void *callData);
|
|
/**
|
|
* Delete only the node data, without invoking any callbacks
|
|
* @param node The node to delete.
|
|
*/
|
|
void DeleteNodeData(pHdb node);
|
|
/**
|
|
* Send a treechange message for node.
|
|
* @param node The node whose child list has changed
|
|
* @param calldata The connection or calldata associated with this operation.
|
|
*/
|
|
void SendTreeChangeMessage(pHdb node, void *callData);
|
|
|
|
/**
|
|
* delete a hipadaba node and all its children. Then invoke the tree
|
|
* change callback to notify listeners.
|
|
* @param node The node to delete
|
|
* @param callData User data for the tree change callback
|
|
*/
|
|
void DeleteHipadabaNode(pHdb node, void *callData);
|
|
/*
|
|
* checks if a Hdb node is valid
|
|
* @param node The node to check
|
|
* @return 1 when valid, 0 else
|
|
*/
|
|
int isHdbNodeValid(pHdb node);
|
|
/**
|
|
* retrieve a node
|
|
* @param root The node where to start the search for the node
|
|
* @param path The unix path string for the node relative to parent
|
|
* @return The desired node or NULL when no such node exists
|
|
*/
|
|
pHdb GetHipadabaNode(pHdb root, char *path);
|
|
/**
|
|
* given a node, return the full path name to the node
|
|
* @param node The node to get the path for
|
|
* @return The full path to the node. This is dynamically allocated memory;
|
|
* the caller is reponsible for deleting it. Can be NULL when out of memory.
|
|
*/
|
|
char *GetHipadabaPath(pHdb node);
|
|
/**
|
|
* removes a node from the parents child list.
|
|
* @param node the node to remove
|
|
* @param callData User data for the tree change callback
|
|
*/
|
|
void RemoveHdbNodeFromParent(pHdb node, void *callData);
|
|
/**
|
|
* count the numbers of children in thie Hdb node
|
|
* @param node The node to count children for
|
|
* @return The number of children
|
|
*/
|
|
int CountHdbChildren(pHdb node);
|
|
/*===================== function protoypes: Callbacks ========================*/
|
|
/**
|
|
* make a new hipdaba callback
|
|
* @param func The function to invoke for this callback
|
|
* @param userData userData to be associated with this callback. Can be NULL.
|
|
* @param killFunc A function for freeing the userData. Can be NULL, then it will
|
|
* not be invoked
|
|
* @return A new suitabaly initialised callback structure or NULL when required elements
|
|
* are missing or there is nor memory.
|
|
*/
|
|
pHdbCallback MakeHipadabaCallback(hdbCallbackFunction func,
|
|
void *userData, killUserData killFunc);
|
|
/**
|
|
* add a callback at the end of the callback chain
|
|
* @param node The node to which to append the callback
|
|
* @param newCB The callback to append
|
|
*/
|
|
void AppendHipadabaCallback(pHdb node, pHdbCallback newCB);
|
|
/**
|
|
* add a callback at the head of the callback chain
|
|
* @param node The node to which to append the callback
|
|
* @param newCB The callback prepend
|
|
*/
|
|
void PrependHipadabaCallback(pHdb node, pHdbCallback newCB);
|
|
/**
|
|
* find the callback data
|
|
* @param node the node from where callbacks have to be searched
|
|
* @param userPtr A pointer to some user data which the callback
|
|
* uses to determine if it is the right one.
|
|
* @return the found callback user data or NULL on failure
|
|
*/
|
|
void *FindHdbCallbackData(pHdb node, void *userPtr);
|
|
/**
|
|
* invoke a callback chain.
|
|
* @param node The node reponsible for this callback chain
|
|
* @param message the message to send
|
|
* @return 1 on success, 0 on failure
|
|
*/
|
|
int InvokeCallbackChain(pHdb node, pHdbMessage message);
|
|
/**
|
|
* Deletes the callback chain of a node. This is internal, normal users
|
|
* should not use this function. Or you create a mess!
|
|
* @param node The node
|
|
*/
|
|
void DeleteCallbackChain(pHdb node);
|
|
/**
|
|
* apply message to the node and all its children
|
|
* @param node The node where to start recursing
|
|
* @param message The message to send
|
|
*/
|
|
void RecurseCallbackChains(pHdb node, pHdbMessage message);
|
|
/*============== Parameter Handling ===============================*/
|
|
/**
|
|
* Set a hipadaba parameter. This is an external set for a parameter. It may cause
|
|
* motors to start driving etc.
|
|
* @param node The node for which to set the parameter
|
|
* @param v The new value for the node
|
|
* @param callData Additonal context data to be passed to the callback functions
|
|
* @return 0 on failure, 1 on success
|
|
*/
|
|
int SetHipadabaPar(pHdb node, hdbValue v, void *callData);
|
|
/**
|
|
* Update a hipadaba parameter. This is an internal update of a parameter,
|
|
* during driving etc.
|
|
* @param node The node for which to update the parameter
|
|
* @param v The new value for the node
|
|
* @param callData Additonal context data to be passed to the callback functions
|
|
* @return 0 on failure, 1 on success
|
|
*/
|
|
int UpdateHipadabaPar(pHdb node, hdbValue v, void *callData);
|
|
/**
|
|
* notify any update listeners that this node has been internally modifed.
|
|
* @param node The node modified
|
|
* @param callData Addtional data for the callback
|
|
* @return 1 on success, 0 on failure
|
|
*/
|
|
int NotifyHipadabaPar(pHdb node, void *callData);
|
|
|
|
/**
|
|
* Read a hipadaba parameter
|
|
* @param node The node for which to read the parameter
|
|
* @param v The read value for the node
|
|
* @param callData Additonal context data to be passed to the callback functions
|
|
* @return 0 on failure, 1 on success
|
|
*/
|
|
int GetHipadabaPar(pHdb node, hdbValue * v, void *callData);
|
|
/*================================ Property Interface ==============================================*/
|
|
/**
|
|
* Set or delete a property
|
|
* @param node The node to set the property for
|
|
* @param key The key for the property
|
|
* @param value The value of the property. If this is NULL, the
|
|
* property is deleted.
|
|
*/
|
|
void SetHdbProperty(pHdb node, char *key, char *value);
|
|
/**
|
|
* get the value of a property
|
|
* @param node The node to get the property from
|
|
* @param key The properties key
|
|
* @param value The area to which to copy the property
|
|
* @param len The length of value
|
|
* @return 0 on failure, 1 on success
|
|
*/
|
|
/**
|
|
* Check if a property exists
|
|
* @param node The node to get the property from
|
|
* @param key The properties key
|
|
* @return 1 or 0 for true or false
|
|
*/
|
|
int HasHdbProperty(pHdb node, char *key);
|
|
int GetHdbProperty(pHdb node, char *key, char *value, int len);
|
|
/**
|
|
* get the value of a property
|
|
* @param node The node to get the property from
|
|
* @param key The properties key
|
|
* @return the property or NULL on failure. Warning: the string is
|
|
* only valid as long as the property has not changed
|
|
*/
|
|
char *GetHdbProp(pHdb node, char *key);
|
|
/**
|
|
* initialize a property scan on this node
|
|
* @param node The node for which to scan properties
|
|
*/
|
|
void InitHdbPropertySearch(pHdb node);
|
|
/**
|
|
* get the next property in a search
|
|
* @param node The node for which to search properties
|
|
* @param value An area where to copy the value of the property
|
|
* @param len The length of value
|
|
* @return The key of the property or NULL when the property list is exhausted
|
|
*/
|
|
const char *GetNextHdbProperty(pHdb node, char *value, int len);
|
|
#endif
|