- introduced <controller> actions function for listing actions

- introduced <controller> reconnect function
This commit is contained in:
zolliker
2010-04-13 14:17:58 +00:00
parent 38818e650c
commit 6c4f57ec6f
4 changed files with 113 additions and 18 deletions

19
ascon.c
View File

@ -313,7 +313,7 @@ int AsconBaseHandler(Ascon * a)
} else if (ret > 0) {
a->state = AsconConnectDone; /* success */
} else if (ret < 0) {
AsconError(a, "ASC3", errno);
AsconError(a, "ASC3", errno);
}
break;
case AsconWriteStart:
@ -584,6 +584,23 @@ void AsconDisconnect(Ascon * a)
{
if (a->fd > 0) {
close(a->fd);
lastClose = DoubleTime();
}
a->fd = -1;
a->state = AsconNotConnected;
}
void AsconReconnect(Ascon * a, char * hostport)
{
if (a->fd > 0) {
close(a->fd);
lastClose = DoubleTime();
}
if (hostport != NULL && hostport[0] != '\0') {
if (a->hostport) {
free(a->hostport);
}
a->hostport = strdup(hostport);
}
a->fd = -1;
a->state = AsconConnectStart;

View File

@ -35,11 +35,17 @@ Ascon *AsconMake(SConnection * con, int argc, char *argv[]);
* \param a the connection to be killed
*/
void AsconKill(Ascon * a);
/** \brief Disconnect function
/** \brief disconnect and disable
* \param a the connection to disconnect
*/
void AsconDisconnect(Ascon * a);
/** \brief Reconnect function
* \param a the connection to reconnect
* \param hostport <host>:<port> to reconnect to (empty for reconnecting to the same port)
*/
void AsconReconnect(Ascon * a, char *hostport);
/** \brief the task handler. To be called repeatedly.
* \param a the connection
* \return the state of the connection

View File

@ -2,6 +2,7 @@
#include <math.h>
#include "ascon.h"
#include "devser.h"
#include "dynstring.h"
typedef struct DevAction {
struct DevAction *next;
@ -11,6 +12,7 @@ typedef struct DevAction {
DevKillActionData *kill;
double interval; /* -1 for a queued action */
double timeDue; /* 0 for a queued action */
DevInfoFunc *infoFunc;
} DevAction;
struct DevSer {
@ -207,11 +209,8 @@ void DevDebugMode(DevSer * devser, int steps)
devser->steps = steps;
}
void DevKill(DevSer * devser)
static void DevReset(DevSer * devser)
{
if (devser->ascon) {
AsconKill(devser->ascon);
}
DevFreeActionList(devser->actions);
DevFreeActionList(devser->toKill);
if (devser->killCurrent) {
@ -221,17 +220,34 @@ void DevKill(DevSer * devser)
devser->killCurrent = 0;
free(devser->current);
}
}
void DevKill(DevSer * devser)
{
if (devser->ascon) {
AsconKill(devser->ascon);
}
DevReset(devser);
TaskRemove(pServ->pTasker, DevQueueTask, devser);
free(devser);
}
void DevDisconnect(DevSer * devser)
{
DevReset(devser);
if (devser->ascon) {
AsconDisconnect(devser->ascon);
}
}
void DevReconnect(DevSer * devser, char *hostport)
{
DevReset(devser);
if (devser->ascon) {
AsconReconnect(devser->ascon, hostport);
}
}
int DevUnschedule(DevSer * devser, void *callData,
DevActionHandler * hdl, DevActionMatch * matchFunc)
{
@ -264,7 +280,7 @@ int DevUnschedule(DevSer * devser, void *callData,
int DevSchedule(DevSer * devser, void *actionData,
DevPrio prio, double interval,
DevActionHandler * hdl, DevActionMatch * matchFunc,
DevKillActionData * killFunc)
DevKillActionData * killFunc, DevInfoFunc * infoFunc)
{
DevAction *action;
DevAction *foundAction = NULL;
@ -272,6 +288,7 @@ int DevSchedule(DevSer * devser, void *actionData,
DevAction **ptr2insertPos = NULL;
int ret;
assert(killFunc == NULL || actionData != NULL);
if (prio <= NullPRIO) {
prio = NullPRIO + 1;
}
@ -293,10 +310,10 @@ int DevSchedule(DevSer * devser, void *actionData,
&& matchFunc(actionData, action->data)) {
if (prio == action->prio && interval < 0) {
/* do not move an action with equal prio */
if(killFunc != NULL && actionData != NULL){
killFunc(actionData);
}
return 0;
if (killFunc) {
killFunc(actionData);
}
return 0; /* not queued */
}
/* remove action from list */
*ptr2prev = action->next;
@ -320,6 +337,7 @@ int DevSchedule(DevSer * devser, void *actionData,
action->data = actionData;
action->hdl = hdl;
action->kill = killFunc;
action->infoFunc = infoFunc;
action->timeDue = 0;
ret = 1;
}
@ -348,9 +366,10 @@ int DevSchedule(DevSer * devser, void *actionData,
int DevQueue(DevSer * devser, void *actionData, DevPrio prio,
DevActionHandler * hdl, DevActionMatch * matchFunc,
DevKillActionData * killFunc)
DevKillActionData * killFunc, DevInfoFunc *infoFunc)
{
return DevSchedule(devser, actionData, prio, -1.0, hdl, matchFunc, killFunc);
return DevSchedule(devser, actionData, prio, -1.0, hdl
, matchFunc, killFunc, infoFunc);
}
int DevRemoveAction(DevSer * devser, void *actionData)
@ -359,7 +378,6 @@ int DevRemoveAction(DevSer * devser, void *actionData)
DevAction *action = NULL;
int cnt = 0;
/* Remove current action, if matched. If a reply is pending, the next
action will get the reply. But as in the inital state no reply is
expected, this should not harm. */
@ -403,3 +421,35 @@ int DevIsPending(DevSer * devser, void *callData,
return 0;
}
char * DevList(DevSer * devser) {
DevAction * action;
pDynString result, info;
char text[80];
char *str;
result = CreateDynString(63,64);
for (action = devser->actions; action != NULL; action = action->next) {
if (action->interval < 0) {
snprintf(text, sizeof text, "%-8s queued ", DevPrio2Text(action->prio));
} else {
snprintf(text, sizeof text, "%-8s %8.3g %14.3f ",
DevPrio2Text(action->prio), action->interval, action->timeDue);
}
DynStringConcat(result, text);
if (action == devser->current) {
DynStringConcat(result, "ACTIVE ");
}
if (action->infoFunc) {
str = action->infoFunc(action->data);
DynStringConcat(result, str);
free(str);
} else {
snprintf(text, sizeof text, "%8.8x", (unsigned int)action->data);
DynStringConcat(result, text);
}
DynStringConcat(result, "\n");
}
str = strdup(GetCharArray(result));
DeleteDynString(result);
return str;
}

View File

@ -29,6 +29,13 @@ typedef int DevActionMatch(void *callData, void *actionData);
*/
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
@ -59,11 +66,16 @@ void DevDebugMode(DevSer * devser, int steps);
* \param devser the device serializer
*/
void DevKill(DevSer * devser);
/** \brief Disconnect
/** \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 <host>:<port> 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
@ -76,12 +88,14 @@ void DevDisconnect(DevSer * devser);
* \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);
DevKillActionData * killFunc, DevInfoFunc * infoFunc);
/** \brief Schedule a periodic action
*
@ -94,13 +108,15 @@ int DevQueue(DevSer * devser, void *actionData, DevPrio prio,
* \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 DevSchedule(DevSer * devser, void *actionData,
DevPrio prio, double interval,
DevActionHandler * hdl, DevActionMatch * matchFunc,
DevKillActionData * killFunc);
DevKillActionData * killFunc, DevInfoFunc * infoFunc);
/** \brief Unschedule matching actions
* \param devser the device serializer
@ -140,4 +156,10 @@ char *DevPrio2Text(DevPrio prio);
*/
DevPrio DevText2Prio(char *text);
/** \brief List registered actions
* \param devser the device serializer
* \return the listing text
*/
char * DevList(DevSer * devser);
#endif