-
Notifications
You must be signed in to change notification settings - Fork 76
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
226 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 */ |