146 lines
4.8 KiB
OpenEdge ABL
146 lines
4.8 KiB
OpenEdge ABL
#ifndef ASCON_I
|
|
#define ASCON_I
|
|
|
|
#include <sys/time.h>
|
|
#include "ascon.h"
|
|
#include "dynstring.h"
|
|
|
|
/** \file
|
|
* \brief Asynchronous connection handling for devices controlled over tcp-ip
|
|
* connections. Interface for the implementation of custom protocols.
|
|
*
|
|
* For the implmentation of a custom protocol, hou have to implement
|
|
* the handler function and the init function, declare the protocol
|
|
* of type AsconProtocol and call AsconInsertProtocol on startup.
|
|
* The handler and init functions are normally be a wrapper around AsconStdHandler
|
|
* and AsconStdInit
|
|
*
|
|
* The functions with fd as the first argument are utility functions with
|
|
* may be used in handler wrapper functions.
|
|
* On error, the return value may be one of the defined macros ASCON_xxx,
|
|
* and errno will give more details about the error.
|
|
*/
|
|
|
|
/**
|
|
* A sub-state of the connection. Only states with sub-state AsconStart may
|
|
* be set by the caller, and only when the sub-state is not AsconOnTheWay
|
|
*/
|
|
typedef enum { AsconOnTheWay=0, AsconStart=1, AsconFinished=2, AsconFailed=3 } AsconMode;
|
|
|
|
/**
|
|
* The state of the connection. The sub-state is state % 4.
|
|
*/
|
|
typedef enum {
|
|
AsconNotConnected=0+AsconFinished,
|
|
AsconKillMe=0+AsconStart,
|
|
AsconConnecting=4+AsconOnTheWay,
|
|
AsconConnectStart=AsconConnecting+AsconStart,
|
|
AsconConnectDone=AsconConnecting+AsconFinished,
|
|
AsconConnectFailed=AsconConnecting+AsconFailed,
|
|
AsconWriting=8+AsconOnTheWay,
|
|
AsconWriteStart=AsconWriting+AsconStart,
|
|
AsconWriteDone=AsconWriting+AsconFinished,
|
|
AsconReading=12+AsconOnTheWay,
|
|
AsconReadStart=AsconReading+AsconStart,
|
|
AsconReadDone=AsconReading+AsconFinished,
|
|
AsconIdle=16+AsconFinished
|
|
} AsconState;
|
|
|
|
/** \brief the task handler function prototype
|
|
*
|
|
* custom handlers must have this prototype
|
|
*/
|
|
typedef int (* AsconHandler)(Ascon *connection);
|
|
|
|
/** Ascon struct
|
|
* all members are public, allowing access by handler wrappers
|
|
*/
|
|
struct Ascon {
|
|
AsconState state; /**< the current state */
|
|
int fd; /**< socket */
|
|
int readState; /**< default implementation: 'was cr' */
|
|
pDynString rdBuffer;/**< read buffer */
|
|
pDynString wrBuffer;/**< write buffer */
|
|
int wrPos; /**< write buffer position */
|
|
double timeout; /**< read timeout (sec) */
|
|
char *hostport; /**< host:port to connect */
|
|
ErrMsg *errList; /**< error message list */
|
|
double start; /**< unix time when read was started */
|
|
void *private; /**< private data of protocol */
|
|
int noResponse; /**< no response expected */
|
|
int responseValid; /**< a valid response is ready */
|
|
AsconHandler handler; /**< handler function */
|
|
double reconnectInterval; /**< reconnect interval */
|
|
double lastReconnect; /**< last connect try */
|
|
};
|
|
|
|
#define ASCON_SELECT_ERROR -1
|
|
#define ASCON_RECV_ERROR -2
|
|
#define ASCON_SEND_ERROR -3
|
|
#define ASCON_DISCONNECTED -4
|
|
|
|
/** \brief the standard handler routine.
|
|
* \param a the connection
|
|
* \return 0 when task has finished (connection to be closed), 1 when active
|
|
*
|
|
* In most cases a custom handler may be a wrapper around AsconStdHandler
|
|
*/
|
|
int AsconStdHandler(Ascon *a);
|
|
|
|
/** \brief initialize a standard connection
|
|
* \param a the connection
|
|
* \param hostport the tcp/ip address (syntax: host:port)
|
|
*
|
|
* In most cases a custom init function may be a wrapper around AsconStdInit
|
|
*/
|
|
void AsconStdInit(Ascon *a, char *hostport);
|
|
|
|
/** The Ascon Protocol
|
|
*/
|
|
typedef struct AsconProtocol {
|
|
struct AsconProtocol *next;
|
|
char *name;
|
|
AsconHandler handler;
|
|
void (*init)(Ascon *s, int argc, char *argv[]);
|
|
} AsconProtocol;
|
|
|
|
/** \brief Insert a new protocol into the protocol list
|
|
* protocol the protocol (must be allocated by the caller, may be statically)
|
|
*/
|
|
void AsconInsertProtocol(AsconProtocol *protocol);
|
|
|
|
/** \brief close the connection and free internal used memory
|
|
* \param a the connection to be closed
|
|
* remark: the connection struct itself has to be freed manually
|
|
*/
|
|
void AsconClose(Ascon *a);
|
|
|
|
/** \brief swallow garbage (utility function)
|
|
* \param fd the socket
|
|
* \return >=0: number of chars swallowed, else error
|
|
*/
|
|
int AsconReadGarbage(int fd);
|
|
|
|
/** \brief check if a connection has succeded (utility function)
|
|
* \param fd the socket
|
|
* \return 1: connection succesful, 0: connection in progress, <0: error
|
|
*/
|
|
int AsconConnectSuccess(int fd);
|
|
|
|
/** \brief read one character, if available (utility function)
|
|
* \param fd the socket
|
|
* \param chr the result
|
|
* \return 1: succes, 0: no data available, <0: error
|
|
*/
|
|
int AsconReadChar(int fd, char *chr);
|
|
|
|
/** \brief non blocking write (utility function)
|
|
* \param fd the socket
|
|
* \param data the data (not nul-terminated, may contain nul)
|
|
* \param length the length of the data
|
|
* \return >0: number of written chars,0: write not yet possible, <0: error
|
|
*/
|
|
int AsconWriteChars(int fd, char *data, int length);
|
|
|
|
#endif
|