- 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

17
ascon.c
View File

@ -584,6 +584,23 @@ void AsconDisconnect(Ascon * a)
{ {
if (a->fd > 0) { if (a->fd > 0) {
close(a->fd); 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->fd = -1;
a->state = AsconConnectStart; a->state = AsconConnectStart;

View File

@ -35,11 +35,17 @@ Ascon *AsconMake(SConnection * con, int argc, char *argv[]);
* \param a the connection to be killed * \param a the connection to be killed
*/ */
void AsconKill(Ascon * a); void AsconKill(Ascon * a);
/** \brief Disconnect function /** \brief disconnect and disable
* \param a the connection to disconnect * \param a the connection to disconnect
*/ */
void AsconDisconnect(Ascon * a); 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. /** \brief the task handler. To be called repeatedly.
* \param a the connection * \param a the connection
* \return the state of the connection * \return the state of the connection

View File

@ -2,6 +2,7 @@
#include <math.h> #include <math.h>
#include "ascon.h" #include "ascon.h"
#include "devser.h" #include "devser.h"
#include "dynstring.h"
typedef struct DevAction { typedef struct DevAction {
struct DevAction *next; struct DevAction *next;
@ -11,6 +12,7 @@ typedef struct DevAction {
DevKillActionData *kill; DevKillActionData *kill;
double interval; /* -1 for a queued action */ double interval; /* -1 for a queued action */
double timeDue; /* 0 for a queued action */ double timeDue; /* 0 for a queued action */
DevInfoFunc *infoFunc;
} DevAction; } DevAction;
struct DevSer { struct DevSer {
@ -207,11 +209,8 @@ void DevDebugMode(DevSer * devser, int steps)
devser->steps = steps; devser->steps = steps;
} }
void DevKill(DevSer * devser) static void DevReset(DevSer * devser)
{ {
if (devser->ascon) {
AsconKill(devser->ascon);
}
DevFreeActionList(devser->actions); DevFreeActionList(devser->actions);
DevFreeActionList(devser->toKill); DevFreeActionList(devser->toKill);
if (devser->killCurrent) { if (devser->killCurrent) {
@ -221,17 +220,34 @@ void DevKill(DevSer * devser)
devser->killCurrent = 0; devser->killCurrent = 0;
free(devser->current); free(devser->current);
} }
}
void DevKill(DevSer * devser)
{
if (devser->ascon) {
AsconKill(devser->ascon);
}
DevReset(devser);
TaskRemove(pServ->pTasker, DevQueueTask, devser); TaskRemove(pServ->pTasker, DevQueueTask, devser);
free(devser); free(devser);
} }
void DevDisconnect(DevSer * devser) void DevDisconnect(DevSer * devser)
{ {
DevReset(devser);
if (devser->ascon) { if (devser->ascon) {
AsconDisconnect(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, int DevUnschedule(DevSer * devser, void *callData,
DevActionHandler * hdl, DevActionMatch * matchFunc) DevActionHandler * hdl, DevActionMatch * matchFunc)
{ {
@ -264,7 +280,7 @@ int DevUnschedule(DevSer * devser, void *callData,
int DevSchedule(DevSer * devser, void *actionData, int DevSchedule(DevSer * devser, void *actionData,
DevPrio prio, double interval, DevPrio prio, double interval,
DevActionHandler * hdl, DevActionMatch * matchFunc, DevActionHandler * hdl, DevActionMatch * matchFunc,
DevKillActionData * killFunc) DevKillActionData * killFunc, DevInfoFunc * infoFunc)
{ {
DevAction *action; DevAction *action;
DevAction *foundAction = NULL; DevAction *foundAction = NULL;
@ -272,6 +288,7 @@ int DevSchedule(DevSer * devser, void *actionData,
DevAction **ptr2insertPos = NULL; DevAction **ptr2insertPos = NULL;
int ret; int ret;
assert(killFunc == NULL || actionData != NULL);
if (prio <= NullPRIO) { if (prio <= NullPRIO) {
prio = NullPRIO + 1; prio = NullPRIO + 1;
} }
@ -293,10 +310,10 @@ int DevSchedule(DevSer * devser, void *actionData,
&& matchFunc(actionData, action->data)) { && matchFunc(actionData, action->data)) {
if (prio == action->prio && interval < 0) { if (prio == action->prio && interval < 0) {
/* do not move an action with equal prio */ /* do not move an action with equal prio */
if(killFunc != NULL && actionData != NULL){ if (killFunc) {
killFunc(actionData); killFunc(actionData);
} }
return 0; return 0; /* not queued */
} }
/* remove action from list */ /* remove action from list */
*ptr2prev = action->next; *ptr2prev = action->next;
@ -320,6 +337,7 @@ int DevSchedule(DevSer * devser, void *actionData,
action->data = actionData; action->data = actionData;
action->hdl = hdl; action->hdl = hdl;
action->kill = killFunc; action->kill = killFunc;
action->infoFunc = infoFunc;
action->timeDue = 0; action->timeDue = 0;
ret = 1; ret = 1;
} }
@ -348,9 +366,10 @@ int DevSchedule(DevSer * devser, void *actionData,
int DevQueue(DevSer * devser, void *actionData, DevPrio prio, int DevQueue(DevSer * devser, void *actionData, DevPrio prio,
DevActionHandler * hdl, DevActionMatch * matchFunc, 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) int DevRemoveAction(DevSer * devser, void *actionData)
@ -359,7 +378,6 @@ int DevRemoveAction(DevSer * devser, void *actionData)
DevAction *action = NULL; DevAction *action = NULL;
int cnt = 0; int cnt = 0;
/* Remove current action, if matched. If a reply is pending, the next /* 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 action will get the reply. But as in the inital state no reply is
expected, this should not harm. */ expected, this should not harm. */
@ -403,3 +421,35 @@ int DevIsPending(DevSer * devser, void *callData,
return 0; 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); 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. /** \brief possible priorities.
* NullPRIO and NumberOfPRIO must not be used as priority * NullPRIO and NumberOfPRIO must not be used as priority
* if an action with StartPRIO is scheduled, all other activities * 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 * \param devser the device serializer
*/ */
void DevKill(DevSer * devser); void DevKill(DevSer * devser);
/** \brief Disconnect /** \brief disconnect and disable the serializer
* \param devser The device serializer to disconnect * \param devser The device serializer to disconnect
*/ */
void DevDisconnect(DevSer * devser); 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 /** \brief Queue an action
* *
* If a matching action with the same action handler * 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 * \param killFunc the action data kill function (called from DevKill and
* after the action has finished, i.e. when hdl returned NULL) * after the action has finished, i.e. when hdl returned NULL)
* or NULL if no kill function is needed. * 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 * \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 * in the second case the actionData's kill Function is immediately called
*/ */
int DevQueue(DevSer * devser, void *actionData, DevPrio prio, int DevQueue(DevSer * devser, void *actionData, DevPrio prio,
DevActionHandler * hdl, DevActionMatch * matchFunc, DevActionHandler * hdl, DevActionMatch * matchFunc,
DevKillActionData * killFunc); DevKillActionData * killFunc, DevInfoFunc * infoFunc);
/** \brief Schedule a periodic action /** \brief Schedule a periodic action
* *
@ -94,13 +108,15 @@ int DevQueue(DevSer * devser, void *actionData, DevPrio prio,
* \param hdl the action handler * \param hdl the action handler
* \param matchFunc a match function with two arguments of the same type * \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 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 * \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 * in the second case the actionData's kill Function is immediately called
*/ */
int DevSchedule(DevSer * devser, void *actionData, int DevSchedule(DevSer * devser, void *actionData,
DevPrio prio, double interval, DevPrio prio, double interval,
DevActionHandler * hdl, DevActionMatch * matchFunc, DevActionHandler * hdl, DevActionMatch * matchFunc,
DevKillActionData * killFunc); DevKillActionData * killFunc, DevInfoFunc * infoFunc);
/** \brief Unschedule matching actions /** \brief Unschedule matching actions
* \param devser the device serializer * \param devser the device serializer
@ -140,4 +156,10 @@ char *DevPrio2Text(DevPrio prio);
*/ */
DevPrio DevText2Prio(char *text); DevPrio DevText2Prio(char *text);
/** \brief List registered actions
* \param devser the device serializer
* \return the listing text
*/
char * DevList(DevSer * devser);
#endif #endif