/** * Asynchronous networking for SICS and other programs. This module centrally manages * a number of network connections for a client program. It is a layer between the * program and the network which manages non blocking network I/O. To this purpose, the * client program has to call ANETprocess at convenient intervals. This module * has a couple of features: * - Connections are abstracted to handles which are guaranteed to be unique * rather then socket numbers. Socket numbers may be reused by the OS. * - This module allows upper level code to figure out if a connection is still * connected or not. * - This module introduces a buffer layer between the socket and the application. * Thus the upper layer does not have to worry much about I/O blocking. This * is taken care of by this module both for reading and writing. * - All I/O is non blocking. * - This module can detect if a client is hanging and close the connection then. * Hanging is detected by not being able to write to the client for some period * of time. * * copyright: see file COPYRIGHT * * Mark Koennecke, January 2009 */ #ifndef ASYNNET_H_ #define ASYNNET_H_ /*=================== error codes ========================================*/ #define ANETOK 1 #define ANETDISCONNECTED -10000 #define ANETWRITEBUFFERFULL -10001 #define ANETTIMEOUT -10002 #define ANETOPENFAIL -10003 #define ANETSOCKERROR -10004 #define ANETMEM -10005 #define ANETOUTOFSOCKETS -10006 /*================== log levels ==========================================*/ #define ANETNONE 0 #define ANETERROR 1 #define ANETIO 2 #define ANETCON 3 /*================== callback functions ==================================*/ /** * \brief Callback called when a connection has been accepted on a * port or data is ready. * \param handle The handle of the new network connection * \return 1 if the new connection can be accepted or 0 if not. * Same for data. */ typedef int (*ANETcallback) (int handle, void *userData); /** * \brief a callback which is called in order to determine if a * a terminator is present in the data. * \param data The data to inspect * \param length The length of the data to inspect * \param userData An opaque pointer passed through to this * function * \return -1 when no terminator is in the data, an integer pointing * to after the terminator in data (in bytes). */ typedef int (*ANETtermCallback) (void *data, int length, void *userData); /** * \brief a callback function for waiting on some event. * This is typically called to do something else while waiting * for data to arrive. It can also return a negative return value, * which will effectively implement a timeout. * \param userData An opaque pointer passed through to this callback * \return 1 to continue waiting, -1 for a timeout. */ typedef int (*ANETwait) (void *userData); /** * \brief callback to log events in ANET * \param level The level of the logging message * \param txt The logging data * \param userData An opaque pointer passed through to ANETlog */ typedef void (*ANETlog) (int level, char *txt, void *userData); /** * \brief a callback for killing userdata associated with a read callback. * This is called in ANETclose, if defined. * \param userData The user data to kill. */ typedef void (*ANETkill) (void *userData); /*===================== open/close functions =============================*/ /** * * \brief open a server port * \param iPort The port number at which to listen for * connections. * \param cb A callback which will be called whenever a new connection * has been accepted on this port. * \prama userData An opaque pointer to be passed as an argument to the * callback function. * \return A handle for the server port or a negative error code. */ int ANETopenServerPort(int iPort, ANETcallback cb, void *userData); /** * \brief open a client connection to a server. * \param name the computer name of the server * \param iPort The port number at which the server is listening * \return A handle to the open port or a negative error code. */ int ANETconnect(char *name, int iPort); /** * \brief register a socket to be managed by this module. The socket * may have been obtained by any means. * \param socket The file descriptor of the socket * \return A handle to use for this socket later on. */ int ANETregisterSocket(int socket); /** * \brief close a connection * \param handle The handle of the connection */ void ANETclose(int handle); /** * \brief This function drives I/O processing, i.e. reading and writing. * This has to be called by the client of this module at regular intervalls. */ void ANETprocess(void); /** * \brief tests if a handle is still a valid connection * \param handle The handle to test. * \return 1 if this is still a connected socket, 0 else. */ int ANETvalidHandle(int handle); /** * \brief figure out to which host we are connected. * \param handle The connection handle * \param hostname a buffer to copy the hostname into * \param hostNameLen the length of the hostname buffer * \return 1 on success, a negative error code else. */ int ANETinfo(int handle, char *hostname, int hostNameLen); /*=================== I/O functions =========================================== * For reading there are possibilities: * - Raw reading happens through the combination of * ANETread and ANETreadConsume. * - Another way for raw reading is to register a read callback which is * called anytime new data arrives. * - The usual case is to wait for a line of terminated command input. This is * done through ANETreadTillterm. * ==========================================================================*/ /** * \brief write to the network * \param handle The handle for the connection * \param buffer A pointer to the data to write * \param count The number of bytes to write. * \return 1 on success, 0 on failure */ int ANETwrite(int handle, void *buffer, int count); /** * \brief Test if the buffer can be written to the network * \param handle The handle for the connection * \param buffer A pointer to the data to write * \param count The number of bytes to write. * \return 1 when possible, 0 when buffer overrun */ int ANETcanWrite(int handle, void *buffer, int count); /** * \brief copy at max bufferLength bytes into buffer. The data is not deleted from * the read buffer yet. * \param handle The handle of the connection to read from * \param buffer a pointer to an area for holding the data * \param bufferLength The maximum number of bytes which can be copied into * the buffer. * \return The number of bytes copied. Can be 0 if no data is available. On * errors a negative error code is returned. */ int ANETread(int handle, void *buffer, int bufferLength); /** * \brief Get a pointer to the data which has been read up to now. * Do not mess with the data!! Else the result may be badly defined! * \param handle The handle for the connection * \param length will be set to the length of the data read so far. * \return NULL when the socket is disconnected, a pointer else. */ void *ANETreadPtr(int handle, int *length); /** * \brief remove count bytes from the read buffer. * \param handle The handle for the connection. * \param count The number of bytes which can be removed from the * read buffer. */ void ANETreadConsume(int handle, int count); /** * \brief set a callback to be called when data is available at the port. * \param handle The handle of the connection * \param cb The callback function to call * \param userData An opaque pointer passed on as a parameter to the * callback function. */ void ANETsetReadCallback(int handle, ANETcallback cb, void *userData, ANETkill killUser); /** * \brief wait for terminated data to arrive. * \param handle The connection handle to read from * \param tcb a callback function which determines if a terminator is in the * data. * \param termData An opaque data pointer passed on to tcb * \param wcb A callback function called while waiting for data * to arrive. * \param waitData An opaque pointer passed on to wcb * \param buffer A newly allocated buffer holding the data as read * including the terminator. * \return 1 on success, a negative error code else. */ int ANETreadTillTerm(int handle, ANETtermCallback tcb, void *termData, ANETwait wcb, void *waitData, char **buffer); /** * Note to Markus: suitable callbacks for the standard case: waiting for \n and * TaskYield for waiting to a timeout will become part of nread.h, .c. */ /*========================== system ====================================*/ /** * \brief install a logging function * \param lcb The logging function to install * \param userData An opaque pointer with data for lcb */ void ANETsetLog(ANETlog lcb, void *userData); #endif /*ASYNNET_H_ */