diff --git a/.gitignore b/.gitignore index 40b6e41c..39aceca8 100644 --- a/.gitignore +++ b/.gitignore @@ -56,3 +56,4 @@ test qtpro5 .DS_Store .qt +win32x diff --git a/libsigrok4DSL/backend.c b/libsigrok4DSL/backend.c index e617496b..e53043c8 100644 --- a/libsigrok4DSL/backend.c +++ b/libsigrok4DSL/backend.c @@ -409,6 +409,11 @@ SR_PRIV int sr_listen_hotplug(struct sr_context *ctx, hotplug_event_callback cal ctx->hotplug_callback = callback; + // Call user custom function. + if (ctx->listen_hotplug_ext != NULL){ + return ctx->listen_hotplug_ext(ctx); + } + ret = libusb_hotplug_register_callback(ctx->libusb_ctx, (libusb_hotplug_event)(LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT), (libusb_hotplug_flag)LIBUSB_HOTPLUG_ENUMERATE, @@ -432,6 +437,12 @@ SR_PRIV int sr_close_hotplug(struct sr_context *ctx) return SR_ERR; } sr_info("%s", "Unregister hotplug callback."); + + // Call user custom function. + if (ctx->close_hotplug_ext != NULL){ + return ctx->close_hotplug_ext(ctx); + } + libusb_hotplug_deregister_callback(ctx->libusb_ctx, ctx->hotplug_handle); return 0; @@ -442,7 +453,14 @@ SR_PRIV void sr_hotplug_wait_timout(struct sr_context *ctx) if (!ctx) { sr_err("%s(): libsigrok context was NULL.", __func__); return; - } + } + + // Call user custom function. + if (ctx->hotplug_wait_timout_ext != NULL){ + ctx->hotplug_wait_timout_ext(ctx); + return; + } + libusb_handle_events_timeout(ctx->libusb_ctx, &ctx->hotplug_tv); } diff --git a/libsigrok4DSL/config.h b/libsigrok4DSL/config.h index 1c40c8d3..9550e6b3 100644 --- a/libsigrok4DSL/config.h +++ b/libsigrok4DSL/config.h @@ -189,4 +189,9 @@ such a type exists and the standard includes do not define it. */ /* #undef uint8_t */ + +#ifdef _WIN32 + //#define HAVE_EXTERN_INIT +#endif + #endif /* SR_CONFIG_H */ diff --git a/libsigrok4DSL/hwdriver.c b/libsigrok4DSL/hwdriver.c index c292e42a..8e690a59 100644 --- a/libsigrok4DSL/hwdriver.c +++ b/libsigrok4DSL/hwdriver.c @@ -26,6 +26,7 @@ #include #include "config.h" /* Needed for HAVE_LIBUSB_1_0 and others. */ #include "log.h" +#include #undef LOG_PREFIX #define LOG_PREFIX "hwdriver: " @@ -371,4 +372,46 @@ SR_PRIV int sr_source_add(int fd, int events, int timeout, 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; + int ret; + struct libusb_device_descriptor des; + + assert(list_buf); + assert(count); + assert(usb_ctx); + + devlist = NULL; + wr = 0; + libusb_get_device_list(usb_ctx, &devlist); + + for (i = 0; devlist[i]; i++) + { + ret = libusb_get_device_descriptor(devlist[i], &des); + if (ret != 0) { + sr_warn("Failed to get device descriptor: %s.", libusb_error_name(ret)); + continue; + } + + if (des.idVendor == 0x2A0E){ + if (wr >= size){ + sr_err("%s", "ds_scan_all_device_list(), buffer length is too short."); + assert(0); + } + + list_buf[wr] = devlist[i]; + wr++; + } + } + + *count = wr; + + libusb_free_device_list(devlist, 1); + + return SR_OK; +} + /** @} */ diff --git a/libsigrok4DSL/lib_main.c b/libsigrok4DSL/lib_main.c index 43307aa6..97629de0 100644 --- a/libsigrok4DSL/lib_main.c +++ b/libsigrok4DSL/lib_main.c @@ -24,6 +24,7 @@ #include #include #include +#include "config.h" #ifdef _WIN32 #include @@ -33,6 +34,8 @@ #define _sleep(m) usleep((m)*1000) #endif +#define MAX_DEVCIE_LIST_LENGTH 20 + #undef LOG_PREFIX #define LOG_PREFIX "lib_main: " @@ -69,6 +72,8 @@ static void collect_run_proc(); static void post_event_async(int event); static void send_event(int event); static void make_demo_device_to_list(); +static struct libusb_device* get_new_attached_usb_device(); +static struct libusb_device* get_new_detached_usb_device(); static struct sr_lib_context lib_ctx = { .event_callback = NULL, @@ -134,6 +139,19 @@ SR_API int ds_lib_init() lib_ctx.sr_ctx->hotplug_tv.tv_sec = 0; lib_ctx.sr_ctx->hotplug_tv.tv_usec = 0; + + /** + * User can use custom hotplug function. + */ + lib_ctx.sr_ctx->listen_hotplug_ext = NULL; + lib_ctx.sr_ctx->close_hotplug_ext = NULL; + lib_ctx.sr_ctx->hotplug_wait_timout_ext = NULL; + +#ifdef _WIN32 + #ifdef HAVE_EXTERN_INIT + lib_extern_init(lib_ctx.sr_ctx); + #endif +#endif sr_listen_hotplug(lib_ctx.sr_ctx, hotplug_event_listen_callback); @@ -143,6 +161,12 @@ SR_API int ds_lib_init() return SR_OK; } +#ifndef _WIN32 +SR_PRIV int lib_extern_init(struct sr_context *ctx){ + return SR_OK; +} +#endif + /** * Free all resource before program exits */ @@ -1020,6 +1044,7 @@ SR_PRIV int sr_usb_device_is_exists(libusb_device *usb_dev) if (dev->handle == (ds_device_handle)usb_dev) { bFind = 1; + break; } } @@ -1126,9 +1151,15 @@ static int update_device_handle(struct libusb_device *old_dev, struct libusb_dev static void hotplug_event_listen_callback(struct libusb_context *ctx, struct libusb_device *dev, int event) { int bDone = 0; + + if (dev == NULL){ + if (event == USB_EV_HOTPLUG_ATTACH) + dev = get_new_attached_usb_device(); + else + dev = get_new_detached_usb_device(); + } - if (dev == NULL) - { + if (dev == NULL){ sr_err("%s", "hotplug_event_listen_callback(), @dev is null."); return; } @@ -1464,4 +1495,97 @@ static void send_event(int event) } } +static struct libusb_device* get_new_attached_usb_device() +{ + struct libusb_device* array[MAX_DEVCIE_LIST_LENGTH]; + int num; + int i; + GList *l; + int bFind; + struct libusb_device* dev; + struct sr_dev_inst *dev_ins; + + sr_info("To find new attached device."); + + dev = NULL; + num = 0; + ds_scan_all_device_list(lib_ctx.sr_ctx->libusb_ctx, &array, MAX_DEVCIE_LIST_LENGTH, &num); + + pthread_mutex_lock(&lib_ctx.mutext); + + for (i = 0; i < num; i++){ + bFind = 0; + + for (l = lib_ctx.device_list; l; l = l->next){ + dev_ins = l->data; + if (dev_ins->handle == (ds_device_handle)array[i]){ + bFind = 1; + break; + } + } + + if (bFind == 0){ + dev = array[i]; + break; + } + } + + pthread_mutex_unlock(&lib_ctx.mutext); + + if (dev != NULL){ + sr_info("Found new attached usb device:%p", dev); + } + + return dev; +} + +static struct libusb_device* get_new_detached_usb_device() +{ + struct libusb_device* array[MAX_DEVCIE_LIST_LENGTH]; + int num; + int i; + GList *l; + int bFind; + struct libusb_device* dev; + struct sr_dev_inst *dev_ins; + + sr_info("To find new detached device."); + + dev = NULL; + num = 0; + ds_scan_all_device_list(lib_ctx.sr_ctx->libusb_ctx, &array, MAX_DEVCIE_LIST_LENGTH, &num); + + pthread_mutex_lock(&lib_ctx.mutext); + + for (l = lib_ctx.device_list; l; l = l->next) + { + bFind = 0; + dev_ins = l->data; + + if (dev_ins->dev_type != DEV_TYPE_USB){ + continue; + } + + for (i = 0; i < num; i++){ + if (dev_ins->handle == (ds_device_handle)array[i]){ + bFind = 1; + break; + } + } + + if (bFind == 0){ + dev = (libusb_device*)dev_ins->handle; + break; + } + } + + pthread_mutex_unlock(&lib_ctx.mutext); + + if (dev != NULL){ + sr_info("Found new detached usb device:%p", dev); + } + + return dev; +} + /**-------------------private function end---------------*/ diff --git a/libsigrok4DSL/libsigrok-internal.h b/libsigrok4DSL/libsigrok-internal.h index 8716f026..959378fb 100644 --- a/libsigrok4DSL/libsigrok-internal.h +++ b/libsigrok4DSL/libsigrok-internal.h @@ -26,7 +26,6 @@ #include #include "libsigrok.h" - /** * @file * @@ -66,6 +65,9 @@ struct sr_context { libusb_hotplug_callback_handle hotplug_handle; hotplug_event_callback hotplug_callback; struct timeval hotplug_tv; + int (*listen_hotplug_ext)(struct sr_context *ctx); + int (*close_hotplug_ext)(struct sr_context *ctx); + int (*hotplug_wait_timout_ext)(struct sr_context *ctx); }; static const struct sr_dev_mode sr_mode_list[] = @@ -404,6 +406,8 @@ SR_PRIV int ds_data_forward(const struct sr_dev_inst *sdi, SR_PRIV int current_device_acquisition_stop(); +SR_PRIV int lib_extern_init(struct sr_context *ctx); + /*--- hwdriver.c ------------------------------------------------------------*/ SR_PRIV int sr_config_get(const struct sr_dev_driver *driver, @@ -423,6 +427,7 @@ SR_PRIV const struct sr_config_info *sr_config_info_get(int key); SR_PRIV int sr_status_get(const struct sr_dev_inst *sdi, struct sr_status *status, gboolean prg); SR_PRIV struct sr_config *sr_config_new(int key, GVariant *data); SR_PRIV void sr_config_free(struct sr_config *src); +SR_PRIV int ds_scan_all_device_list(libusb_context *usb_ctx, struct libusb_device **list_buf, int size, int *count); /*--- dsl.c ------------------------------------------------------------*/ SR_PRIV int sr_option_value_to_code(int config_id, const char *value, const struct lang_text_map_item *array, int num); diff --git a/libsigrok4DSL/output/csv.c b/libsigrok4DSL/output/csv.c index 03670425..de73b7b5 100644 --- a/libsigrok4DSL/output/csv.c +++ b/libsigrok4DSL/output/csv.c @@ -242,7 +242,7 @@ static int receive(const struct sr_output *o, const struct sr_datafeed_packet *p } tmpv = (double)(ctx->index-1) / (double)ctx->samplerate; - g_string_append_printf(*out, "%0.18g", tmpv); + g_string_append_printf(*out, "%0.15g", tmpv); for (j = 0; j < ctx->num_enabled_channels; j++) { idx = j;