diff --git a/src/hal/ethernet/linux/ethernet_linux.c b/src/hal/ethernet/linux/ethernet_linux.c index cff4f068..a2e3e8c9 100644 --- a/src/hal/ethernet/linux/ethernet_linux.c +++ b/src/hal/ethernet/linux/ethernet_linux.c @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -40,6 +41,60 @@ struct sEthernetSocket { struct sockaddr_ll socketAddress; }; +struct sEthernetHandleSet { + fd_set handles; + int maxHandle; +}; + +EthernetHandleSet +EthernetHandleSet_new(void) +{ + EthernetHandleSet result = (EthernetHandleSet) GLOBAL_MALLOC(sizeof(struct sEthernetHandleSet)); + + if (result != NULL) { + FD_ZERO(&result->handles); + result->maxHandle = -1; + } + + return result; +} + +void +EthernetHandleSet_addSocket(EthernetHandleSet self, const EthernetSocket sock) +{ + if (self != NULL && sock != NULL && sock->rawSocket != -1) { + FD_SET(sock->rawSocket, &self->handles); + if (sock->rawSocket > self->maxHandle) { + self->maxHandle = sock->rawSocket; + } + } +} + +int +EthernetHandleSet_waitReady(EthernetHandleSet self, unsigned int timeoutMs) +{ + int result; + + if ((self != NULL) && (self->maxHandle >= 0)) { + struct timeval timeout; + + timeout.tv_sec = timeoutMs / 1000; + timeout.tv_usec = (timeoutMs % 1000) * 1000; + result = select(self->maxHandle + 1, &self->handles, NULL, NULL, &timeout); + } + else { + result = -1; + } + + return result; +} + +void +EthernetHandleSet_destroy(EthernetHandleSet self) +{ + GLOBAL_FREEMEM(self); +} + static int getInterfaceIndex(int sock, const char* deviceName) { diff --git a/src/hal/inc/hal_ethernet.h b/src/hal/inc/hal_ethernet.h index 137e717c..5fa6e412 100644 --- a/src/hal/inc/hal_ethernet.h +++ b/src/hal/inc/hal_ethernet.h @@ -48,6 +48,50 @@ extern "C" { */ typedef struct sEthernetSocket* EthernetSocket; +/** Opaque reference for a set of ethernet socket handles */ +typedef struct sEthernetHandleSet* EthernetHandleSet; + +/** + * \brief Create a new connection handle set (EthernetHandleSet) + * + * \return new EthernetHandleSet instance + */ +EthernetHandleSet +EthernetHandleSet_new(void); + +/** + * \brief add a socket to an existing handle set + * + * \param self the HandleSet instance + * \param sock the socket to add + */ +void +EthernetHandleSet_addSocket(EthernetHandleSet self, const EthernetSocket sock); + + +/** + * \brief wait for a socket to become ready + * + * This function is corresponding to the BSD socket select function. + * It returns the number of sockets on which data is pending or 0 if no data is pending + * on any of the monitored connections. The function will return after "timeout" ms if no + * data is pending. + * The function shall return -1 if a socket error occures. + * + * \param self the EthernetHandleSet instance + * \param timeout in milliseconds (ms) + */ +int +EthernetHandleSet_waitReady(EthernetHandleSet self, unsigned int timeoutMs); + +/** + * \brief destroy the EthernetHandleSet instance + * + * \param self the HandleSet instance to destroy + */ +void +EthernetHandleSet_destroy(EthernetHandleSet self); + /** * \brief Return the MAC address of an Ethernet interface. *