Skip to content

Commit

Permalink
Merge e49d25c into 66c1015
Browse files Browse the repository at this point in the history
  • Loading branch information
darcato authored Oct 18, 2021
2 parents 66c1015 + e49d25c commit e6edd6a
Show file tree
Hide file tree
Showing 4 changed files with 226 additions and 0 deletions.
2 changes: 2 additions & 0 deletions asyn/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ DBD += asyn.dbd
INC += asynShellCommands.h
INC += asynInterposeCom.h
INC += asynInterposeEos.h
INC += asynInterposeTemplate.h
INC += asynInterposeFlush.h
ifneq ($(EPICS_LIBCOM_ONLY),YES)
asyn_SRCS += asynShellCommands.c
Expand All @@ -111,6 +112,7 @@ asyn_SRCS += asynInterposeEos.c
asyn_SRCS += asynInterposeFlush.c
asyn_SRCS += asynInterposeDelay.c
asyn_SRCS += asynInterposeEcho.c
asyn_SRCS += asynInterposeTemplate.c

SRC_DIRS += $(ASYN)/asynPortDriver/exceptions
INC += ParamListInvalidIndex.h
Expand Down
1 change: 1 addition & 0 deletions asyn/miscellaneous/asyn.dbd
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ registrar(asynInterposeFlushRegister)
registrar(asynInterposeEosRegister)
registrar(asynInterposeDelayRegister)
registrar(asynInterposeEchoRegister)
registrar(asynInterposeTemplateRegister)

#
# The following ties this to EPICS records.
Expand Down
152 changes: 152 additions & 0 deletions asyn/miscellaneous/asynInterposeTemplate.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
/*asynInterposeTemplate.c*/

/*
* Example of an asynInterpose implementation
* The template implementation does *nothing*,
* simply forwards requests to the lower port.
*
* Use this as as a base example to build your asynInterpose.
*
* Author: davide.marcato@lnl.infn.it
*/

#include "asynInterposeTemplate.h"

ASYN_API
int asynInterposeTemplateConfig(const char *portName) {
interposePvt *pvt;
asynInterface *plowerLevelInterface;
asynStatus status;
asynUser *pasynUser;
int addr = 0;

// Populate private data
pvt = callocMustSucceed(1, sizeof(interposePvt), "asynInterposeTemplate");
pvt->portName = epicsStrDup(portName);
pvt->templateInterface.interfaceType = asynOctetType;
pvt->templateInterface.pinterface = &octet;
pvt->templateInterface.drvPvt = pvt;
pasynUser = pasynManager->createAsynUser(0, 0);
pvt->pasynUser = pasynUser;
pvt->pasynUser->userPvt = pvt;

// Connect
status = pasynManager->connectDevice(pasynUser, portName, addr);
if (status != asynSuccess) {
printf("%s connectDevice failed\n", portName);
pasynManager->freeAsynUser(pasynUser);
free(pvt);
return -1;
}

// Add callback
status = pasynManager->exceptionCallbackAdd(pasynUser, ExceptionHandler);
if (status != asynSuccess) {
printf("%s exceptionCallbackAdd failed\n", portName);
pasynManager->freeAsynUser(pasynUser);
free(pvt);
return -1;
}

// Interpose port
status = pasynManager->interposeInterface(portName, addr, &pvt->templateInterface,
&plowerLevelInterface);
if (status != asynSuccess) {
printf("%s interposeInterface failed\n", portName);
pasynManager->exceptionCallbackRemove(pasynUser);
pasynManager->freeAsynUser(pasynUser);
free(pvt);
return -1;
}
pvt->poctet = (asynOctet *)plowerLevelInterface->pinterface;
pvt->octetPvt = plowerLevelInterface->drvPvt;

return (0);
}

// Catch all exceptions
static void ExceptionHandler(asynUser *pasynUser, asynException exception) {
// On connections/disconnections
// Occurs every streamdevice transaction
if (exception == asynExceptionConnect) {
// Default = do nothing
}
}

/**
* asynOctet methods
*/

static asynStatus writeIt(void *ppvt, asynUser *pasynUser, const char *data, size_t numchars,
size_t *nbytesTransfered) {
interposePvt *pvt = (interposePvt *)ppvt;

// Write on underlying port
return pvt->poctet->write(pvt->octetPvt, pasynUser, data, numchars, nbytesTransfered);
}

static asynStatus readIt(void *ppvt, asynUser *pasynUser, char *data, size_t maxchars,
size_t *nbytesTransfered, int *eomReason) {
interposePvt *pvt = (interposePvt *)ppvt;

// Read from underlying port
return pvt->poctet->read(pvt->octetPvt, pasynUser, data, maxchars, nbytesTransfered, eomReason);
}

static asynStatus flushIt(void *ppvt, asynUser *pasynUser) {
interposePvt *pvt = (interposePvt *)ppvt;
return pvt->poctet->flush(pvt->octetPvt, pasynUser);
}

static asynStatus registerInterruptUser(void *ppvt, asynUser *pasynUser,
interruptCallbackOctet callback, void *userPvt,
void **registrarPvt) {
interposePvt *pvt = (interposePvt *)ppvt;
return pvt->poctet->registerInterruptUser(pvt->octetPvt, pasynUser, callback, userPvt,
registrarPvt);
}

static asynStatus cancelInterruptUser(void *ppvt, asynUser *pasynUser, void *registrarPvt) {
interposePvt *pvt = (interposePvt *)ppvt;
return pvt->poctet->cancelInterruptUser(pvt->octetPvt, pasynUser, registrarPvt);
}

static asynStatus setInputEos(void *ppvt, asynUser *pasynUser, const char *eos, int eoslen) {
interposePvt *pvt = (interposePvt *)ppvt;
return pvt->poctet->setInputEos(pvt->octetPvt, pasynUser, eos, eoslen);
}

static asynStatus getInputEos(void *ppvt, asynUser *pasynUser, char *eos, int eossize,
int *eoslen) {
interposePvt *pvt = (interposePvt *)ppvt;
return pvt->poctet->getInputEos(pvt->octetPvt, pasynUser, eos, eossize, eoslen);
}

static asynStatus setOutputEos(void *ppvt, asynUser *pasynUser, const char *eos, int eoslen) {
interposePvt *pvt = (interposePvt *)ppvt;
return pvt->poctet->setOutputEos(pvt->octetPvt, pasynUser, eos, eoslen);
}

static asynStatus getOutputEos(void *ppvt, asynUser *pasynUser, char *eos, int eossize,
int *eoslen) {
interposePvt *pvt = (interposePvt *)ppvt;
return pvt->poctet->getOutputEos(pvt->octetPvt, pasynUser, eos, eossize, eoslen);
}

/* register asynInterposeTemplateConfig*/
static const iocshArg asynInterposeTemplateConfigArg0 = {"portName", iocshArgString};
static const iocshArg *asynInterposeTemplateConfigArgs[] = {&asynInterposeTemplateConfigArg0};
static const iocshFuncDef asynInterposeTemplateConfigFuncDef = {"asynInterposeTemplateConfig", 1,
asynInterposeTemplateConfigArgs};
static void asynInterposeTemplateConfigCallFunc(const iocshArgBuf *args) {
asynInterposeTemplateConfig(args[0].sval);
}

static void asynInterposeTemplateRegister(void) {
static int firstTime = 1;
if (firstTime) {
firstTime = 0;
iocshRegister(&asynInterposeTemplateConfigFuncDef, asynInterposeTemplateConfigCallFunc);
}
}
epicsExportRegistrar(asynInterposeTemplateRegister);
71 changes: 71 additions & 0 deletions asyn/miscellaneous/asynInterposeTemplate.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*asynInterposeTemplate.h*/

/*
* Example of an asynInterpose implementation
* The template implementation does *nothing*,
* simply forwards requests to the lower port.
*
* Use this as as a base example to build your asynInterpose.
*
* Author: davide.marcato@lnl.infn.it
*/

#ifndef asynInterposeTemplate_H
#define asynInterposeTemplate_H

#include <cantProceed.h>
#include <epicsAssert.h>
#include <epicsExport.h>
#include <epicsStdio.h>
#include <epicsString.h>
#include <iocsh.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "asynDriver.h"
#include "asynOctet.h"

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

// Interpose private data
typedef struct interposePvt {
char *portName;
asynInterface templateInterface; /* This asynOctet interface */
asynOctet *poctet; /* The methods we're overriding */
void *octetPvt; /* Private data of next lower interface */
asynUser *pasynUser; /* For connect/disconnect reporting */
} interposePvt;

ASYN_API
int asynInterposeTemplateConfig(const char *portName);

/* Connect/disconnect handling */
static void ExceptionHandler(asynUser *pasynUser, asynException exception);

/* asynOctet methods */
static asynStatus writeIt(void *ppvt, asynUser *pasynUser, const char *data, size_t numchars,
size_t *nbytesTransfered);
static asynStatus readIt(void *ppvt, asynUser *pasynUser, char *data, size_t maxchars,
size_t *nbytesTransfered, int *eomReason);
static asynStatus flushIt(void *ppvt, asynUser *pasynUser);
static asynStatus registerInterruptUser(void *ppvt, asynUser *pasynUser,
interruptCallbackOctet callback, void *userPvt,
void **registrarPvt);
static asynStatus cancelInterruptUser(void *ppvt, asynUser *pasynUser, void *registrarPvt);
static asynStatus setInputEos(void *ppvt, asynUser *pasynUser, const char *eos, int eoslen);
static asynStatus getInputEos(void *ppvt, asynUser *pasynUser, char *eos, int eossize, int *eoslen);
static asynStatus setOutputEos(void *ppvt, asynUser *pasynUser, const char *eos, int eoslen);
static asynStatus getOutputEos(void *ppvt, asynUser *pasynUser, char *eos, int eossize,
int *eoslen);
static asynOctet octet = {
writeIt, readIt, flushIt, registerInterruptUser, cancelInterruptUser,
setInputEos, getInputEos, setOutputEos, getOutputEos};

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* asynInterposeTemplate_H */

0 comments on commit e6edd6a

Please sign in to comment.