From cc727b6a7eb13d07546a6fab5c6793348f7e4a59 Mon Sep 17 00:00:00 2001 From: szykula Date: Thu, 23 May 2024 16:24:19 +0200 Subject: [PATCH] Fixed the Windows builds - patched the USB polling mechanism under Windows (currently does not support hot plugging) - fixed the CMakeLists.txt MinGW support - added the CLion-specific git ignores --- .gitignore | 4 + CMakeLists.txt | 35 +++++- libsigrok4DSL/hardware/DSL/dscope.c | 35 +----- libsigrok4DSL/hardware/DSL/dsl.c | 14 +++ libsigrok4DSL/hardware/DSL/dslogic.c | 34 +---- libsigrok4DSL/hwdriver.c | 15 +-- libsigrok4DSL/libsigrok-internal.h | 20 +-- libsigrok4DSL/session.c | 178 +++++---------------------- libsigrok4DSL/std.c | 61 --------- 9 files changed, 89 insertions(+), 307 deletions(-) diff --git a/.gitignore b/.gitignore index 81fa4def..4e037528 100644 --- a/.gitignore +++ b/.gitignore @@ -59,3 +59,7 @@ qtpro5 win32x qrc_* install_manifest.txt + +# CLion-specific +.idea/ +cmake-build*/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 7b8cf57d..c20499be 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -182,14 +182,20 @@ find_package(Qt5Core QUIET) if(Qt5Core_FOUND) message("----- Qt5:") message(STATUS " includes:" ${Qt5Core_INCLUDE_DIRS}) - #find_package(Qt5WinExtras REQUIRED) + if (WIN32) + find_package(Qt5WinExtras REQUIRED) + endif () + find_package(Qt5Svg REQUIRED) find_package(Qt5Widgets REQUIRED) find_package(Qt5Gui REQUIRED) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}") - #set(QT_INCLUDE_DIRS ${Qt5Gui_INCLUDE_DIRS} ${Qt5Widgets_INCLUDE_DIRS} ${Qt5WinExtras_INCLUDE_DIRS}) - #set(QT_LIBRARIES Qt5::Gui Qt5::Widgets Qt5::WinExtras) - set(QT_INCLUDE_DIRS ${Qt5Gui_INCLUDE_DIRS} ${Qt5Widgets_INCLUDE_DIRS}) - set(QT_LIBRARIES Qt5::Gui Qt5::Widgets) + if (WIN32) + set(QT_INCLUDE_DIRS ${Qt5Gui_INCLUDE_DIRS} ${Qt5Widgets_INCLUDE_DIRS} ${Qt5WinExtras_INCLUDE_DIRS}) + set(QT_LIBRARIES Qt5::Gui Qt5::Widgets Qt5::WinExtras Qt5::WinMain Qt5::Svg) + else () + set(QT_INCLUDE_DIRS ${Qt5Gui_INCLUDE_DIRS} ${Qt5Widgets_INCLUDE_DIRS}) + set(QT_LIBRARIES Qt5::Gui Qt5::Widgets Qt5::Svg) + endif () add_definitions(${Qt5Gui_DEFINITIONS} ${Qt5Widgets_DEFINITIONS}) else() find_package(Qt6Core QUIET) @@ -353,6 +359,14 @@ set(DSView_SOURCES DSView/pv/ui/popupdlglist.cpp ) +# Windows-specific QT source files +if(WIN32) + list(APPEND DSView_SOURCES + DSView/pv/winnativewidget.cpp + DSView/pv/winshadow.cpp + ) +endif () + set(DSView_HEADERS DSView/mystyle.h DSView/pv/log.h @@ -447,6 +461,14 @@ set(DSView_HEADERS DSView/pv/ui/xtoolbutton.h ) +# Windows-specific QT headers +if(WIN32) + list(APPEND DSView_HEADERS + DSView/pv/winnativewidget.h + DSView/pv/winshadow.h + ) +endif () + #=============================================================================== #= libsigrok4DSL source #------------------------------------------------------------------------------- @@ -552,6 +574,8 @@ if(WIN32) enable_language(RC) # app icon list(APPEND DSView_SOURCES applogo.rc) + # MinGW Unicode support + add_definitions(-municode) endif() if(Qt5Core_FOUND) @@ -599,7 +623,6 @@ set(CMAKE_CXX_FLAGS "-Wall -Wextra") set(CMAKE_BUILD_TYPE Release) set(CMAKE_CXX_FLAGS_DEBUG "-g") set(CMAKE_CXX_FLAGS_RELEASE "-O3") -add_compile_options(-O3) #=============================================================================== #= Linker Configuration diff --git a/libsigrok4DSL/hardware/DSL/dscope.c b/libsigrok4DSL/hardware/DSL/dscope.c index c7bcdd53..5c5a8280 100644 --- a/libsigrok4DSL/hardware/DSL/dscope.c +++ b/libsigrok4DSL/hardware/DSL/dscope.c @@ -1897,16 +1897,6 @@ static int cleanup(void) return SR_OK; } -static void remove_sources(struct DSL_context *devc) -{ - int i; - sr_info("%s: remove fds from polling", __func__); - /* Remove fds from polling. */ - for (i = 0; devc->usbfd[i] != -1; i++) - sr_source_remove(devc->usbfd[i]); - g_free(devc->usbfd); -} - static int receive_data(int fd, int revents, const struct sr_dev_inst *sdi) { int completed = 0; @@ -1953,7 +1943,7 @@ static int receive_data(int fd, int revents, const struct sr_dev_inst *sdi) } if (devc->status == DSL_FINISH) { - remove_sources(devc); + sr_session_source_remove((gintptr) devc->channel); } devc->trf_completed = 0; @@ -1966,9 +1956,6 @@ static int dev_acquisition_start(struct sr_dev_inst *sdi, void *cb_data) struct DSL_context *devc; struct sr_usb_dev_inst *usb; - struct drv_context *drvc; - const struct libusb_pollfd **lupfd; - unsigned int i; int ret; struct ctl_wr_cmd wr_cmd; GSList *l; @@ -1978,7 +1965,6 @@ static int dev_acquisition_start(struct sr_dev_inst *sdi, void *cb_data) return SR_ERR_DEVICE_CLOSED; } - drvc = di->priv; devc = sdi->priv; usb = sdi->conn; @@ -2087,23 +2073,8 @@ static int dev_acquisition_start(struct sr_dev_inst *sdi, void *cb_data) return ret; } - /* setup callback function for data transfer */ - lupfd = libusb_get_pollfds(drvc->sr_ctx->libusb_ctx); - for (i = 0; lupfd[i]; i++); - - if (!(devc->usbfd = malloc(sizeof(struct libusb_pollfd) * (i + 1)))){ - sr_err("%s,ERROR:failed to alloc memory.", __func__); - return SR_ERR; - } - - for (i = 0; lupfd[i]; i++) { - sr_source_add(lupfd[i]->fd, lupfd[i]->events, - dsl_get_timeout(sdi), receive_data, sdi); - devc->usbfd[i] = lupfd[i]->fd; - } - - devc->usbfd[i] = -1; - free(lupfd); + sr_session_source_add ((gintptr) devc->channel, G_IO_IN | G_IO_ERR, + (int) dsl_get_timeout(sdi), receive_data, sdi); wr_cmd.header.dest = DSL_CTL_START; wr_cmd.header.size = 0; diff --git a/libsigrok4DSL/hardware/DSL/dsl.c b/libsigrok4DSL/hardware/DSL/dsl.c index 38ffde67..d507d618 100644 --- a/libsigrok4DSL/hardware/DSL/dsl.c +++ b/libsigrok4DSL/hardware/DSL/dsl.c @@ -1955,6 +1955,20 @@ SR_PRIV int dsl_dev_open(struct sr_dev_driver *di, struct sr_dev_inst *sdi, gboo return SR_ERR; } + if (sdi->status == SR_ST_ACTIVE) { + ret = _pipe(devc->pipe_fds,0x1000,0x8000); + if (ret != SR_OK) { + sr_err("%s: pipe() failed", __func__); + return SR_ERR; + } + GIOChannel *new_channel; + new_channel = g_io_channel_unix_new(devc->pipe_fds[0]); + devc->channel = new_channel; + g_io_channel_set_flags(new_channel, 2, NULL); + g_io_channel_set_encoding(devc->channel,NULL,NULL); + g_io_channel_set_buffered(devc->channel,FALSE); + } + if (devc->profile->dev_caps.feature_caps & CAPS_FEATURE_SECURITY) { ret = dsl_secuCheck(sdi, encryption, SECU_STEPS); if (ret != SR_OK){ diff --git a/libsigrok4DSL/hardware/DSL/dslogic.c b/libsigrok4DSL/hardware/DSL/dslogic.c index 3906acc7..2cc0cf01 100644 --- a/libsigrok4DSL/hardware/DSL/dslogic.c +++ b/libsigrok4DSL/hardware/DSL/dslogic.c @@ -1312,16 +1312,6 @@ static int cleanup(void) return SR_OK; } -static void remove_sources(struct DSL_context *devc) -{ - int i; - sr_info("%s: remove fds from polling", __func__); - /* Remove fds from polling. */ - for (i = 0; devc->usbfd[i] != -1; i++) - sr_source_remove(devc->usbfd[i]); - g_free(devc->usbfd); -} - static void report_overflow(struct DSL_context *devc) { struct sr_datafeed_packet packet; @@ -1396,7 +1386,7 @@ static int receive_data(int fd, int revents, const struct sr_dev_inst *sdi) if (devc->status == DSL_FINISH) { /* Remove polling */ - remove_sources(devc); + sr_session_source_remove((gintptr) devc->channel); } devc->trf_completed = 0; @@ -1409,9 +1399,6 @@ static int dev_acquisition_start(struct sr_dev_inst *sdi, void *cb_data) struct DSL_context *devc; struct sr_usb_dev_inst *usb; - struct drv_context *drvc; - const struct libusb_pollfd **lupfd; - unsigned int i; int ret; struct ctl_wr_cmd wr_cmd; @@ -1420,7 +1407,6 @@ static int dev_acquisition_start(struct sr_dev_inst *sdi, void *cb_data) return SR_ERR_DEVICE_CLOSED; } - drvc = di->priv; devc = sdi->priv; usb = sdi->conn; @@ -1485,22 +1471,8 @@ static int dev_acquisition_start(struct sr_dev_inst *sdi, void *cb_data) return ret; } - /* setup callback function for data transfer */ - lupfd = libusb_get_pollfds(drvc->sr_ctx->libusb_ctx); - for (i = 0; lupfd[i]; i++); - - if (!(devc->usbfd = malloc(sizeof(struct libusb_pollfd) * (i + 1)))){ - sr_err("%s,ERROR:failed to alloc memory.", __func__); - return SR_ERR; - } - - for (i = 0; lupfd[i]; i++) { - sr_source_add(lupfd[i]->fd, lupfd[i]->events, - dsl_get_timeout(sdi), receive_data, sdi); - devc->usbfd[i] = lupfd[i]->fd; - } - devc->usbfd[i] = -1; - free(lupfd); + sr_session_source_add ((gintptr) devc->channel, G_IO_IN | G_IO_ERR, + (int) dsl_get_timeout(sdi), receive_data, sdi); wr_cmd.header.dest = DSL_CTL_START; wr_cmd.header.size = 0; diff --git a/libsigrok4DSL/hwdriver.c b/libsigrok4DSL/hwdriver.c index d9d7c32a..310020e9 100644 --- a/libsigrok4DSL/hwdriver.c +++ b/libsigrok4DSL/hwdriver.c @@ -366,21 +366,8 @@ SR_PRIV int sr_status_get(const struct sr_dev_inst *sdi, /* Unnecessary level of indirection follows. */ -/** @private */ -SR_PRIV int sr_source_remove(int fd) -{ - return sr_session_source_remove(fd); -} - -/** @private */ -SR_PRIV int sr_source_add(int fd, int events, int timeout, - sr_receive_data_callback_t cb, void *cb_data) -{ - return sr_session_source_add(fd, events, timeout, cb, cb_data); -} - SR_PRIV int ds_scan_all_device_list(libusb_context *usb_ctx,struct libusb_device **list_buf, int size, int *count) -{ +{ libusb_device **devlist; int i; int wr; diff --git a/libsigrok4DSL/libsigrok-internal.h b/libsigrok4DSL/libsigrok-internal.h index 67f79bdb..c3ab084d 100644 --- a/libsigrok4DSL/libsigrok-internal.h +++ b/libsigrok4DSL/libsigrok-internal.h @@ -287,24 +287,17 @@ SR_PRIV void sr_serial_dev_inst_free(struct sr_serial_dev_inst *serial); typedef int (*sr_receive_data_callback_t)(int fd, int revents, const struct sr_dev_inst *sdi); SR_PRIV void sr_hw_cleanup_all(void); -SR_PRIV int sr_source_remove(int fd); -SR_PRIV int sr_source_add(int fd, int events, int timeout, - sr_receive_data_callback_t cb, void *cb_data); /*--- session.c -------------------------------------------------------------*/ SR_PRIV int usb_hotplug_callback(struct libusb_context *ctx, struct libusb_device *dev, libusb_hotplug_event event, void *user_data); -SR_PRIV int sr_session_source_add(int fd, int events, int timeout, - sr_receive_data_callback_t cb, const struct sr_dev_inst *sdi); -SR_PRIV int sr_session_source_add_pollfd(GPollFD *pollfd, int timeout, - sr_receive_data_callback_t cb, const struct sr_dev_inst *sdi); -SR_PRIV int sr_session_source_add_channel(GIOChannel *channel, int events, - int timeout, sr_receive_data_callback_t cb, const struct sr_dev_inst *sdi); -SR_PRIV int sr_session_source_remove(int fd); -SR_PRIV int sr_session_source_remove_pollfd(GPollFD *pollfd); -SR_PRIV int sr_session_source_remove_channel(GIOChannel *channel); +SR_PRIV int sr_session_source_add(gintptr poll_object, int events, + int timeout, + sr_receive_data_callback_t cb, + const struct sr_dev_inst *sdi); +SR_PRIV int sr_session_source_remove(gintptr poll_object); /*--- std.c -----------------------------------------------------------------*/ @@ -312,9 +305,6 @@ typedef int (*dev_close_t)(struct sr_dev_inst *sdi); SR_PRIV int std_hw_init(struct sr_context *sr_ctx, struct sr_dev_driver *di, const char *prefix); -SR_PRIV int std_hw_dev_acquisition_stop_serial(struct sr_dev_inst *sdi, - void *cb_data, dev_close_t hw_dev_close_fn, - struct sr_serial_dev_inst *serial, const char *prefix); SR_PRIV int std_session_send_df_header(const struct sr_dev_inst *sdi, const char *prefix); diff --git a/libsigrok4DSL/session.c b/libsigrok4DSL/session.c index 23a1864b..79ccfcee 100644 --- a/libsigrok4DSL/session.c +++ b/libsigrok4DSL/session.c @@ -260,68 +260,6 @@ SR_PRIV int sr_session_stop(void) return SR_OK; } -/** - * Debug helper. - * - * @param packet The packet to show debugging information for. - */ - -/* -static void datafeed_dump(const struct sr_datafeed_packet *packet) -{ - const struct sr_datafeed_logic *logic; - const struct sr_datafeed_dso *dso; - const struct sr_datafeed_analog *analog; - - if (packet == NULL){ - sr_err("datafeed_dump() Error! packet is null."); - return; - } - - switch (packet->type) { - case SR_DF_HEADER: - sr_dbg("bus: Received SR_DF_HEADER packet."); - break; - case SR_DF_TRIGGER: - sr_dbg("bus: Received SR_DF_TRIGGER packet."); - break; - case SR_DF_META: - sr_dbg("bus: Received SR_DF_META packet."); - break; - case SR_DF_LOGIC: - logic = packet->payload; - sr_dbg("bus: Received SR_DF_LOGIC packet (%llu bytes).", - (u64_t)logic->length); - break; - case SR_DF_DSO: - dso = packet->payload; - sr_dbg("bus: Received SR_DF_DSO packet (%d samples).", - dso->num_samples); - break; - case SR_DF_ANALOG: - analog = packet->payload; - sr_dbg("bus: Received SR_DF_ANALOG packet (%d samples).", - analog->num_samples); - break; - case SR_DF_END: - sr_dbg("bus: Received SR_DF_END packet."); - break; - case SR_DF_FRAME_BEGIN: - sr_dbg("bus: Received SR_DF_FRAME_BEGIN packet."); - break; - case SR_DF_FRAME_END: - sr_dbg("bus: Received SR_DF_FRAME_END packet."); - break; - case SR_DF_OVERFLOW: - sr_dbg("bus: Received SR_DF_OVERFLOW packet."); - break; - default: - sr_dbg("bus: Received unknown packet type: %d.", packet->type); - break; - } -} -*/ - /** * Add an event source for a file descriptor. * @@ -329,13 +267,13 @@ static void datafeed_dump(const struct sr_datafeed_packet *packet) * @param timeout Max time to wait before the callback is called, ignored if 0. * @param cb Callback function to add. Must not be NULL. * @param cb_data Data for the callback function. Can be NULL. - * @param poll_object TODO. + * @param poll_object Object responsible for the event source. * * @return SR_OK upon success, SR_ERR_ARG upon invalid arguments, or * SR_ERR_MALLOC upon memory allocation errors. */ -static int _sr_session_source_add(GPollFD *pollfd, int timeout, - sr_receive_data_callback_t cb, const struct sr_dev_inst *sdi, gintptr poll_object) +static int sr_session_source_add_internal(GPollFD *pollfd, int timeout, + sr_receive_data_callback_t cb, const struct sr_dev_inst *sdi, gintptr poll_object) { struct source *new_sources, *s; GPollFD *new_pollfds; @@ -345,7 +283,7 @@ static int _sr_session_source_add(GPollFD *pollfd, int timeout, return SR_ERR_ARG; } if (session == NULL){ - sr_err("_sr_session_source_add(), session is null."); + sr_err("sr_session_source_add_internal(), session is null."); return SR_ERR_CALL_STATUS; } @@ -384,7 +322,7 @@ static int _sr_session_source_add(GPollFD *pollfd, int timeout, /** * Add an event source for a file descriptor. * - * @param fd The file descriptor. + * @param poll_object Pointer to the polled object. * @param events Events to check for. * @param timeout Max time to wait before the callback is called, ignored if 0. * @param cb Callback function to add. Must not be NULL. @@ -393,60 +331,32 @@ static int _sr_session_source_add(GPollFD *pollfd, int timeout, * @return SR_OK upon success, SR_ERR_ARG upon invalid arguments, or * SR_ERR_MALLOC upon memory allocation errors. */ -SR_PRIV int sr_session_source_add(int fd, int events, int timeout, - sr_receive_data_callback_t cb, const struct sr_dev_inst *sdi) -{ - GPollFD p; - - p.fd = fd; - p.events = events; - - return _sr_session_source_add(&p, timeout, cb, sdi, (gintptr)fd); -} - -/** - * Add an event source for a GPollFD. - * - * @param pollfd The GPollFD. - * @param timeout Max time to wait before the callback is called, ignored if 0. - * @param cb Callback function to add. Must not be NULL. - * @param cb_data Data for the callback function. Can be NULL. - * - * @return SR_OK upon success, SR_ERR_ARG upon invalid arguments, or - * SR_ERR_MALLOC upon memory allocation errors. - */ -SR_PRIV int sr_session_source_add_pollfd(GPollFD *pollfd, int timeout, - sr_receive_data_callback_t cb, const struct sr_dev_inst *sdi) -{ - return _sr_session_source_add(pollfd, timeout, cb, - sdi, (gintptr)pollfd); -} - -/** - * Add an event source for a GIOChannel. - * - * @param channel The GIOChannel. - * @param events Events to poll on. - * @param timeout Max time to wait before the callback is called, ignored if 0. - * @param cb Callback function to add. Must not be NULL. - * @param cb_data Data for the callback function. Can be NULL. - * - * @return SR_OK upon success, SR_ERR_ARG upon invalid arguments, or - * SR_ERR_MALLOC upon memory allocation errors. - */ -SR_PRIV int sr_session_source_add_channel(GIOChannel *channel, int events, - int timeout, sr_receive_data_callback_t cb, const struct sr_dev_inst *sdi) +SR_PRIV int sr_session_source_add(gintptr poll_object, int events, + int timeout, + sr_receive_data_callback_t cb, + const struct sr_dev_inst *sdi) { GPollFD p; -#ifdef _WIN32 - g_io_channel_win32_make_pollfd(channel, events, &p); +#ifdef WIN32 + if(poll_object > 0) + { + /* poll_object points to a valid GIOChannel */ + g_io_channel_win32_make_pollfd((GIOChannel *) poll_object,events,&p); + } + else + { + /* poll_object is not a valid descriptor */ + p.fd = (gint64) poll_object; + p.events = events; + } #else - p.fd = g_io_channel_unix_get_fd(channel); + p.fd = (gint64) poll_object; p.events = events; #endif - return _sr_session_source_add(&p, timeout, cb, sdi, (gintptr)channel); + return sr_session_source_add_internal(&p, timeout, cb, sdi, + poll_object); } /** @@ -454,20 +364,20 @@ SR_PRIV int sr_session_source_add_channel(GIOChannel *channel, int events, * * @todo Add more error checks and logging. * - * @param channel The channel for which the source should be removed. + * @param poll_object The object for which the source should be removed. * * @return SR_OK upon success, SR_ERR_ARG upon invalid arguments, or * SR_ERR_MALLOC upon memory allocation errors, SR_ERR_BUG upon * internal errors. */ -static int _sr_session_source_remove(gintptr poll_object) +static int sr_session_source_remove_internal(gintptr poll_object) { struct source *new_sources; GPollFD *new_pollfds; unsigned int old; if (session == NULL){ - sr_err("_sr_session_source_remove(), session is null."); + sr_err("sr_session_source_remove_internal(), session is null."); return SR_ERR_CALL_STATUS; } @@ -524,43 +434,15 @@ static int _sr_session_source_remove(gintptr poll_object) /** * Remove the source belonging to the specified file descriptor. * - * @param fd The file descriptor for which the source should be removed. - * - * @return SR_OK upon success, SR_ERR_ARG upon invalid arguments, or - * SR_ERR_MALLOC upon memory allocation errors, SR_ERR_BUG upon - * internal errors. - */ -SR_PRIV int sr_session_source_remove(int fd) -{ - return _sr_session_source_remove((gintptr)fd); -} - -/** - * Remove the source belonging to the specified poll descriptor. - * - * @param pollfd The poll descriptor for which the source should be removed. + * @param poll_object The object for which the source should be removed. * * @return SR_OK upon success, SR_ERR_ARG upon invalid arguments, or * SR_ERR_MALLOC upon memory allocation errors, SR_ERR_BUG upon * internal errors. */ -SR_PRIV int sr_session_source_remove_pollfd(GPollFD *pollfd) +SR_PRIV int sr_session_source_remove(gintptr poll_object) { - return _sr_session_source_remove((gintptr)pollfd); + return sr_session_source_remove_internal(poll_object); } -/** - * Remove the source belonging to the specified channel. - * - * @param channel The channel for which the source should be removed. - * - * @return SR_OK upon success, SR_ERR_ARG upon invalid arguments, or - * SR_ERR_MALLOC upon memory allocation errors, SR_ERR_BUG upon - * internal errors. - */ -SR_PRIV int sr_session_source_remove_channel(GIOChannel *channel) -{ - return _sr_session_source_remove((gintptr)channel); -} - /** @} */ diff --git a/libsigrok4DSL/std.c b/libsigrok4DSL/std.c index 8ec46001..a3b8ecaa 100644 --- a/libsigrok4DSL/std.c +++ b/libsigrok4DSL/std.c @@ -102,64 +102,3 @@ SR_PRIV int std_session_send_df_header(const struct sr_dev_inst *sdi, return SR_OK; } - -/* - * Standard sr_session_stop() API helper. - * - * This function can be used to simplify most (serial port based) driver's - * hw_dev_acquisition_stop() API callback. - * - * @param sdi The device instance for which acquisition should stop. - * Must not be NULL. - * @param cb_data Opaque 'cb_data' pointer. Must not be NULL. - * @param hw_dev_close_fn Function pointer to the driver's hw_dev_close(). - * Must not be NULL. - * @param serial The serial device instance (struct serial_dev_inst *). - * Must not be NULL. - * @param prefix A driver-specific prefix string used for log messages. - * Must not be NULL. An empty string is allowed. - * - * @return SR_OK upon success, SR_ERR_ARG upon invalid arguments, or - * SR_ERR upon other errors. - */ -SR_PRIV int std_hw_dev_acquisition_stop_serial(struct sr_dev_inst *sdi, - void *cb_data, dev_close_t hw_dev_close_fn, - struct sr_serial_dev_inst *serial, const char *prefix) -{ - int ret; - struct sr_datafeed_packet packet; - - if (!prefix) { - sr_err("Invalid prefix."); - return SR_ERR_ARG; - } - - if (sdi->status != SR_ST_ACTIVE) { - sr_err("%sDevice inactive, can't stop acquisition.", prefix); - return SR_ERR; - } - - sr_dbg("%sStopping acquisition.", prefix); - - if ((ret = sr_source_remove(serial->fd)) < 0) { - sr_err("%sFailed to remove source: %d.", prefix, ret); - return ret; - } - - if ((ret = hw_dev_close_fn(sdi)) < 0) { - sr_err("%sFailed to close device: %d.", prefix, ret); - return ret; - } - - /* Send SR_DF_END packet to the session bus. */ - sr_dbg("%sSending SR_DF_END packet.", prefix); - packet.type = SR_DF_END; - packet.status = SR_PKT_OK; - packet.payload = NULL; - if ((ret = ds_data_forward(cb_data, &packet)) < 0) { - sr_err("%sFailed to send SR_DF_END packet: %d.", prefix, ret); - return ret; - } - - return SR_OK; -} \ No newline at end of file