From 5333aed1cd832b7fc5cff59b191da67473f8ab6d Mon Sep 17 00:00:00 2001 From: Paul Kocialkowski Date: Wed, 6 Aug 2014 14:30:39 +0200 Subject: External fds polling support Signed-off-by: Paul Kocialkowski --- include/samsung-ipc.h | 9 ++++-- samsung-ipc/devices/aries/aries.c | 39 ++++++++++++++++++++---- samsung-ipc/devices/crespo/crespo.c | 40 +++++++++++++++++++++---- samsung-ipc/devices/galaxys2/galaxys2.c | 4 +-- samsung-ipc/devices/i9300/i9300.c | 4 +-- samsung-ipc/devices/maguro/maguro.c | 4 +-- samsung-ipc/devices/n7100/n7100.c | 4 +-- samsung-ipc/devices/piranha/piranha.c | 4 +-- samsung-ipc/devices/xmm626/xmm626_sec_modem.c | 43 +++++++++++++++++++++++---- samsung-ipc/devices/xmm626/xmm626_sec_modem.h | 3 +- samsung-ipc/ipc.c | 6 ++-- samsung-ipc/ipc.h | 2 +- 12 files changed, 129 insertions(+), 33 deletions(-) diff --git a/include/samsung-ipc.h b/include/samsung-ipc.h index c45bd4b..9d638ec 100644 --- a/include/samsung-ipc.h +++ b/include/samsung-ipc.h @@ -54,6 +54,11 @@ struct ipc_client_gprs_capabilities { unsigned int cid_count; }; +struct ipc_poll_fds { + int *fds; + unsigned int count; +}; + /* * Helpers */ @@ -68,7 +73,7 @@ int ipc_client_transport_handlers_register(struct ipc_client *client, int (*close)(void *transport_data), int (*read)(void *transport_data, void *data, size_t size), int (*write)(void *transport_data, const void *data, size_t size), - int (*poll)(void *transport_data, struct timeval *timeout), + int (*poll)(void *transport_data, struct ipc_poll_fds *fds, struct timeval *timeout), void *transport_data); int ipc_client_power_handlers_register(struct ipc_client *client, int (*power_on)(void *power_data), int (*power_off)(void *power_data), @@ -88,7 +93,7 @@ int ipc_client_recv(struct ipc_client *client, struct ipc_message *message); int ipc_client_open(struct ipc_client *client); int ipc_client_close(struct ipc_client *client); -int ipc_client_poll(struct ipc_client *client, struct timeval *timeout); +int ipc_client_poll(struct ipc_client *client, struct ipc_poll_fds *fds, struct timeval *timeout); int ipc_client_power_on(struct ipc_client *client); int ipc_client_power_off(struct ipc_client *client); int ipc_client_gprs_activate(struct ipc_client *client, unsigned int cid); diff --git a/samsung-ipc/devices/aries/aries.c b/samsung-ipc/devices/aries/aries.c index c285ba6..321a982 100644 --- a/samsung-ipc/devices/aries/aries.c +++ b/samsung-ipc/devices/aries/aries.c @@ -623,11 +623,14 @@ int aries_write(void *data, const void *buffer, size_t length) return rc; } -int aries_poll(void *data, struct timeval *timeout) +int aries_poll(void *data, struct ipc_poll_fds *fds, struct timeval *timeout) { struct aries_transport_data *transport_data; - fd_set fds; + fd_set set; int fd; + int fd_max; + unsigned int i; + unsigned int count; int rc; if (data == NULL) @@ -639,10 +642,36 @@ int aries_poll(void *data, struct timeval *timeout) if (fd < 0) return -1; - FD_ZERO(&fds); - FD_SET(fd, &fds); + FD_ZERO(&set); + FD_SET(fd, &set); + + fd_max = fd; + + if (fds != NULL && fds->fds != NULL && fds->count > 0) { + for (i = 0; i < fds->count; i++) { + if (fds->fds[i] >= 0) { + FD_SET(fds->fds[i], &set); + + if (fds->fds[i] > fd_max) + fd_max = fds->fds[i]; + } + } + } + + rc = select(fd_max + 1, &set, NULL, NULL, timeout); + + if (fds != NULL && fds->fds != NULL && fds->count > 0) { + count = fds->count; - rc = select(fd + 1, &fds, NULL, NULL, timeout); + for (i = 0; i < fds->count; i++) { + if (!FD_ISSET(fds->fds[i], &set)) { + fds->fds[i] = -1; + count--; + } + } + + fds->count = count; + } return rc; } diff --git a/samsung-ipc/devices/crespo/crespo.c b/samsung-ipc/devices/crespo/crespo.c index 31bf273..3ddaa03 100644 --- a/samsung-ipc/devices/crespo/crespo.c +++ b/samsung-ipc/devices/crespo/crespo.c @@ -388,11 +388,14 @@ int crespo_write(void *data, const void *buffer, size_t length) return 0; } -int crespo_poll(void *data, struct timeval *timeout) +int crespo_poll(void *data, struct ipc_poll_fds *fds, struct timeval *timeout) { struct crespo_transport_data *transport_data; - fd_set fds; + fd_set set; int fd; + int fd_max; + unsigned int i; + unsigned int count; int rc; if (data == NULL) @@ -404,10 +407,37 @@ int crespo_poll(void *data, struct timeval *timeout) if (fd < 0) return -1; - FD_ZERO(&fds); - FD_SET(fd, &fds); + FD_ZERO(&set); + FD_SET(fd, &set); + + fd_max = fd; + + if (fds != NULL && fds->fds != NULL && fds->count > 0) { + for (i = 0; i < fds->count; i++) { + if (fds->fds[i] >= 0) { + FD_SET(fds->fds[i], &set); + + if (fds->fds[i] > fd_max) + fd_max = fds->fds[i]; + } + } + } + + rc = select(fd_max + 1, &set, NULL, NULL, timeout); + + if (fds != NULL && fds->fds != NULL && fds->count > 0) { + count = fds->count; + + for (i = 0; i < fds->count; i++) { + if (!FD_ISSET(fds->fds[i], &set)) { + fds->fds[i] = -1; + count--; + } + } + + fds->count = count; + } - rc = select(fd + 1, &fds, NULL, NULL, timeout); return rc; } diff --git a/samsung-ipc/devices/galaxys2/galaxys2.c b/samsung-ipc/devices/galaxys2/galaxys2.c index 19ddd73..672400f 100644 --- a/samsung-ipc/devices/galaxys2/galaxys2.c +++ b/samsung-ipc/devices/galaxys2/galaxys2.c @@ -290,7 +290,7 @@ int galaxys2_write(void *data, const void *buffer, size_t length) return rc; } -int galaxys2_poll(void *data, struct timeval *timeout) +int galaxys2_poll(void *data, struct ipc_poll_fds *fds, struct timeval *timeout) { struct galaxys2_transport_data *transport_data; int rc; @@ -300,7 +300,7 @@ int galaxys2_poll(void *data, struct timeval *timeout) transport_data = (struct galaxys2_transport_data *) data; - rc = xmm626_sec_modem_poll(transport_data->fd, timeout); + rc = xmm626_sec_modem_poll(transport_data->fd, fds, timeout); return rc; } diff --git a/samsung-ipc/devices/i9300/i9300.c b/samsung-ipc/devices/i9300/i9300.c index fafcbe4..b88db59 100644 --- a/samsung-ipc/devices/i9300/i9300.c +++ b/samsung-ipc/devices/i9300/i9300.c @@ -284,7 +284,7 @@ int i9300_write(void *data, const void *buffer, size_t length) return rc; } -int i9300_poll(void *data, struct timeval *timeout) +int i9300_poll(void *data, struct ipc_poll_fds *fds, struct timeval *timeout) { struct i9300_transport_data *transport_data; int rc; @@ -294,7 +294,7 @@ int i9300_poll(void *data, struct timeval *timeout) transport_data = (struct i9300_transport_data *) data; - rc = xmm626_sec_modem_poll(transport_data->fd, timeout); + rc = xmm626_sec_modem_poll(transport_data->fd, fds, timeout); return rc; } diff --git a/samsung-ipc/devices/maguro/maguro.c b/samsung-ipc/devices/maguro/maguro.c index dcc1bf3..f2cfb16 100644 --- a/samsung-ipc/devices/maguro/maguro.c +++ b/samsung-ipc/devices/maguro/maguro.c @@ -265,7 +265,7 @@ int maguro_write(void *data, const void *buffer, size_t length) return rc; } -int maguro_poll(void *data, struct timeval *timeout) +int maguro_poll(void *data, struct ipc_poll_fds *fds, struct timeval *timeout) { struct maguro_transport_data *transport_data; int rc; @@ -275,7 +275,7 @@ int maguro_poll(void *data, struct timeval *timeout) transport_data = (struct maguro_transport_data *) data; - rc = xmm626_sec_modem_poll(transport_data->fd, timeout); + rc = xmm626_sec_modem_poll(transport_data->fd, fds, timeout); return rc; } diff --git a/samsung-ipc/devices/n7100/n7100.c b/samsung-ipc/devices/n7100/n7100.c index cc3c73b..a6145d7 100644 --- a/samsung-ipc/devices/n7100/n7100.c +++ b/samsung-ipc/devices/n7100/n7100.c @@ -284,7 +284,7 @@ int n7100_write(void *data, const void *buffer, size_t length) return rc; } -int n7100_poll(void *data, struct timeval *timeout) +int n7100_poll(void *data, struct ipc_poll_fds *fds, struct timeval *timeout) { struct n7100_transport_data *transport_data; int rc; @@ -294,7 +294,7 @@ int n7100_poll(void *data, struct timeval *timeout) transport_data = (struct n7100_transport_data *) data; - rc = xmm626_sec_modem_poll(transport_data->fd, timeout); + rc = xmm626_sec_modem_poll(transport_data->fd, fds, timeout); return rc; } diff --git a/samsung-ipc/devices/piranha/piranha.c b/samsung-ipc/devices/piranha/piranha.c index b3df61d..00a564f 100644 --- a/samsung-ipc/devices/piranha/piranha.c +++ b/samsung-ipc/devices/piranha/piranha.c @@ -232,7 +232,7 @@ int piranha_write(void *data, const void *buffer, size_t length) return rc; } -int piranha_poll(void *data, struct timeval *timeout) +int piranha_poll(void *data, struct ipc_poll_fds *fds, struct timeval *timeout) { struct piranha_transport_data *transport_data; int rc; @@ -242,7 +242,7 @@ int piranha_poll(void *data, struct timeval *timeout) transport_data = (struct piranha_transport_data *) data; - rc = xmm626_sec_modem_poll(transport_data->fd, timeout); + rc = xmm626_sec_modem_poll(transport_data->fd, fds, timeout); return rc; } diff --git a/samsung-ipc/devices/xmm626/xmm626_sec_modem.c b/samsung-ipc/devices/xmm626/xmm626_sec_modem.c index 33b115d..dfdebdf 100644 --- a/samsung-ipc/devices/xmm626/xmm626_sec_modem.c +++ b/samsung-ipc/devices/xmm626/xmm626_sec_modem.c @@ -468,25 +468,56 @@ int xmm626_sec_modem_write(int fd, const void *buffer, size_t length) return rc; } -int xmm626_sec_modem_poll(int fd, struct timeval *timeout) +int xmm626_sec_modem_poll(int fd, struct ipc_poll_fds *fds, + struct timeval *timeout) { int status; - fd_set fds; + fd_set set; + int fd_max; + unsigned int i; + unsigned int count; int rc; if (fd < 0) return -1; - FD_ZERO(&fds); - FD_SET(fd, &fds); + FD_ZERO(&set); + FD_SET(fd, &set); - rc = select(fd + 1, &fds, NULL, NULL, timeout); - if (FD_ISSET(fd, &fds)) { + fd_max = fd; + + if (fds != NULL && fds->fds != NULL && fds->count > 0) { + for (i = 0; i < fds->count; i++) { + if (fds->fds[i] >= 0) { + FD_SET(fds->fds[i], &set); + + if (fds->fds[i] > fd_max) + fd_max = fds->fds[i]; + } + } + } + + rc = select(fd_max + 1, &set, NULL, NULL, timeout); + + if (FD_ISSET(fd, &set)) { status = ioctl(fd, IOCTL_MODEM_STATUS, 0); if (status != STATE_ONLINE && status != STATE_BOOTING) return -1; } + if (fds != NULL && fds->fds != NULL && fds->count > 0) { + count = fds->count; + + for (i = 0; i < fds->count; i++) { + if (!FD_ISSET(fds->fds[i], &set)) { + fds->fds[i] = -1; + count--; + } + } + + fds->count = count; + } + return rc; } diff --git a/samsung-ipc/devices/xmm626/xmm626_sec_modem.h b/samsung-ipc/devices/xmm626/xmm626_sec_modem.h index 728320e..9599a84 100644 --- a/samsung-ipc/devices/xmm626/xmm626_sec_modem.h +++ b/samsung-ipc/devices/xmm626/xmm626_sec_modem.h @@ -53,7 +53,8 @@ int xmm626_sec_modem_open(int type); int xmm626_sec_modem_close(int fd); int xmm626_sec_modem_read(int fd, void *buffer, size_t length); int xmm626_sec_modem_write(int fd, const void *buffer, size_t length); -int xmm626_sec_modem_poll(int fd, struct timeval *timeout); +int xmm626_sec_modem_poll(int fd, struct ipc_poll_fds *fds, + struct timeval *timeout); char *xmm626_sec_modem_gprs_get_iface(unsigned int cid); int xmm626_sec_modem_gprs_get_capabilities(struct ipc_client_gprs_capabilities *capabilities); diff --git a/samsung-ipc/ipc.c b/samsung-ipc/ipc.c index 5db8f4d..b3ee679 100644 --- a/samsung-ipc/ipc.c +++ b/samsung-ipc/ipc.c @@ -225,7 +225,7 @@ int ipc_client_transport_handlers_register(struct ipc_client *client, int (*close)(void *transport_data), int (*read)(void *transport_data, void *data, size_t size), int (*write)(void *transport_data, const void *data, size_t size), - int (*poll)(void *transport_data, struct timeval *timeout), + int (*poll)(void *transport_data, struct ipc_poll_fds *fds, struct timeval *timeout), void *transport_data) { if (client == NULL || client->handlers == NULL) @@ -358,12 +358,12 @@ int ipc_client_close(struct ipc_client *client) return client->handlers->close(client->handlers->transport_data); } -int ipc_client_poll(struct ipc_client *client, struct timeval *timeout) +int ipc_client_poll(struct ipc_client *client, struct ipc_poll_fds *fds, struct timeval *timeout) { if (client == NULL || client->handlers == NULL || client->handlers->poll == NULL) return -1; - return client->handlers->poll(client->handlers->transport_data, timeout); + return client->handlers->poll(client->handlers->transport_data, fds, timeout); } int ipc_client_power_on(struct ipc_client *client) diff --git a/samsung-ipc/ipc.h b/samsung-ipc/ipc.h index 5808aa1..60fca12 100644 --- a/samsung-ipc/ipc.h +++ b/samsung-ipc/ipc.h @@ -43,7 +43,7 @@ struct ipc_client_handlers { int (*read)(void *transport_data, void *buffer, size_t length); int (*write)(void *transport_data, const void *buffer, size_t length); - int (*poll)(void *transport_data, struct timeval *timeout); + int (*poll)(void *transport_data, struct ipc_poll_fds *fds, struct timeval *timeout); void *transport_data; -- cgit v1.1