- introduced <controller> actions function for listing actions
- introduced <controller> reconnect function
This commit is contained in:
17
ascon.c
17
ascon.c
@ -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;
|
||||||
|
8
ascon.h
8
ascon.h
@ -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
|
||||||
|
70
devser.c
70
devser.c
@ -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;
|
||||||
|
}
|
||||||
|
30
devser.h
30
devser.h
@ -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
|
||||||
|
Reference in New Issue
Block a user