X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=hardware%2Fcommon%2Fserial.c;h=891fd02d3729e43b235f8e1b404ed2642ee8482e;hb=34ea7f9695794ea4654b26dd4aa6b79cdee90b71;hp=0d26b46452f9cccefb0a951b8de22e383794d68f;hpb=cb7b165b3dc073c49729173132a37203e9d98838;p=libsigrok.git diff --git a/hardware/common/serial.c b/hardware/common/serial.c index 0d26b464..891fd02d 100644 --- a/hardware/common/serial.c +++ b/hardware/common/serial.c @@ -638,25 +638,69 @@ SR_PRIV int sr_serial_extract_options(GSList *options, const char **serial_devic return SR_OK; } -SR_PRIV int serial_source_add(struct sr_serial_dev_inst *serial, int events, - int timeout, sr_receive_data_callback_t cb, void *cb_data) -{ #ifdef _WIN32 - return SR_ERR; +typedef HANDLE event_handle; #else - int fd; - sp_get_port_handle(serial->data, &fd); - return sr_source_add(fd, events, timeout, cb, cb_data); +typedef int event_handle; #endif + +SR_PRIV int serial_source_add(struct sr_serial_dev_inst *serial, int events, + int timeout, sr_receive_data_callback_t cb, void *cb_data) +{ + enum sp_event mask = 0; + unsigned int i; + + if (sp_new_event_set(&serial->event_set) != SP_OK) + return SR_ERR; + + if (events & G_IO_IN) + mask |= SP_EVENT_RX_READY; + if (events & G_IO_OUT) + mask |= SP_EVENT_TX_READY; + if (events & G_IO_ERR) + mask |= SP_EVENT_ERROR; + + if (sp_add_port_events(serial->event_set, serial->data, mask) != SP_OK) { + sp_free_event_set(serial->event_set); + return SR_ERR; + } + + serial->pollfds = (GPollFD *) g_malloc0(sizeof(GPollFD) * serial->event_set->count); + + for (i = 0; i < serial->event_set->count; i++) { + + serial->pollfds[i].fd = ((event_handle *) serial->event_set->handles)[i]; + + mask = serial->event_set->masks[i]; + + if (mask & SP_EVENT_RX_READY) + serial->pollfds[i].events |= G_IO_IN; + if (mask & SP_EVENT_TX_READY) + serial->pollfds[i].events |= G_IO_OUT; + if (mask & SP_EVENT_ERROR) + serial->pollfds[i].events |= G_IO_ERR; + + if (sr_session_source_add_pollfd(&serial->pollfds[i], + timeout, cb, cb_data) != SR_OK) + return SR_ERR; + } + + return SR_OK; } SR_PRIV int serial_source_remove(struct sr_serial_dev_inst *serial) { -#ifdef _WIN32 - return SR_ERR; -#else - int fd; - sp_get_port_handle(serial->data, &fd); - return sr_source_remove(fd); -#endif + unsigned int i; + + for (i = 0; i < serial->event_set->count; i++) + if (sr_session_source_remove_pollfd(&serial->pollfds[i]) != SR_OK) + return SR_ERR; + + g_free(serial->pollfds); + sp_free_event_set(serial->event_set); + + serial->pollfds = NULL; + serial->event_set = NULL; + + return SR_OK; }