/** @file * This is a set of helper functions for SICS to work with the hierarchical parameter * database hipadaba. In SICS, the calldata associated with any callback will always * be the connection object. * * copyright: GPL * * Mark Koennecke, June 2006 */ #ifndef SICSHIPADABA_H_ #define SICSHIPADABA_H_ #include #include #include #include #define MAX_HDB_PATH 1024 /*======================== callback error codes ===============================*/ #define SICSCBRO -607 #define SICSCBPERM -608 #define SICSCBRANGE -609 #define SICSCBBADFIXED -610 #define SICSNOPAR -611 /*======================== SICS Messages ======================================*/ typedef struct { char *type; int ID; } hdbIDMessage, *pHdbIDMessage; /*------------------------------------------------------------------------------*/ pHdbIDMessage GetKillIDMessage(pHdbMessage message); pHdbIDMessage GetKillInternalIDMessage(pHdbMessage message); /*-----------------------------------------------------------------------------*/ typedef struct { char *type; void *pPtr; } hdbPtrMessage, *pHdbPtrMessage; /*-----------------------------------------------------------------------------*/ pHdbPtrMessage GetKillPtrMessage(pHdbMessage message); pHdbMessage GetHdbStartMessage(pHdbMessage message); pHdbMessage GetHdbStopMessage(pHdbMessage message); void SendHdbStatusMessage(pHdb node, char *status); /*======================== data structure for automatic parameter update =======*/ typedef struct { SConnection *pCon; int updateList; int iEnd; } hdbUpdateTask, *pHdbUpdateTask; /*======================== common callbacks =====================================*/ /** * make a ReadOnly callback * @return a callback which disallows setting of a parameter. */ pHdbCallback MakeReadOnlyCallback(); /** * make a callback which checks permissions. To be used on write * @param priv The privilege to check against * @return a suitably initialized callback structure for * checking permissions. */ pHdbCallback MakeCheckPermissionCallback(int priv); /** * make a callback which directly updates a * paramter after setting. Useful for program parameters. * @return a suitably initialized callback structure setting * program parameters */ pHdbCallback MakeSetUpdateCallback(); /** * Remove a SetUpdate callback. This is useful for chaning the * behaviour of a node created with the hmake command * @param node the node */ void RemoveSetUpdateCallback(pHdb node); /** * make a callback which starts a parameter driving. * @param sicsObject The SICS object to drive. * @return a suitably initialized callback structure for * starting a parameter driving. */ pHdbCallback MakeSICSDriveCallback(void *sicsObject); /** * make a callback which reads a SICS drivable object * @param sicsObject The SICS drivable object to read. * @return a suitably initialized callback structure for * reading a drivable parameter */ pHdbCallback MakeSICSReadDriveCallback(void *sicsObject); /** * make a callback which enables automatically * notification of pCon on parameter updates. * @param pCon The connection to notify. The notification * is issued in the context of this connection. * @param id An integer id which can later on be used to remove the * callback. * @return a suitably initialized callback structure for * automatic notification. */ pHdbCallback MakeNotifyCallback(SConnection * pCon, int id); /** * make a callback for checking if a parameter is within a given * range of integers * @param min The minimum value of the range * @param max The maximum value of the range * @return a suitably configured callback or NULL * when out of memory */ pHdbCallback MakeIntRangeCallback(int min, int max); /** * make a callback for checking if a parameter is one out * of a series of permitted integers * @param data An array of permitted integers * @param length The length of the data array. * @return a suitably configured callback or NULL * when out of memory */ pHdbCallback MakeIntFixedCallback(int *data, int length); /** * make a callback for checking if a parameter is within a given * range of floats * @param min The minimum value of the range * @param max The maximum value of the range * @return a suitably configured callback or NULL * when out of memory */ pHdbCallback MakeFloatRangeCallback(double min, double max); /** * make a callback which reads a memory address (perhaps in a * data structure) which is a float value * @param address The address of the parameter * @return a suitable callback for reading this parameter. */ pHdbCallback MakeMemReadCallback(float *address); /** * make a callback which sets a memory address (perhaps in a * data structure) which is a float value. It is assumed that * this is a direct parameter, i.e, UpdateHipadabaPar is * automatically called. * @param address The address of the parameter * @return a suitable callback for setting this parameter. */ pHdbCallback MakeMemSetCallback(float *address); /** * make a tree chnage callback * @param pCon The connection to notfy on tree chnages * @param id The ID of this callback * @return a suitable callback for notififications about tree changes. */ pHdbCallback MakeTreeChangeCallback(SConnection * pCon, int id); /** * make a clalback to invoke a function node */ pHdbCallback MakeSICSFuncCallback(void *obj); /** * callback for checking node values against the values property * @param node The node to for which this callback has been called * @param userData userData associated with this callback. NULL expected * @param message The message sent to the node */ hdbCallbackReturn SICSValueCheckCallback(pHdb node, void *userData, pHdbMessage message); /*======================== parameter creation ===================================*/ /** * make a simple SICS hdb parameter. Setting it will call update immediately. Use * this for program parameters. * @param name The name of the parameter * @param priv The privilege required to change that parameter * @param v The initial value and datatype of this parameter * @return A new suitably configured Hdb parameter or NULL when out of memory. */ pHdb MakeSICSHdbPar(char *name, int priv, hdbValue v); /** * make a SICS hdb drivable parameter. Setting it will start the motor, * virtual motor or environment parameter. This will call StartDevice * eventually * @param name The name of the parameter * @param priv The privilege required to change that parameter * @param sicsObject The object corresponding to this parameter. * @param datatype The datatype of this variable * @return A new suitably configured Hdb parameter or NULL when out of memory. */ pHdb MakeSICSHdbDriv(char *name, int priv, void *sicsObject, int datatype); /** * make SICS hdb variable which is connected to a memory location, perhaps in * an objects data structure. * @param name The name of the variable * @param priv The privilege required to set this parameter * @param address A pointer to the memory location of the variable. */ pHdb MakeSICSMemPar(char *name, int priv, float *address); /** * makes a SICS Hdb read only parameter. Setting such a parameter causes an error. * @param name The name of the parameter * @param v The initial value and datatype of this parameter * @return A new suitably configured Hdb parameter or NULL when out of memory. */ pHdb MakeSICSROPar(char *name, hdbValue v); /** * make a SICS scriptable parameter. I.e. when this parameter is set or read, * appropriate scripts are invoked. * @param name The name of the parameter * @param setScript The script to call when this parameter is being set * @param readScript The script to call when this parameter is being read. * @param v The initial value and datatype of this parameter * @return A new suitably configured Hdb parameter or NULL when out of memory. */ pHdb MakeSICSScriptPar(char *name, char *setScript, char *readScript, hdbValue v); /** * remove a SICS paramameter node and its children. In contrast to the * normal DeletHipadabaNode, this function also takes care of * clearing scipted nodes out of the update tasks watch list. * @param node The node to delete * @param callData User data for the tree change callback */ void RemoveSICSPar(pHdb node, void *callData); /*=============== Add par functions =======================================*/ /** * add a new simple hdb parameter as child to node * @param parent The parent node to add the new node to. * @param name The name of the new node * @param priv The privilege required to change that parameter * @param v The initial value and datatype of this parameter * @return the created node on success, NULL else */ pHdb AddSICSHdbPar(pHdb parent, char *name, int priv, hdbValue v); /** * add a new read only hdb parameter as child to node * @param parent The parent node to add the new node to. * @param name The name of the new node * @param v The initial value and datatype of this parameter * @return the created node on success, NULL else */ pHdb AddSICSHdbROPar(pHdb parent, char *name, hdbValue v); /** * Add a new hdb parameter as child to node. Updates are synced * to the memory location data. This works for simple variables, fixed size * arrays and fixed sized strings. This does not work for dynamically sized * arrays or strings. * @param parent The parent node to add the new node to. * @param name The name of the new node * @param priv The privilege required to change that parameter * @param data The pointer to map this parameter to. This must be in * dynamically allocated memory. * @param datalength The length of the data area pointed to by data. * @param type The data type of the parameter * @param length The length of the type. Used for array types. * @return the created node on success, NULL else */ pHdb AddSICSHdbMemPar(pHdb parent, char *name, int priv, void *data, int datalength, int type, int length); /*============== access support functions =================================*/ /** Find the parent of a node to be created * @param rootpath the root path (where to start). May be NULL for absolute paths * @param relpath an absolute or relative path * @param namePtr (output) a pointer to a name. Will be the last element of * the path if the parent was found. If namePtr is NULL, the routine does * the same as FindHdbNode(root, relpath, pCon) * @param pCon a connection for writing the error messages (may be NULL) * @return the parent node or NULL on failure * * An abolute path starts with a slash, else it is a relative path. * If the node exists already, an error message is emitted (node exists already) * and NULL is returned. * * Nodes anchored in the sics object list are also found when * the path starts with "/sics/" */ pHdb FindHdbParent(char *rootpath, char *relpath, char **namePtr, SConnection * pCon); /** FindHdbNode finds a node * @param rootpath the root path (where to start). May be NULL for absolute paths. * @param relpath an absolute or relative path * @param pCon a connection for writing the error messages (may be NULL) * @return the found node or NULL on failure * * An abolute path starts with a slash, else it is a relative path. * If relpath if a single dot ('.') root is returned. * * Nodes anchored in the sics object list are also found when * the path starts with "/sics/" */ pHdb FindHdbNode(char *rootpath, char *relpath, SConnection * pCon); /** FindHdbIntern finds a node. It does so without complaining * on the various bits which can fail. It is for internal use where the caller * deals with the absence of the desired node. * @param path the path to search. Paths starting /sics/are searched for in the object database * @return the found node or NULL on failure */ pHdb FindHdbIntern(char *path); /** Get the absolute path of a node anchored in the * Hipadaba root or in a sics object * @param nodeArg the input node * @param path the result * @param pathlen length of the result * @return 1 on success, 0 on failure */ int GetHdbPath(pHdb nodeArg, char *path, size_t pathlen); /** Remove all Callbacks rooted in the main root _and_ in sics objects * @param internalID the internalID to be looked for */ void RemoveSICSInternalCallback(void *internalID); /** Remove all Callbacks rooted in the node * @param internalID the internalID to be looked for */ void RemoveSICSInternalCallbackFrom(pHdb node, void *internalID); /** * SICSHdbGetPar returns the value of a parameter. * @param obj The object for which to get a parameter. * @param pCon The optional connection object to use for reporting errors. * @param path The path to the parameter. * @param v the value * @return 1 on success, a negative error code else. */ int SICSHdbGetPar(void *obj, SConnection * pCon, char *path, hdbValue * v); /** * SICSHdbUpdatePar updates the value of a parameter. * @param obj The object for which to get a parameter. * @param pCon The optional connection object to use for reporting errors. * @param path The path to the parameter. * @param v the value * @return 1 on success, a negative error code else. */ int SICSHdbUpdatePar(void *obj, SConnection * pCon, char *path, hdbValue v); /** * SICSHdbSetPar sets the value of a parameter. * @param obj The object for which to set a parameter. * @param pCon The optional connection object to use for reporting errors. * @param path The path to the parameter. * @param v the value * @return positive on success, a negative error code else. */ int SICSHdbSetPar(void *obj, SConnection * pCon, char *path, hdbValue v); /** * query function if a parameter is read only. * @param node The ndoe to query * @return 1 when RO, 0 else */ int isSICSHdbRO(pHdb node); /*============= common SICS Interactions ===================================*/ /** * Install a SICS automatic notification callback on the node. This is * a default callback using the current connection with its current * context for notification. * @param node The parameter on which to install the callback * @param pCon The connection to which this callback is linked. * @param id An int associated with this notification callback. A * precaution for later removal. * @param recurse a flag 0 or 1 which determines if callbacks are * installed to all nodes recursively. * @return 1 on success, 0 when out of memory. */ int InstallSICSNotify(pHdb node, SConnection * pCon, int id, int recurse); /** * remove all Callbacks associated with a given conenction * @param root Where to start removing callbacks * @param pCon The connection for which to remove callbacks */ void RemoveConnectionCallbacks(pHdb root, SConnection * pCon); /** * handles the common task of checking for, and processing a SICS parameter. * @param root The node at which to search for parameters * @param pCon The connection in whichs context the parameter is processed. * @param printPrefix A prefix to prepend before printing this parameter. * Will be ignored if NULL. * @param argc number of arguments to process. * @param argv The arguments to process. argv[0] should be the parameter * name. * @return -1 when argv[0] is no parameter, 0 on failure, 1 on success. */ int ProcessSICSHdbPar(pHdb root, SConnection * pCon, char *printPrefix, int argc, char *argv[]); /** * print a listing of the parameters of node to pCon, using the * specified prefix. * @param node The node to print * @param pCon The connection to print to * @param prefix The prefix to use for printing */ void PrintSICSParList(pHdb node, SConnection * pCon, char *prefix); /** * save the content of the Hipadaba starting at node into a file. This can * be used to save the configuration of an instrument. This routine is * recursive. * @param fd The file to write to * @param node The node to print from * @param prefix A prefix to use for printing. */ void SaveSICSHipadaba(FILE * fd, pHdb node, char *prefix); /** * A SICS task which scans a Hipadaba and reads and updates all parameters, * one per invocation. TODO: how to distinguish between automatic pars which * do not need this and pars which need this? Idea 1: make a root point at an * artificial tree of parameters which need to be checked like this. * @param pData The root to start scanning at. * @return 0 when ends, 1 else */ int SICSHipadabaTask(void *pData); void SICSHipadabaSignal(void *pData, int iSignal, void *pSigData); /*================== value helpers ========================================*/ /** * format a Hdb Value into a string using SICS defaults. * @param v The Hdb value to format * @param node The Hdb node (for format property) * @return a dynamic string holding the formatted data. NULL when * out of memory */ pDynString formatValue(hdbValue v, pHdb node); /** * read values for a Hdb value from a string. * @param v The hdbValue to read data into. Datatype and arraylength must * already have been initialised before this call in order to allow for * checks. Arrays should also have been allocated in the right size. * @param data The string to parse and convert. * @param error A string to copy failure reasons to * @param errlen The length of the error string * @return 0 on failure, 1 on success */ int readHdbValue(hdbValue * v, char *data, char *error, int errlen); /** * convert from test to a Hipadaba type * @param text The type text * @return The converted Hipadaba type */ int convertHdbType(char *text); /** * wrap a SICSOBJFunc function as an hdbValue * @param func the function * @return: A properly initialized hdbValue structure */ hdbValue MakeSICSFunc(SICSOBJFunc func); /*================= SICS Interpreter Interface ===========================*/ /** * InstallHipadaba installs the Hipadaba commands into the SICS interpreter. * The actual command implementation is in sicshipadaba.c. * @param pCon The connection object * @param pSics The SICS interpreter * @param pData The object data structure * @param argc The number of arguments * @param argv[] The text arguments * @return 0 on filaure, 1 on success */ int InstallSICSHipadaba(SConnection * pCon, SicsInterp * pSics, void *pData, int argc, char *argv[]); /** * get the root of the SICS Hipadaba tree * @return The root node of the hipdaba */ pHdb GetHipadabaRoot(); /** * kill the SICS hierarchical database * Only to be called when shutting down the SICServer */ void killSICSHipadaba(void); #endif /*SICSHIPADABA_H_ */