#ifndef DEVSER_H #define DEVSER_H /** \file * \brief Device Serializer */ typedef struct DevSer DevSer; /** \brief The action handler to be called * \param actionData the data stored with the action * \param lastReply the last reply or NULL when no command was * sent in the last action, or the error message (when commError == 1) * \param commError 0: ok, 1: there was a communication error * \return the command to be sent or NULL if no command has to be sent */ typedef char *DevActionHandler(void *actionData, char *lastReply, int commError); /** \brief Check if an action matches the call data * \param callData the callers data * \param actionData the action data * \return 1 on a match, 0 on no match */ typedef int DevActionMatch(void *callData, void *actionData); /** \brief Kill ActionData * \param actionData action data */ typedef void DevKillActionData(void *actionData); /** \brief ActionData info function * \param actionData action data * \return textual information about action for listing * the result is an allocated string and has to be freed after use */ typedef char * DevInfoFunc(void *actionData); /** \brief possible priorities. * NullPRIO and NumberOfPRIO must not be used as priority * if an action with StartPRIO is scheduled, all other activities * are blocked until the action is unscheduled */ typedef enum { NullPRIO, SlowPRIO, ReadPRIO, ProgressPRIO, WritePRIO, HaltPRIO, StartPRIO, NumberOfPRIO } DevPrio; /** \brief Make a new device serializer and async connection. * \param con the SICS connection (for error messages) * \param argc the number of args for specifying the protocol * \param argv the args * \return the created device serializer or NULL on failure */ DevSer *DevMake(SConnection * con, int argc, char *argv[]); /** \brief put the device serializer into debug mode * \param devser the device serializer * \param steps the number of steps to be executed or -1 for disable debugging mode */ void DevDebugMode(DevSer * devser, int steps); /** \brief Kill the contents of the device serializer and its async connection. * * The data structure itself is killed at some time later * \param devser the device serializer */ void DevKill(DevSer * devser); /** \brief disconnect and disable the serializer * \param devser The device serializer to disconnect */ void DevDisconnect(DevSer * devser); /** \brief reconnect the serializer * \param devser The device serializer to reconnect * \param hostport : to reconnect to another port * ar an empty string to reconnect to the same port */ void DevReconnect(DevSer * devser, char *hostport); /** \brief Queue an action * * If a matching action with the same action handler * exists already, no new action is queued. * \param devser the device serializer * \param actionData the action data * \param prio the priority * \param hdl the action handler * \param matchFunc a match function with two arguments of the same type * \param killFunc the action data kill function (called from DevKill and * after the action has finished, i.e. when hdl returned NULL) * or NULL if no kill function is needed. * \param infoFunc the actions info function or NULL if no info function * is defined. * \return 1 when this was a new action, 0 when an action was overwritten * in the second case the actionData's kill Function is immediately called */ int DevQueue(DevSer * devser, void *actionData, DevPrio prio, DevActionHandler * hdl, DevActionMatch * matchFunc, DevKillActionData * killFunc, DevInfoFunc * infoFunc); /** \brief Schedule a periodic action, with specified start * * If a matching action exists already, * it is overwritten with a possibly changed interval and priority. * \param devser the device serializer * \param actionData the action data * \param prio the priority * \param interval the interval in seconds (0 is allowed) * \param start the first call time. if a passed time is specified, * the next call happens immediately, and further calls happen after * start + n * interval * \param hdl the action handler * \param matchFunc a match function with two arguments of the same type * \param killFunc the action data kill function or NULL if no kill function is needed. * \param infoFunc the actions info function or NULL if no info function * is defined. * \return 1 when this was a new action, 0 when an action was overwritten * in the second case the actionData's kill Function is immediately called */ int DevScheduleS(DevSer * devser, void *actionData, DevPrio prio, double interval, double start, DevActionHandler * hdl, DevActionMatch * matchFunc, DevKillActionData * killFunc, DevInfoFunc * infoFunc); /** \brief Schedule a periodic action, without specified start * * Parameters see DevScheduleS. */ int DevSchedule(DevSer * devser, void *actionData, DevPrio prio, double interval, DevActionHandler * hdl, DevActionMatch * matchFunc, DevKillActionData * killFunc, DevInfoFunc * infoFunc); /** \brief Unschedule matching actions * \param devser the device serializer * \param callData the callers data to be used as first argument of the match function * \param hdl the action handler * \param matchFunc a match function (the first argument might have an other type than the second) * \return the number of unscheduled actions */ int DevUnschedule(DevSer * devser, void *callData, DevActionHandler * hdl, DevActionMatch * matchFunc); /** \brief remove action from the serializer * \param devser the device serializer * \param actionData the action data to be compared for a match */ int DevRemoveAction(DevSer * devser, void *actionData); /** \brief check if an action is pending * \param devser the device serializer * \param callData the callers data to be used as first argument of the match function * \param hdl the action handler * \param matchFunc a match function (the first argument might have an other type than the second) * \return the number of unscheduled actions */ int DevIsPending(DevSer * devser, void *callData, DevActionHandler * hdl, DevActionMatch * matchFunc); /** \brief Convert integer priority to text * \param prio * \return text */ char *DevPrio2Text(DevPrio prio); /** \brief Convert text priority to integer * \param text * \return prio */ DevPrio DevText2Prio(char *text); /** \brief List registered actions * \param devser the device serializer * \return the listing text */ char * DevList(DevSer * devser); /** * \brief Get statistics * \param devser The device serializer * \param avg The average response time * \param max The maximum response time * \param maxCount how often the communication took longer then max/2. * \param errCount The count of communication errors detected so far. * \param errFlag A flag if the device is in an error state or not */ void DevStatistics(DevSer *devser, double *avg, double *max, int *maxCount, long *errCount, int *errFlag); /** * \brief Get Ascon invocation statistics. This can help to stop * blocking behaviour in protocol handlers. * \param devser The device serializer to query * \param avg The avgerage time spent in AsconTask invocations * \param max The maximum time spent in a AsconTask call. */ void DevAsconStatistics(DevSer *self, double *avg, double *max, int *maxState, int *longCount); /** * \brief return host:port * \param devser The device serializer to query * \return the host and port */ char *DevHostport(DevSer *devser); /** * \brief return IP address * \param a The device serializer to query * \return the IP address (dotted numbers) */ char *DevIP(DevSer *devser); /** * \brief return status of device server ("offline", "unconnected", "") * \param devser The device serializer to query * \return the status */ char *DevStatus(DevSer *devser); /** * \brief set or get timeout * \param devser The device serializer to change * \param timeout the timeout to set * \param setmode 0: get, 1: set * \return the timeout value */ double DevGetSetTimeout(DevSer *devser, double timeout, int setmode); /** * \brief set reconnectInterval * \param a the Ascon * \param interval the interval to set (0: no reconnect, -1: read value) * \return the value */ int DevReconnectInterval(DevSer *devser, int interval); /** * Drive devser processing. Normally called as a SICS task * @param ds The device serialiser to run * @return 1 when continuing the task, 0 when the task is to be stopped */ int DevQueueTask(void *ds); #endif