From 9c935ad68377ba09adecab6f75c151e095de740c Mon Sep 17 00:00:00 2001 From: dreamsourcelabTAI Date: Mon, 8 Aug 2022 15:59:50 +0800 Subject: [PATCH] Code refactoring 7 --- common/log/xlog.c | 37 +- common/log/xlog.h | 9 +- libsigrok4DSL/backend.c | 8 - libsigrok4DSL/dsdevice.c | 17 +- libsigrok4DSL/hardware/DSL/dscope.c | 58 ++-- libsigrok4DSL/hardware/DSL/dsl.c | 158 ++++----- libsigrok4DSL/hardware/DSL/dslogic.c | 62 ++-- libsigrok4DSL/hardware/common/usb.c | 6 +- libsigrok4DSL/hardware/demo/demo.c | 33 +- libsigrok4DSL/lib_main.c | 490 +++++++++++++++++++++++---- libsigrok4DSL/libsigrok-internal.h | 92 ++++- libsigrok4DSL/libsigrok.h | 163 +++------ libsigrok4DSL/session_driver.c | 2 +- libsigrok4DSL/std.c | 62 +--- libsigrok4DSL/tests/test_main.c | 34 -- libsigrok4DSL/tests/test_main.cpp | 68 ++++ 16 files changed, 800 insertions(+), 499 deletions(-) delete mode 100644 libsigrok4DSL/tests/test_main.c create mode 100644 libsigrok4DSL/tests/test_main.cpp diff --git a/common/log/xlog.c b/common/log/xlog.c index c8f86b27..8093840a 100644 --- a/common/log/xlog.c +++ b/common/log/xlog.c @@ -45,7 +45,7 @@ struct xlog_receiver_info int _type; //see enum xlog_receiver_type FILE *_file; xlog_print_func _fn; // print function - xlog_receiver _rev; //user callback + xlog_receive_callback _rev; //user callback }; struct xlog_context @@ -139,10 +139,7 @@ static void print_to_user_callback(struct xlog_receiver_info *info, const char * info->_rev(buf, wr); } -/** - * create a log context, the console is default log receiver -*/ -XLOG_API xlog_context* xlog_new() +static xlog_context* xlog_new_context(int bConsole) { int i=0; xlog_context *ctx = (xlog_context*)malloc(sizeof(xlog_context)); @@ -152,10 +149,14 @@ XLOG_API xlog_context* xlog_new() ctx->_receivers[i]._fn = NULL; ctx->_receivers[i]._file = NULL; } - ctx->_receivers[0]._fn = print_to_console; - ctx->_receivers[0]._type = RECEIVER_TYPE_CONSOLE; + ctx->_count = 0; ctx->_log_level = XLOG_LEVEL_INFO; - ctx->_count = 1; + + if (bConsole){ + ctx->_receivers[0]._fn = print_to_console; + ctx->_receivers[0]._type = RECEIVER_TYPE_CONSOLE; + ctx->_count = 1; + } pthread_mutex_init(&ctx->_mutext, NULL); } @@ -163,6 +164,22 @@ XLOG_API xlog_context* xlog_new() return ctx; } +/** + * create a log context, the console is default log receiver +*/ +XLOG_API xlog_context* xlog_new() +{ + return xlog_new_context(1); +} + +/* + create a log context +*/ +XLOG_API xlog_context* xlog_new2(int bConsole) +{ + return xlog_new_context(bConsole); +} + /** * free a log context, return 0 if success. */ @@ -190,7 +207,7 @@ XLOG_API void xlog_free(xlog_context* ctx) /** * append a log data receiver, return 0 if success. */ -XLOG_API int xlog_add_receiver(xlog_context* ctx, xlog_receiver rev, int *out_index) +XLOG_API int xlog_add_receiver(xlog_context* ctx, xlog_receive_callback rev, int *out_index) { int i; @@ -476,7 +493,7 @@ XLOG_API int xlog_warn(xlog_writer *wr, const char *format, ...) } } - pthread_mutex_unlock(&ctx->_mutext); + pthread_mutex_unlock(&ctx->_mutext); return 0; } diff --git a/common/log/xlog.h b/common/log/xlog.h index 947113c0..2ecd170c 100644 --- a/common/log/xlog.h +++ b/common/log/xlog.h @@ -63,13 +63,18 @@ typedef struct xlog_writer xlog_writer; /** * define log data receiver type */ -typedef void (*xlog_receiver)(const char *data, int length); +typedef void (*xlog_receive_callback)(const char *data, int length); /* create a log context, the console is default log receiver */ XLOG_API xlog_context* xlog_new(); +/* + create a log context +*/ +XLOG_API xlog_context* xlog_new2(int bConsole); + /** * free a log context, return 0 if success. * and all xlog_writer will be can't to use. @@ -79,7 +84,7 @@ XLOG_API void xlog_free(xlog_context* ctx); /** * append a log data receiver, return 0 if success. */ -XLOG_API int xlog_add_receiver(xlog_context* ctx, xlog_receiver rev, int *out_index); +XLOG_API int xlog_add_receiver(xlog_context* ctx, xlog_receive_callback rev, int *out_index); /** * append a log data receiver, return 0 if success. diff --git a/libsigrok4DSL/backend.c b/libsigrok4DSL/backend.c index 5f5714af..94c2bade 100644 --- a/libsigrok4DSL/backend.c +++ b/libsigrok4DSL/backend.c @@ -136,10 +136,6 @@ static int sanity_check_all_drivers(void) sr_err("No dev_list in driver %d ('%s').", i, d); errors++; } - if (!drivers[i]->dev_clear) { - sr_err("No dev_clear in driver %d ('%s').", i, d); - errors++; - } /* Note: config_get() is optional. */ if (!drivers[i]->config_set) { sr_err("No config_set in driver %d ('%s').", i, d); @@ -302,8 +298,6 @@ SR_API int sr_init(struct sr_context **ctx) int ret = SR_ERR; struct sr_context *context; - sr_log_init(); //try init log - if (!ctx) { sr_err("%s(): libsigrok context was NULL.", __func__); return SR_ERR; @@ -377,8 +371,6 @@ SR_API int sr_exit(struct sr_context *ctx) g_free(ctx); - sr_log_uninit(); //try uninit log - return SR_OK; } diff --git a/libsigrok4DSL/dsdevice.c b/libsigrok4DSL/dsdevice.c index 8351e7d6..a36c9f50 100644 --- a/libsigrok4DSL/dsdevice.c +++ b/libsigrok4DSL/dsdevice.c @@ -22,6 +22,7 @@ #include #include "config.h" /* Needed for HAVE_LIBUSB_1_0 and others. */ #include "log.h" +#include #undef LOG_PREFIX #define LOG_PREFIX "device: " @@ -189,11 +190,9 @@ SR_PRIV struct sr_dev_inst *sr_dev_inst_new(int mode, int index, int status, sdi->driver = NULL; sdi->mode = mode; - sdi->index = index; + sdi->name[0] = '\0'; sdi->status = status; - sdi->inst_type = -1; sdi->vendor = vendor ? g_strdup(vendor) : NULL; - sdi->model = model ? g_strdup(model) : NULL; sdi->version = version ? g_strdup(version) : NULL; sdi->channels = NULL; sdi->conn = NULL; @@ -201,6 +200,10 @@ SR_PRIV struct sr_dev_inst *sr_dev_inst_new(int mode, int index, int status, sdi->handle = (sr_device_handle)sdi; sdi->dev_type = DEV_TYPE_UNKOWN; + if (model && *model){ + strncpy(sdi->name, model, sizeof(sdi->name)); + } + return sdi; } @@ -235,7 +238,6 @@ SR_PRIV void sr_dev_inst_free(struct sr_dev_inst *sdi) g_free(sdi->priv); g_free(sdi->vendor); - g_free(sdi->model); g_free(sdi->version); g_free(sdi); } @@ -254,6 +256,8 @@ SR_PRIV struct sr_usb_dev_inst *sr_usb_dev_inst_new(uint8_t bus, udi->bus = bus; udi->address = address; udi->devhdl = hdl; + udi->usb_dev = NULL; + udi->is_wait_re_connected = 0; return udi; } @@ -331,10 +335,7 @@ SR_API const GSList *sr_dev_mode_list(const struct sr_dev_inst *sdi) SR_API int sr_dev_clear(const struct sr_dev_driver *driver) { - if (driver && driver->dev_clear) - return driver->dev_clear(); - else - return SR_OK; + return SR_OK; } SR_API int sr_dev_open(struct sr_dev_inst *sdi) diff --git a/libsigrok4DSL/hardware/DSL/dscope.c b/libsigrok4DSL/hardware/DSL/dscope.c index 69e86c7f..34780d18 100644 --- a/libsigrok4DSL/hardware/DSL/dscope.c +++ b/libsigrok4DSL/hardware/DSL/dscope.c @@ -27,6 +27,8 @@ #undef LOG_PREFIX #define LOG_PREFIX "dscope: " +static int dev_destroy(struct sr_dev_inst *sdi); + enum { /** Normal */ OP_NORMAL = 0, @@ -177,10 +179,6 @@ static struct DSL_context *DSCope_dev_new(const struct DSL_profile *prof) return devc; } -static int dev_clear(void) -{ - return std_dev_clear(di, NULL); -} static int init(struct sr_context *sr_ctx) { @@ -202,6 +200,7 @@ static GSList *scan(GSList *options) int devcnt, ret, i, j; const char *conn; enum libusb_speed usb_speed; + struct sr_usb_dev_inst *usb_dev_info; drvc = di->priv; @@ -273,7 +272,11 @@ static GSList *scan(GSList *options) if (!prof) continue; - sr_info("Got a device handle: %p", device_handle); + if (sr_usb_device_is_exists(device_handle)){ + sr_info("Device is exists, handle: %p", device_handle); + continue;; + } + sr_info("Got a new device handle: %p", device_handle); devcnt = g_slist_length(drvc->instances); devc = DSCope_dev_new(prof); @@ -282,29 +285,33 @@ static GSList *scan(GSList *options) sdi = sr_dev_inst_new(channel_modes[devc->ch_mode].mode, devcnt, SR_ST_INITIALIZING, prof->vendor, prof->model, prof->model_version); + if (!sdi) { g_free(devc); return NULL; } + sdi->priv = devc; sdi->driver = di; - sdi->dev_type = DEV_TYPE_HARDWARE; - - drvc->instances = g_slist_append(drvc->instances, sdi); + sdi->dev_type = DEV_TYPE_USB; /* Fill in probelist according to this device's profile. */ - if (dsl_setup_probes(sdi, channel_modes[devc->ch_mode].num) != SR_OK) + if (dsl_setup_probes(sdi, channel_modes[devc->ch_mode].num) != SR_OK){ + sr_err("%s", "dsl_setup_probes() error"); + dev_destroy(sdi); return NULL; + } + devices = g_slist_append(devices, sdi); if (dsl_check_conf_profile(device_handle)) { /* Already has the firmware, so fix the new address. */ sr_info("Found a DSCope device, name: \"%s\"", prof->model); - sdi->status = SR_ST_INACTIVE; - sdi->inst_type = SR_INST_USB; - sdi->conn = sr_usb_dev_inst_new(libusb_get_bus_number(device_handle), - libusb_get_device_address(device_handle), NULL); - /* only report device after firmware is ready */ - devices = g_slist_append(devices, sdi); + + usb_dev_info = sr_usb_dev_inst_new(libusb_get_bus_number(device_handle), + libusb_get_device_address(device_handle), NULL); + usb_dev_info->usb_dev = device_handle; + sdi->conn = usb_dev_info; + sdi->status = SR_ST_INACTIVE; } else { char *firmware; @@ -323,14 +330,18 @@ static GSList *scan(GSList *options) sr_err("Firmware upload failed for " "device %d.", devcnt); g_free(firmware); - sdi->inst_type = SR_INST_USB; - sdi->conn = sr_usb_dev_inst_new (libusb_get_bus_number(device_handle), - 0xff, NULL); + + usb_dev_info = sr_usb_dev_inst_new(libusb_get_bus_number(device_handle),0xff, NULL); + usb_dev_info->usb_dev = device_handle; + sdi->conn = usb_dev_info; } } libusb_free_device_list(devlist, 1); - g_slist_free_full(conn_devices, (GDestroyNotify)sr_usb_dev_inst_free); + + if (conn_devices){ + g_slist_free_full(conn_devices, (GDestroyNotify)sr_usb_dev_inst_free); + } return devices; } @@ -1833,10 +1844,9 @@ static int dev_close(struct sr_dev_inst *sdi) static int dev_destroy(struct sr_dev_inst *sdi) { - dsl_destroy_device(sdi); + return dsl_destroy_device(sdi); } - static int cleanup(void) { int ret; @@ -1845,12 +1855,10 @@ static int cleanup(void) if (!(drvc = di->priv)) return SR_OK; - ret = dev_clear(); - g_free(drvc); di->priv = NULL; - return ret; + return SR_OK; } static void remove_sources(struct DSL_context *devc) @@ -2090,12 +2098,12 @@ SR_PRIV struct sr_dev_driver DSCope_driver_info = { .name = "DSCope", .longname = "DSCope (generic driver for DScope oscilloscope)", .api_version = 1, + .driver_type = DRIVER_TYPE_HARDWARE, .init = init, .cleanup = cleanup, .scan = scan, .dev_list = dev_list, .dev_mode_list = dev_mode_list, - .dev_clear = dev_clear, .config_get = config_get, .config_set = config_set, .config_list = config_list, diff --git a/libsigrok4DSL/hardware/DSL/dsl.c b/libsigrok4DSL/hardware/DSL/dsl.c index 27ad43fc..6a20cc6c 100644 --- a/libsigrok4DSL/hardware/DSL/dsl.c +++ b/libsigrok4DSL/hardware/DSL/dsl.c @@ -306,112 +306,82 @@ static int hw_dev_open(struct sr_dev_driver *di, struct sr_dev_inst *sdi) sr_info("%s", "Try to open device instance."); - assert(usb->devhdl == NULL); + if(usb->devhdl == NULL){ + sr_err("%s", "hw_dev_open(), usb->devhdl is null."); + return SR_ERR; + } + if (usb->usb_dev == NULL){ + sr_err("%s", "hw_dev_open(), usb->usb_dev is null."); + return SR_ERR; + } + if (usb->is_wait_re_connected){ + sr_err("Device is waitting reconnect, handle:%p", usb->usb_dev); + return SR_ERR; + } if (sdi->status == SR_ST_ACTIVE) { /* Device is already in use. */ - sr_info("%s", "Device is actived, can't to open."); + sr_info("Device is actived, can't to open, handle:%p", usb->usb_dev); return SR_ERR; } - skip = 0; - device_count = libusb_get_device_list(drvc->sr_ctx->libusb_ctx, &devlist); - if (device_count < 0) { - sr_err("Failed to get device list: %s.", - libusb_error_name(device_count)); + if (sdi->status == SR_ST_INITIALIZING) { + sr_info("%s", "The device instance is still boosting."); + } + dev_handel = usb->usb_dev; + + sr_info("Open device instance, handle: %p", dev_handel); + + if (libusb_open(dev_handel, &usb->devhdl) != 0){ + sr_err("Failed to open device: %s, handle:%p", + libusb_error_name(ret), dev_handel); return SR_ERR; } - for (i = 0; i < device_count; i++) - { - dev_handel = devlist[i]; - - if ((ret = libusb_get_device_descriptor(dev_handel, &des))) { - sr_err("Failed to get device descriptor: %s.", - libusb_error_name(ret)); - continue; - } - - if (des.idVendor != devc->profile->vid - || des.idProduct != devc->profile->pid){ - continue; - } - - if (sdi->status == SR_ST_INITIALIZING) { - sr_info("%s", "The device instance is still boosting."); - if (skip != sdi->index) { - /* Skip devices of this type that aren't the one we want. */ - sr_info("%s", "Skip devices of this type that aren't the one we want."); - skip += 1; - continue; - } - } - else if (sdi->status == SR_ST_INACTIVE) { - /* - * This device is fully enumerated, so we need to find - * this device by vendor, product, bus and address. - */ - sr_info("%s", "The device instance is live, but not use."); - if (libusb_get_bus_number(dev_handel) != usb->bus - || libusb_get_device_address(dev_handel) != usb->address){ - /* This is not the one. */ - sr_info("%s", "Font a device, but is not the one."); - continue; - } - } - - sr_info("Open device instance, handle: %p", dev_handel); - - if (!(ret = libusb_open(dev_handel, &usb->devhdl))) { - if (usb->address == 0xff) - /* - * First time we touch this device after FW - * upload, so we don't know the address yet. - */ - usb->address = libusb_get_device_address(dev_handel); - } - else { - sr_err("Failed to open device: %s.", - libusb_error_name(ret)); - break; - } - - rd_cmd.header.dest = DSL_CTL_FW_VERSION; - rd_cmd.header.size = 2; - rd_cmd.data = rd_cmd_data; - if ((ret = command_ctl_rd(usb->devhdl, rd_cmd)) != SR_OK) { - sr_err("Failed to get firmware version."); - break; - } - vi.major = rd_cmd_data[0]; - vi.minor = rd_cmd_data[1]; - + if (usb->address == 0xff){ /* - * Different versions may have incompatible issue, - * Mark for up level process - */ - if (vi.major != DSL_REQUIRED_VERSION_MAJOR) { - sr_err("Expected firmware version %d.%d, " - "got %d.%d.", DSL_REQUIRED_VERSION_MAJOR, DSL_REQUIRED_VERSION_MINOR, - vi.major, vi.minor); - sdi->status = SR_ST_INCOMPATIBLE; - } else { - sdi->status = SR_ST_ACTIVE; - } + * First time we touch this device after FW + * upload, so we don't know the address yet. + */ + usb->address = libusb_get_device_address(dev_handel); + } - sr_info("Opened device %d on %d.%d, " + rd_cmd.header.dest = DSL_CTL_FW_VERSION; + rd_cmd.header.size = 2; + rd_cmd.data = rd_cmd_data; + + if ((ret = command_ctl_rd(usb->devhdl, rd_cmd)) != SR_OK) { + sr_err("Failed to get firmware version."); + return ret; + } + + vi.major = rd_cmd_data[0]; + vi.minor = rd_cmd_data[1]; + + /* + * Different versions may have incompatible issue, + * Mark for up level process. + */ + if (vi.major != DSL_REQUIRED_VERSION_MAJOR) { + sr_err("Expected firmware version %d.%d, " + "got %d.%d.", DSL_REQUIRED_VERSION_MAJOR, DSL_REQUIRED_VERSION_MINOR, + vi.major, vi.minor); + sdi->status = SR_ST_INCOMPATIBLE; + } + else { + sdi->status = SR_ST_ACTIVE; + } + + sr_info("Opened device %p on %d.%d, " "interface %d, firmware %d.%d.", - sdi->index, usb->bus, usb->address, + usb->usb_dev, usb->bus, usb->address, USB_INTERFACE, vi.major, vi.minor); - break; - } - libusb_free_device_list(devlist, 1); - if ((sdi->status != SR_ST_ACTIVE) && - (sdi->status != SR_ST_INCOMPATIBLE)) + (sdi->status != SR_ST_INCOMPATIBLE)){ return SR_ERR; - + } + return SR_OK; } @@ -1963,7 +1933,7 @@ SR_PRIV int dsl_dev_close(struct sr_dev_inst *sdi) usb = sdi->conn; if (usb->devhdl == NULL){ - sr_info("%s", "dsl_dev_close(),Device handle is null."); + sr_info("%s", "dsl_dev_close(),libusb_device_handle is null."); return SR_ERR; } @@ -2521,11 +2491,11 @@ SR_PRIV int dsl_destroy_device(const struct sr_dev_inst *sdi) } if (sdi->conn) { - if (sdi->inst_type == SR_INST_USB) + if (sdi->dev_type == DEV_TYPE_USB) sr_usb_dev_inst_free(sdi->conn); - else if (sdi->inst_type == SR_INST_SERIAL) + else if (sdi->dev_type == DEV_TYPE_SERIAL) sr_serial_dev_inst_free(sdi->conn); } sr_dev_inst_free(sdi); -} \ No newline at end of file +} diff --git a/libsigrok4DSL/hardware/DSL/dslogic.c b/libsigrok4DSL/hardware/DSL/dslogic.c index 1ec18d8b..c674284f 100644 --- a/libsigrok4DSL/hardware/DSL/dslogic.c +++ b/libsigrok4DSL/hardware/DSL/dslogic.c @@ -28,6 +28,8 @@ #undef LOG_PREFIX #define LOG_PREFIX "dslogic: " +static int dev_destroy(struct sr_dev_inst *sdi); + static const char *maxHeights[] = { "1X", "2X", @@ -247,11 +249,6 @@ static struct DSL_context *DSLogic_dev_new(const struct DSL_profile *prof) return devc; } -static int dev_clear(void) -{ - return std_dev_clear(di, NULL); -} - static int init(struct sr_context *sr_ctx) { return std_hw_init(sr_ctx, di, LOG_PREFIX); @@ -272,6 +269,7 @@ static GSList *scan(GSList *options) int devcnt, ret, i, j; const char *conn; enum libusb_speed usb_speed; + struct sr_usb_dev_inst *usb_dev_info; drvc = di->priv; @@ -344,14 +342,17 @@ static GSList *scan(GSList *options) if (!prof) continue; - sr_info("Got a device handle: %p", device_handle); + if (sr_usb_device_is_exists(device_handle)){ + sr_info("Device is exists, handle: %p", device_handle); + continue;; + } + sr_info("Got a new device handle: %p", device_handle); - devcnt = g_slist_length(drvc->instances); devc = DSLogic_dev_new(prof); if (!devc) return NULL; - sdi = sr_dev_inst_new(channel_modes[devc->ch_mode].mode, devcnt, SR_ST_INITIALIZING, + sdi = sr_dev_inst_new(channel_modes[devc->ch_mode].mode, -1, SR_ST_INITIALIZING, prof->vendor, prof->model, prof->model_version); if (!sdi) { g_free(devc); @@ -359,23 +360,26 @@ static GSList *scan(GSList *options) } sdi->priv = devc; sdi->driver = di; - sdi->dev_type = DEV_TYPE_HARDWARE; - - drvc->instances = g_slist_append(drvc->instances, sdi); - + sdi->dev_type = DEV_TYPE_USB; + /* Fill in probelist according to this device's profile. */ - if (dsl_setup_probes(sdi, channel_modes[devc->ch_mode].num) != SR_OK) + if (dsl_setup_probes(sdi, channel_modes[devc->ch_mode].num) != SR_OK){ + sr_err("%s", "dsl_setup_probes() error"); + dev_destroy(sdi); return NULL; + } + devices = g_slist_append(devices, sdi); if (dsl_check_conf_profile(device_handle)) { /* Already has the firmware, so fix the new address. */ sr_info("Found a DSLogic device,name: \"%s\"", prof->model); - sdi->status = SR_ST_INACTIVE; - sdi->inst_type = SR_INST_USB; - sdi->conn = sr_usb_dev_inst_new(libusb_get_bus_number(device_handle), - libusb_get_device_address(device_handle), NULL); - /* only report device after firmware is ready */ - devices = g_slist_append(devices, sdi); + + usb_dev_info = sr_usb_dev_inst_new(libusb_get_bus_number(device_handle), + libusb_get_device_address(device_handle), NULL); + + usb_dev_info->usb_dev = device_handle; + sdi->conn = usb_dev_info; + sdi->status = SR_ST_INACTIVE; } else { char *firmware; @@ -394,14 +398,18 @@ static GSList *scan(GSList *options) sr_err("Firmware upload failed for " "device %d.", devcnt); g_free(firmware); - sdi->inst_type = SR_INST_USB; - sdi->conn = sr_usb_dev_inst_new (libusb_get_bus_number(device_handle), - 0xff, NULL); + + usb_dev_info = sr_usb_dev_inst_new(libusb_get_bus_number(device_handle),0xff, NULL); + usb_dev_info->usb_dev = device_handle; + sdi->conn = usb_dev_info; } } libusb_free_device_list(devlist, 1); - g_slist_free_full(conn_devices, (GDestroyNotify)sr_usb_dev_inst_free); + + if (conn_devices){ + g_slist_free_full(conn_devices, (GDestroyNotify)sr_usb_dev_inst_free); + } return devices; } @@ -1196,7 +1204,7 @@ static int dev_close(struct sr_dev_inst *sdi) static int dev_destroy(struct sr_dev_inst *sdi) { - dsl_destroy_device(sdi); + return dsl_destroy_device(sdi); } static int cleanup(void) @@ -1207,12 +1215,10 @@ static int cleanup(void) if (!(drvc = di->priv)) return SR_OK; - ret = dev_clear(); - g_free(drvc); di->priv = NULL; - return ret; + return SR_OK; } static void remove_sources(struct DSL_context *devc) @@ -1429,12 +1435,12 @@ SR_PRIV struct sr_dev_driver DSLogic_driver_info = { .name = "DSLogic", .longname = "DSLogic (generic driver for DSLogic LA)", .api_version = 1, + .driver_type = DRIVER_TYPE_HARDWARE, .init = init, .cleanup = cleanup, .scan = scan, .dev_list = dev_list, .dev_mode_list = dev_mode_list, - .dev_clear = dev_clear, .config_get = config_get, .config_set = config_set, .config_list = config_list, diff --git a/libsigrok4DSL/hardware/common/usb.c b/libsigrok4DSL/hardware/common/usb.c index d24b67ed..c4d4f8c6 100644 --- a/libsigrok4DSL/hardware/common/usb.c +++ b/libsigrok4DSL/hardware/common/usb.c @@ -126,6 +126,8 @@ SR_PRIV GSList *sr_usb_find(libusb_context *usb_ctx, const char *conn) usb = sr_usb_dev_inst_new(libusb_get_bus_number(devlist[i]), libusb_get_device_address(devlist[i]), NULL); + usb->usb_dev = devlist[i]; + devices = g_slist_append(devices, usb); } libusb_free_device_list(devlist, 1); @@ -179,7 +181,9 @@ SR_PRIV GSList *sr_usb_find_usbtmc(libusb_context *usb_ctx) libusb_get_device_address(devlist[i])); usb = sr_usb_dev_inst_new(libusb_get_bus_number(devlist[i]), - libusb_get_device_address(devlist[i]), NULL); + libusb_get_device_address(devlist[i]), NULL); + usb->usb_dev = devlist[i]; + devices = g_slist_append(devices, usb); } libusb_free_config_descriptor(confdes); diff --git a/libsigrok4DSL/hardware/demo/demo.c b/libsigrok4DSL/hardware/demo/demo.c index e14764dc..14f3e9d7 100644 --- a/libsigrok4DSL/hardware/demo/demo.c +++ b/libsigrok4DSL/hardware/demo/demo.c @@ -61,13 +61,6 @@ extern struct ds_trigger *trigger; static int hw_dev_acquisition_stop(const struct sr_dev_inst *sdi, void *cb_data); -static int clear_instances(void) -{ - /* Nothing needed so far. */ - - return SR_OK; -} - static int hw_init(struct sr_context *sr_ctx) { return std_hw_init(sr_ctx, di, LOG_PREFIX); @@ -246,29 +239,9 @@ static int dev_destroy(struct sr_dev_inst *sdi) } static int hw_cleanup(void) -{ - GSList *l; - struct sr_dev_inst *sdi; - struct drv_context *drvc; - int ret = SR_OK; +{ - if (!(drvc = di->priv)) - return SR_OK; - - /* Properly close and free all devices. */ - for (l = drvc->instances; l; l = l->next) { - if (!(sdi = l->data)) { - /* Log error, but continue cleaning up the rest. */ - sr_err("%s: sdi was NULL, continuing", __func__); - ret = SR_ERR_BUG; - continue; - } - sr_dev_inst_free(sdi); - } - g_slist_free(drvc->instances); - drvc->instances = NULL; - - return ret; + return 0; } static unsigned int en_ch_num(const struct sr_dev_inst *sdi) @@ -1111,12 +1084,12 @@ SR_PRIV struct sr_dev_driver demo_driver_info = { .name = "virtual-demo", .longname = "Demo driver and pattern generator", .api_version = 1, + .driver_type = DRIVER_TYPE_DEMO, .init = hw_init, .cleanup = hw_cleanup, .scan = hw_scan, .dev_list = hw_dev_list, .dev_mode_list = hw_dev_mode_list, - .dev_clear = clear_instances, .config_get = config_get, .config_set = config_set, .config_list = config_list, diff --git a/libsigrok4DSL/lib_main.c b/libsigrok4DSL/lib_main.c index c87b20cc..e5d179ad 100644 --- a/libsigrok4DSL/lib_main.c +++ b/libsigrok4DSL/lib_main.c @@ -21,6 +21,9 @@ #include "libsigrok-internal.h" #include "log.h" +#include +#include +#include #ifdef _WIN32 #include @@ -34,55 +37,88 @@ #define LOG_PREFIX "lib_main: " char DS_RES_PATH[500] = {0}; -static struct sr_context *sr_ctx = NULL; -static libsigrok_event_callback_t event_callback = NULL; -static GList* all_device_list = NULL; // All device instance, sr_dev_inst* type -static GThread *hotplug_thread = NULL; -static int sr_exit_flag = 0; -static int attach_event_flag = 0; -static int detach_event_flag = 0; -static int wait_redo_attch_flag = 0; -static int wait_redo_attch_times = 0; - +struct sr_lib_context +{ + libsigrok_event_callback_t event_callback; + struct sr_context *sr_ctx; + GList* device_list; // All device instance, sr_dev_inst* type + pthread_mutex_t mutext; + GThread *hotplug_thread; + int lib_exit_flag; + int attach_event_flag; + int detach_event_flag; + int is_waitting_reconnect; + int check_reconnect_times; + struct libusb_device *attach_device_handle; + struct libusb_device *detach_device_handle; + struct sr_device_info current_device; +}; + static void hotplug_event_listen_callback(struct libusb_context *ctx, struct libusb_device *dev, int event); static void usb_hotplug_process_proc(); +static void destroy_device_instance(struct sr_dev_inst *dev); + +static struct sr_lib_context lib_ctx = { + .event_callback = NULL, + .sr_ctx = NULL, + .device_list = NULL, + .hotplug_thread = NULL, + .lib_exit_flag = 0, + .attach_event_flag = 0, + .detach_event_flag = 0, + .is_waitting_reconnect = 0, + .check_reconnect_times = 0, + .attach_device_handle = NULL, + .detach_device_handle = NULL, + .current_device = { + .handle = NULL, + .name[0] = '\0', + .is_current = 0, + .dev_type = DEV_TYPE_UNKOWN, + }, +}; /** * Must call first */ SR_API int sr_lib_init() -{ +{ int ret = 0; struct sr_dev_driver **drivers = NULL; struct sr_dev_driver **dr = NULL; - if (sr_ctx != NULL){ + if (lib_ctx.sr_ctx != NULL){ return SR_ERR_HAVE_DONE; } - ret = sr_init(&sr_ctx); + sr_log_init(); //try init log + + sr_info("Init %s.", SR_LIB_NAME); + + ret = sr_init(&lib_ctx.sr_ctx); if (ret != SR_OK){ return ret; } - sr_exit_flag = 0; + lib_ctx.lib_exit_flag = 0; // Initialise all libsigrok drivers drivers = sr_driver_list(); for (dr = drivers; *dr; dr++) { - if (sr_driver_init(sr_ctx, *dr) != SR_OK) { + if (sr_driver_init(lib_ctx.sr_ctx, *dr) != SR_OK) { sr_err("Failed to initialize driver '%s'", (*dr)->name); return SR_ERR; } } + pthread_mutex_init(&lib_ctx.mutext, NULL); //init locker - sr_ctx->hotplug_tv.tv_sec = 0; - sr_ctx->hotplug_tv.tv_usec = 0; + lib_ctx.sr_ctx->hotplug_tv.tv_sec = 0; + lib_ctx.sr_ctx->hotplug_tv.tv_usec = 0; - sr_listen_hotplug(sr_ctx, hotplug_event_listen_callback); + sr_listen_hotplug(lib_ctx.sr_ctx, hotplug_event_listen_callback); /** Start usb hotplug thread */ - hotplug_thread = g_thread_new("hotplug_proc", usb_hotplug_process_proc, NULL); + lib_ctx.hotplug_thread = g_thread_new("hotplug_proc", usb_hotplug_process_proc, NULL); return SR_OK; } @@ -91,47 +127,38 @@ SR_API int sr_lib_init() * Free all resource before program exits */ SR_API int sr_lib_exit() -{ - struct sr_dev_driver **drivers = NULL; - struct sr_dev_driver **dr = NULL; - struct sr_dev_driver *driver_ins; - GSList *l; - struct sr_dev_inst *dev; +{ + GSList *l; - if (sr_ctx == NULL){ + if (lib_ctx.sr_ctx == NULL){ return SR_ERR_HAVE_DONE; } - sr_close_hotplug(sr_ctx); + sr_info("Uninit %s.", SR_LIB_NAME); - sr_exit_flag = 1; //all thread to exit + sr_close_hotplug(lib_ctx.sr_ctx); - if (hotplug_thread != NULL){ - g_thread_join(hotplug_thread); - hotplug_thread = NULL; + lib_ctx.lib_exit_flag = 1; //all thread to exit + + if (lib_ctx.hotplug_thread != NULL){ + g_thread_join(lib_ctx.hotplug_thread); + lib_ctx.hotplug_thread = NULL; } // Release all device - for (l = all_device_list; l; l = l->next) - { - dev = l->data; - if (dev && dev->driver) - { - driver_ins = dev->driver; - - if (driver_ins->dev_destroy) - driver_ins->dev_destroy(dev); - else if (driver_ins->dev_close) - driver_ins->dev_close(dev); - } + for (l = lib_ctx.device_list; l; l = l->next){ + destroy_device_instance((struct sr_dev_inst*)l->data); } - g_safe_free_list(all_device_list); - + g_safe_free_list(lib_ctx.device_list); - if (sr_exit(sr_ctx) != SR_OK){ + pthread_mutex_destroy(&lib_ctx.mutext); //uninit locker + + if (sr_exit(lib_ctx.sr_ctx) != SR_OK){ sr_err("%s", "call sr_exit error"); } - sr_ctx = NULL; + lib_ctx.sr_ctx = NULL; + + sr_log_uninit(); //try uninit log return SR_OK; } @@ -149,87 +176,404 @@ SR_API void sr_set_firmware_resource_dir(const char *dir) DS_RES_PATH[len] = '/'; DS_RES_PATH[len + 1] = 0; } + + sr_info("Firmware resource path:%s", DS_RES_PATH); } } /** * Set event callback, event type see enum libsigrok_event_type */ -SR_API void sr_set_event_callback(libsigrok_event_callback_t *cb) +SR_API void sr_set_event_callback(libsigrok_event_callback_t cb) { - event_callback = cb; + lib_ctx.event_callback = cb; } +/** + * Get the device list, if the field _handle is 0, the list visited to end. + * User need call free() to release the buffer. If the list is empty, the out_list is null. + */ +SR_API int sr_device_get_list(struct sr_device_info** out_list, int *out_count) +{ + int num; + struct sr_device_info *array = NULL; + struct sr_device_info *p = NULL; + GList *l; + struct sr_dev_inst *dev; + + if (out_list == NULL){ + return SR_ERR_ARG; + } + *out_list = NULL; + + pthread_mutex_lock(&lib_ctx.mutext); + + num = g_slist_length(lib_ctx.device_list); + if (num == 0){ + pthread_mutex_unlock(&lib_ctx.mutext); + return SR_OK; + } + + array = (struct sr_device_info*)malloc(sizeof(struct sr_device_info) * (num+1)); + if (array == NULL){ + pthread_mutex_unlock(&lib_ctx.mutext); + return SR_ERR_MALLOC; + } + + p = array; + + for (l=lib_ctx.device_list; l; l = l->next){ + dev = l->data; + p->handle = dev->handle; + strncpy(p->name, dev->name, sizeof(dev->name) - 1); + p->dev_type = dev->dev_type; + p->is_current = (dev->handle == lib_ctx.current_device.handle); + p++; + } + + p->handle = 0; //is the end + p->name[0] = '\0'; + + if (out_count){ + *out_count = num; + } + + pthread_mutex_unlock(&lib_ctx.mutext); + + *out_list = array; + return SR_OK; +} + +/**-------------------internal function ---------------*/ +/** + * Check whether the USB device is in the device list. + */ +SR_PRIV int sr_usb_device_is_exists(libusb_device *usb_dev) +{ + GList *l; + struct sr_dev_inst *dev; + struct sr_usb_dev_inst *usb_dev_info; + int bFind = 0; + + if (usb_dev == NULL){ + sr_err("%s", "sr_usb_device_is_exists(), @usb_dev is null."); + return 0; + } + + pthread_mutex_lock(&lib_ctx.mutext); + + for (l = lib_ctx.device_list; l; l = l->next){ + dev = l->data; + usb_dev_info = dev->conn; + if (dev->dev_type == DEV_TYPE_USB + && usb_dev_info != NULL + && usb_dev_info->usb_dev == usb_dev){ + bFind = 1; + } + } + + pthread_mutex_unlock(&lib_ctx.mutext); + + return bFind; +} + +/** + * Remove one device from the list, and destory it. + * User need to call sr_device_get_list() to get the new list. + */ +SR_API int sr_remove_device(sr_device_handle handle) +{ + GList *l; + struct sr_dev_inst *dev; + int bFind = 0; + + if (handle == NULL){ + return SR_ERR_ARG; + } + + pthread_mutex_lock(&lib_ctx.mutext); + + for (l = lib_ctx.device_list; l; l = l->next){ + dev = l->data; + if (dev->handle == handle){ + lib_ctx.device_list = g_slist_remove(lib_ctx.device_list, l->data); + destroy_device_instance(dev); + bFind = 1; + break; + } + } + pthread_mutex_unlock(&lib_ctx.mutext); + + if (bFind == 0){ + return SR_ERR_CALL_STATUS; + } + return SR_OK; +} + +/** + * Get the current device info. + * If the current device is not exists, the handle filed will be set null. + */ +SR_API int sr_get_current_device_info(struct sr_device_info *info) +{ + if (info == NULL){ + return SR_ERR_ARG; + } + + info->handle = NULL; + info->name[0] = '\0'; + info->is_current = 0; + info->dev_type = DEV_TYPE_UNKOWN; + + if (lib_ctx.current_device.handle != NULL){ + info->handle = lib_ctx.current_device.handle; + strncpy(info->name, lib_ctx.current_device.name, sizeof(info->name)); + info->is_current = 1; + info->dev_type = lib_ctx.current_device.dev_type; + } + + return SR_OK; +} /**-------------------private function ---------------*/ -static int scan_hardware_device() +static int update_device_handle(struct libusb_device *old_dev, struct libusb_device *new_dev) { + GList *l; + struct sr_dev_inst *dev; + struct sr_usb_dev_inst *usb_dev_info; + int bFind = 0; + uint8_t bus; + uint8_t address; + pthread_mutex_lock(&lib_ctx.mutext); + + for (l = lib_ctx.device_list; l; l = l->next){ + dev = l->data; + usb_dev_info = dev->conn; + if (dev->dev_type == DEV_TYPE_USB + && usb_dev_info != NULL + && usb_dev_info->usb_dev == old_dev){ + + bus = libusb_get_bus_number(new_dev); + address = libusb_get_device_address(new_dev); + + if (bus == usb_dev_info->bus && address == usb_dev_info->address){ + bFind = 1; + usb_dev_info->usb_dev = new_dev; + } + else{ + sr_err("Try to update the device handle, but the bus and addres is not the same!"); + } + + break; + } + } + + pthread_mutex_unlock(&lib_ctx.mutext); + return bFind; } static void hotplug_event_listen_callback(struct libusb_context *ctx, struct libusb_device *dev, int event) { - if (event == USB_EV_HOTPLUG_ATTACH){ - sr_info("One device attached."); + int bDone = 0; - if (wait_redo_attch_flag){ - sr_info("%s", "Device loose contact, but it reconnect success."); + if (dev == NULL){ + sr_err("%s", "hotplug_event_listen_callback(), @dev is null."); + return; + } + + if (event == USB_EV_HOTPLUG_ATTACH){ + sr_info("One device attached, handle:%p", dev); + + if (lib_ctx.is_waitting_reconnect){ + if (lib_ctx.attach_device_handle != NULL){ + sr_err("One attached device haven't processed complete,handle:%p", + lib_ctx.attach_device_handle); + } + + if (lib_ctx.detach_device_handle == NULL){ + sr_err("%s", "The detached device handle is null, but the status is waitting for reconnect."); + } + else{ + if (update_device_handle(lib_ctx.detach_device_handle, dev)){ + bDone = 1; + sr_info("%s", "One device loose contact, but it reconnect success."); + } + else{ + sr_err("Update device handle error! can't find the old."); + } + lib_ctx.detach_device_handle = NULL; + } } - wait_redo_attch_flag = 0; - attach_event_flag = 1; + if (bDone == 0){ + lib_ctx.attach_event_flag = 1; // Is a new device attched. + lib_ctx.attach_device_handle = dev; + } + lib_ctx.is_waitting_reconnect = 0; } else if (event == USB_EV_HOTPLUG_DETTACH){ - sr_info("One device detached."); - wait_redo_attch_flag = 1; //Begin wait the device reconnect, if timeout, will process the detach event. - wait_redo_attch_times = 0; + sr_info("One device detached,handle:%p", dev); + + if (lib_ctx.detach_device_handle != NULL){ + sr_err("One detached device haven't processed complete,handle:%p", + lib_ctx.detach_device_handle); + } + /** + * Begin to wait the device reconnect, if timeout, will process the detach event. + */ + lib_ctx.is_waitting_reconnect = 1; + lib_ctx.check_reconnect_times = 0; + lib_ctx.detach_device_handle = dev; } else{ - sr_err("%s", "Unknown usb event"); - wait_redo_attch_flag = 1; + sr_err("%s", "Unknown usb device event"); } } static void process_attach_event() { + struct sr_dev_driver **drivers; + GList *dev_list; + GSList *l; + GList *cur_list; + struct sr_dev_driver *dr; + int num = 0; + sr_info("%s", "Process device attch event."); + + if (lib_ctx.attach_device_handle == NULL){ + sr_err("%s", "The attached device handle is null."); + return; + } + + drivers = sr_driver_list(); + + while (*drivers) + { + dr = *drivers; + + if (dr->driver_type == DRIVER_TYPE_HARDWARE) + { + dev_list = dr->scan(NULL); + if (dev_list != NULL){ + sr_info("Get new device list by driver \"%s\"", dr->name); + + pthread_mutex_lock(&lib_ctx.mutext); + cur_list = lib_ctx.device_list; + + for (l= dev_list; l; l = l->next){ + cur_list = g_slist_append(cur_list, l->data); + num++; + } + + lib_ctx.device_list = cur_list; + pthread_mutex_unlock(&lib_ctx.mutext); + g_slist_free(dev_list); + } + } + + drivers++; + } + + if (lib_ctx.event_callback != NULL && num > 0){ + // Tell user one new device attched, and the list is updated. + lib_ctx.event_callback(SR_EV_NEW_DEVICE_ATTACH); + } + + lib_ctx.attach_device_handle = NULL; } static void process_detach_event() { + libusb_device *ev_dev; + int ev = SR_EV_INACTIVE_DEVICE_DETACH; + GList *l; + struct sr_dev_inst *dev; + struct sr_usb_dev_inst *usb_dev_info; + struct sr_dev_driver *driver_ins; + sr_info("%s", "Process device detach event."); + + ev_dev = lib_ctx.detach_device_handle; + if (ev_dev == NULL){ + sr_err("%s", "The detached device handle is null."); + return; + } + lib_ctx.detach_device_handle = NULL; + + pthread_mutex_lock(&lib_ctx.mutext); + + for (l = lib_ctx.device_list; l; l = l->next){ + dev = l->data; + usb_dev_info = dev->conn; + + if (dev->dev_type == DEV_TYPE_USB + && usb_dev_info != NULL + && usb_dev_info->usb_dev == ev_dev){ + //Found the device, and remove it. + lib_ctx.device_list = g_slist_remove(lib_ctx.device_list, l->data); + destroy_device_instance(dev); + break; + } + } + pthread_mutex_unlock(&lib_ctx.mutext); + + if (ev_dev == lib_ctx.current_device.handle) + ev = SR_EV_CURRENT_DEVICE_DETACH; + + if (lib_ctx.event_callback != NULL){ + //Tell user one new device detached, and the list is updated. + lib_ctx.event_callback(ev); + } } static void usb_hotplug_process_proc() { sr_info("%s", "Hotplug thread start!"); - while (!sr_exit_flag) + while (!lib_ctx.lib_exit_flag) { - sr_hotplug_wait_timout(sr_ctx); + sr_hotplug_wait_timout(lib_ctx.sr_ctx); - if (attach_event_flag){ + if (lib_ctx.attach_event_flag){ process_attach_event(); - attach_event_flag = 0; + lib_ctx.attach_event_flag = 0; } - if (detach_event_flag){ + if (lib_ctx.detach_event_flag){ process_detach_event(); - detach_event_flag = 0; + lib_ctx.detach_event_flag = 0; } _sleep(100); - if (wait_redo_attch_flag){ - wait_redo_attch_times++; + if (lib_ctx.is_waitting_reconnect){ + lib_ctx.check_reconnect_times++; // 500ms - if (wait_redo_attch_times == 5){ + if (lib_ctx.check_reconnect_times == 5){ //Device loose contact,wait for it reconnection timeout. - detach_event_flag = 1; // use detach event - wait_redo_attch_flag = 0; + lib_ctx.detach_event_flag = 1; // use detach event + lib_ctx.is_waitting_reconnect = 0; } } } sr_info("%s", "Hotplug thread end!"); -} \ No newline at end of file +} + + +static void destroy_device_instance(struct sr_dev_inst *dev) +{ + if (dev == NULL || dev->driver == NULL){ + sr_err("%s", "destroy_device_instance() argument error."); + return; + } + struct sr_dev_driver *driver_ins; + driver_ins = dev->driver; + + if (driver_ins->dev_destroy) + driver_ins->dev_destroy(dev); + else if (driver_ins->dev_close) + driver_ins->dev_close(dev); +} diff --git a/libsigrok4DSL/libsigrok-internal.h b/libsigrok4DSL/libsigrok-internal.h index 805e77e8..32df7c0b 100644 --- a/libsigrok4DSL/libsigrok-internal.h +++ b/libsigrok4DSL/libsigrok-internal.h @@ -67,6 +67,89 @@ struct sr_context { struct timeval hotplug_tv; }; +static const struct sr_dev_mode sr_mode_list[] = +{ + {LOGIC,"Logic Analyzer","la"}, + {ANALOG, "Data Acquisition", "daq"}, + {DSO, "Oscilloscope", "osc"}, +}; + +enum sr_dev_driver_type +{ + DRIVER_TYPE_DEMO = 0, + DRIVER_TYPE_FILE = 1, + DRIVER_TYPE_HARDWARE = 2 +}; + +struct sr_dev_driver { + /* Driver-specific */ + char *name; + char *longname; + int api_version; + int driver_type; // enum sr_dev_driver_type + int (*init) (struct sr_context *sr_ctx); + int (*cleanup) (void); + GSList *(*scan) (GSList *options); + GSList *(*dev_list) (void); + const GSList *(*dev_mode_list) (const struct sr_dev_inst *sdi); + + int (*config_get) (int id, GVariant **data, + const struct sr_dev_inst *sdi, + const struct sr_channel *ch, + const struct sr_channel_group *cg); + int (*config_set) (int id, GVariant *data, + struct sr_dev_inst *sdi, + struct sr_channel *ch, + struct sr_channel_group *cg); + int (*config_list) (int info_id, GVariant **data, + const struct sr_dev_inst *sdi, + const struct sr_channel_group *cg); + + /* Device-specific */ + int (*dev_open) (struct sr_dev_inst *sdi); + int (*dev_close) (struct sr_dev_inst *sdi); + int (*dev_destroy) (struct sr_dev_inst *sdi); + int (*dev_status_get) (const struct sr_dev_inst *sdi, + struct sr_status *status, gboolean prg); + int (*dev_acquisition_start) (struct sr_dev_inst *sdi, + void *cb_data); + int (*dev_acquisition_stop) (const struct sr_dev_inst *sdi, + void *cb_data); + + /* Dynamic */ + void *priv; +}; + +struct sr_dev_inst { + /** Device driver. */ + struct sr_dev_driver *driver; + /**Identity. */ + sr_device_handle handle; + /** device name. */ + char name[50]; + /** Device type:(demo,filelog,hardware). The type see enum sr_device_type. */ + int dev_type; + /** Index of device in driver. */ + int index; + /** Device instance status. SR_ST_NOT_FOUND, etc. */ + int status; + /** Device mode. LA/DAQ/OSC, etc. */ + int mode; + /** Device vendor. */ + char *vendor; + + /** Device version. */ + char *version; + /** List of channels. */ + GSList *channels; + /** List of sr_channel_group structs */ + GSList *channel_groups; + /** Device instance connection data (used?) */ + void *conn; + /** Device instance private data (used?) */ + void *priv; +}; + struct sr_session { /** List of struct sr_dev pointers. */ GSList *devs; @@ -99,6 +182,8 @@ struct sr_usb_dev_inst { uint8_t bus; uint8_t address; struct libusb_device_handle *devhdl; + struct libusb_device *usb_dev; + int is_wait_re_connected; }; #define SERIAL_PARITY_NONE 0 @@ -193,7 +278,6 @@ SR_PRIV int sr_session_datafeed_callback_add(sr_datafeed_callback_t cb,void *cb_ /*--- std.c -----------------------------------------------------------------*/ typedef int (*dev_close_t)(struct sr_dev_inst *sdi); -typedef void (*std_dev_clear_t)(void *priv); SR_PRIV int std_hw_init(struct sr_context *sr_ctx, struct sr_dev_driver *di, const char *prefix); @@ -202,8 +286,6 @@ SR_PRIV int std_hw_dev_acquisition_stop_serial(struct sr_dev_inst *sdi, 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); -SR_PRIV int std_dev_clear(const struct sr_dev_driver *driver, - std_dev_clear_t clear_private); /*--- trigger.c -------------------------------------------------*/ SR_PRIV uint64_t sr_trigger_get_mask0(uint16_t stage); @@ -271,5 +353,9 @@ SR_PRIV int sr_close_hotplug(struct sr_context *ctx); SR_PRIV void sr_hotplug_wait_timout(struct sr_context *ctx); /*--- lib_main.c -------------------------------------------------*/ +/** + * Check whether the USB device is in the device list. + */ +SR_PRIV int sr_usb_device_is_exists(libusb_device *usb_dev); #endif diff --git a/libsigrok4DSL/libsigrok.h b/libsigrok4DSL/libsigrok.h index 1f98cbde..05b56da6 100644 --- a/libsigrok4DSL/libsigrok.h +++ b/libsigrok4DSL/libsigrok.h @@ -63,6 +63,8 @@ extern "C" { * return codes, but never remove or redefine existing ones. */ +#define SR_LIB_NAME "libsigrok" + /** Status/error codes returned by libsigrok functions. */ enum { SR_OK = 0, /**< No error. */ @@ -160,13 +162,12 @@ enum { #define SR_PRIV #endif -typedef unsigned long long sr_device_handle; - enum sr_device_type{ DEV_TYPE_UNKOWN = 0, DEV_TYPE_DEMO = 1, DEV_TYPE_FILELOG = 2, - DEV_TYPE_HARDWARE = 3, + DEV_TYPE_USB = 3, + DEV_TYPE_SERIAL = 4, }; /** Data types used by sr_config_info(). */ @@ -334,6 +335,8 @@ enum { }; struct sr_context; //hidden all field +struct sr_dev_inst; +struct sr_dev_driver; struct sr_datafeed_packet { uint16_t type; @@ -1069,45 +1072,6 @@ enum sr_config_option_id{ SR_CONF_DATALOG, }; -struct sr_dev_inst { - /** Device driver. */ - struct sr_dev_driver *driver; - /**Identity. */ - sr_device_handle handle; - /** Device type:(demo,filelog,hardware). The type see enum sr_device_type. */ - int dev_type; - /** Index of device in driver. */ - int index; - /** Device instance status. SR_ST_NOT_FOUND, etc. */ - int status; - /** Device instance type. SR_INST_USB, etc. */ - int inst_type; - /** Device mode. LA/DAQ/OSC, etc. */ - int mode; - /** Device vendor. */ - char *vendor; - /** Device model. */ - char *model; - /** Device version. */ - char *version; - /** List of channels. */ - GSList *channels; - /** List of sr_channel_group structs */ - GSList *channel_groups; - /** Device instance connection data (used?) */ - void *conn; - /** Device instance private data (used?) */ - void *priv; -}; - -/** Types of device instances (sr_dev_inst). */ -enum { - /** Device instance type for USB devices. */ - SR_INST_USB = 10000, - /** Device instance type for serial port devices. */ - SR_INST_SERIAL, -}; - /** Device instance status. */ enum { /** The device instance was not found. */ @@ -1175,52 +1139,6 @@ struct sr_dev_mode { const char *name; const char *acronym; }; - -static const struct sr_dev_mode sr_mode_list[] = -{ - {LOGIC,"Logic Analyzer","la"}, - {ANALOG, "Data Acquisition", "daq"}, - {DSO, "Oscilloscope", "osc"}, -}; - -struct sr_dev_driver { - /* Driver-specific */ - char *name; - char *longname; - int api_version; - int (*init) (struct sr_context *sr_ctx); - int (*cleanup) (void); - GSList *(*scan) (GSList *options); - GSList *(*dev_list) (void); - const GSList *(*dev_mode_list) (const struct sr_dev_inst *sdi); - int (*dev_clear) (void); - - int (*config_get) (int id, GVariant **data, - const struct sr_dev_inst *sdi, - const struct sr_channel *ch, - const struct sr_channel_group *cg); - int (*config_set) (int id, GVariant *data, - struct sr_dev_inst *sdi, - struct sr_channel *ch, - struct sr_channel_group *cg); - int (*config_list) (int info_id, GVariant **data, - const struct sr_dev_inst *sdi, - const struct sr_channel_group *cg); - - /* Device-specific */ - int (*dev_open) (struct sr_dev_inst *sdi); - int (*dev_close) (struct sr_dev_inst *sdi); - int (*dev_destroy) (struct sr_dev_inst *sdi); - int (*dev_status_get) (const struct sr_dev_inst *sdi, - struct sr_status *status, gboolean prg); - int (*dev_acquisition_start) (struct sr_dev_inst *sdi, - void *cb_data); - int (*dev_acquisition_stop) (const struct sr_dev_inst *sdi, - void *cb_data); - - /* Dynamic */ - void *priv; -}; enum { SIMPLE_TRIGGER = 0, @@ -1391,43 +1309,48 @@ SR_API void sr_log_level(int level); /*---event define ---------------------------------------------*/ enum libsigrok_event_type { - // A new device attachs, user need calls sr_device_get_list to get the list, - // and call sr_device_select to swith a new device. - EV_DEVICE_ATTACH = 0, + // A new device attached, user need to call sr_device_get_list to get the list, + // the last one is new. + // User can call sr_device_select() to switch to the current device. + SR_EV_NEW_DEVICE_ATTACH = 0, - // A device detachs, user need calls sr_device_get_list to get the list, - // and call sr_device_select to swith a new device. - EV_DEVICE_DETACH = 1, + // The current device detached, user need to call sr_device_get_list to get the list, + // and call sr_device_select() to switch to the current device. + SR_EV_CURRENT_DEVICE_DETACH = 1, - // User can call sr_device_get_list to get new list, and update the data view. - EV_CURRENT_DEVICE_CHANGED = 2, + // A inactive device detached. + // User can call sr_device_get_list() to get the new list, and update the list view. + SR_EV_INACTIVE_DEVICE_DETACH = 2, - // User can call sr_device_get_list to get new list, and update the list view. - EV_DEVICE_LIST_CHANGED = 3, + // The current device switch success. + // User can call sr_device_get_list() to get new list, and update the data view. + SR_EV_CURRENT_DEVICE_CHANGED = 3, }; +typedef unsigned long long sr_device_handle; + /** * Device base info */ struct sr_device_info { - sr_device_handle _handle; - char _name[50]; - int _dev_type; // enum sr_device_type - int _is_current; //is actived + sr_device_handle handle; + char name[50]; + int dev_type; // enum sr_device_type + int is_current; //is actived }; struct sr_task_progress { - int _progress; - int _is_end; + int progress; + int is_end; }; struct sr_store_extra_data { - char _name[50]; - char *_data; - int _data_length; + char name[50]; + char *data; + int data_length; }; @@ -1451,7 +1374,7 @@ SR_API int sr_lib_exit(); /** * Set event callback, event type see enum libsigrok_event_type */ -SR_API void sr_set_event_callback(libsigrok_event_callback_t *cb); +SR_API void sr_set_event_callback(libsigrok_event_callback_t cb); /** * By default, the library can manage data by itself. If set the callback, @@ -1466,20 +1389,18 @@ SR_API int sr_set_datafeed_callback(sr_datafeed_callback_t cb, void *cb_data); SR_API void sr_set_firmware_resource_dir(const char *dir); /** - * Get the device list, the last item is null. - * User need call free() to release the buffer. If the list is empty, it returns null. + * Get the device list, if the field _handle is 0, the list visited to end. + * User need call free() to release the buffer. If the list is empty, the out_list is null. */ -SR_API struct sr_device_info* sr_device_get_list(int *out_count); +SR_API int sr_device_get_list(struct sr_device_info** out_list, int *out_count); /** - * Active a device, if success, it will trigs the event of EV_CURRENT_DEVICE_CHANGED. - * If the old actived device is hardware, maybe user need store the data first. + * Active a device, if success, it will trigs the event of SR_EV_CURRENT_DEVICE_CHANGED. */ SR_API int sr_device_select(sr_device_handle handle); /** - * Active a device, if success, it will trigs the event of EV_CURRENT_DEVICE_CHANGED. - * If the old actived device is hardware, maybe user need store the data first. + * Active a device, if success, it will trigs the event of SR_EV_CURRENT_DEVICE_CHANGED. * @index is -1, will select the last one. */ SR_API int sr_device_select_by_index(int index); @@ -1490,16 +1411,16 @@ SR_API int sr_device_select_by_index(int index); SR_API int sr_device_from_file(const char *file_path); /** - * Get current sample count + * Remove one device from the list, and destory it. + * User need to call sr_device_get_list() to get the new list. */ -SR_API uint64_t sr_sample_count(); +SR_API int sr_remove_device(sr_device_handle handle); /** - * Store current session data. - * @ext_data_array is the extra data. + * Get the current device info. + * If the current device is not exists, the handle filed will be set null. */ -SR_API int sr_store_session_data(struct sr_task_progress *prog, const char *file_path, - struct sr_store_extra_data *ext_data_array, int ext_data_count); +SR_API int sr_get_current_device_info(struct sr_device_info *info); /** * Start collect data diff --git a/libsigrok4DSL/session_driver.c b/libsigrok4DSL/session_driver.c index 670c1620..14e7165f 100644 --- a/libsigrok4DSL/session_driver.c +++ b/libsigrok4DSL/session_driver.c @@ -1020,12 +1020,12 @@ SR_PRIV struct sr_dev_driver session_driver = { .name = "virtual-session", .longname = "Session-emulating driver", .api_version = 1, + .driver_type = DRIVER_TYPE_FILE, .init = init, .cleanup = dev_clear, .scan = NULL, .dev_list = NULL, .dev_mode_list = dev_mode_list, - .dev_clear = dev_clear, .config_get = config_get, .config_set = config_set, .config_list = config_list, diff --git a/libsigrok4DSL/std.c b/libsigrok4DSL/std.c index 82bc8f66..2e8b39c6 100644 --- a/libsigrok4DSL/std.c +++ b/libsigrok4DSL/std.c @@ -53,7 +53,6 @@ SR_PRIV int std_hw_init(struct sr_context *sr_ctx, struct sr_dev_driver *di, } drvc->sr_ctx = sr_ctx; - drvc->instances = NULL; di->priv = drvc; return SR_OK; @@ -161,63 +160,4 @@ SR_PRIV int std_hw_dev_acquisition_stop_serial(struct sr_dev_inst *sdi, } return SR_OK; -} - -/* - * Standard driver dev_clear() helper. - * - * This function can be used to implement the dev_clear() driver API - * callback. dev_close() is called before every sr_dev_inst is cleared. - * - * The only limitation is driver-specific device contexts (sdi->priv). - * These are freed, but any dynamic allocation within structs stored - * there cannot be freed. - * - * @param driver The driver which will have its instances released. - * - * @return SR_OK on success. - */ -SR_PRIV int std_dev_clear(const struct sr_dev_driver *driver, - std_dev_clear_t clear_private) -{ - struct sr_dev_inst *sdi; - struct drv_context *drvc; - struct dev_context *devc; - GSList *l; - int ret; - - if (!(drvc = driver->priv)) - /* Driver was never initialized, nothing to do. */ - return SR_OK; - - ret = SR_OK; - for (l = drvc->instances; l; l = l->next) { - /* Log errors, but continue cleaning up the rest. */ - if (!(sdi = l->data)) { - ret = SR_ERR_BUG; - continue; - } - if (!(devc = sdi->priv)) { - ret = SR_ERR_BUG; - continue; - } - if (driver->dev_close) - driver->dev_close(sdi); - - if (sdi->conn) { - if (sdi->inst_type == SR_INST_USB) - sr_usb_dev_inst_free(sdi->conn); - else if (sdi->inst_type == SR_INST_SERIAL) - sr_serial_dev_inst_free(sdi->conn); - } - if (clear_private) - clear_private(sdi->priv); - sdi = l->data; - sr_dev_inst_free(sdi); - } - - g_slist_free(drvc->instances); - drvc->instances = NULL; - - return ret; -} +} \ No newline at end of file diff --git a/libsigrok4DSL/tests/test_main.c b/libsigrok4DSL/tests/test_main.c deleted file mode 100644 index 1eea2d85..00000000 --- a/libsigrok4DSL/tests/test_main.c +++ /dev/null @@ -1,34 +0,0 @@ - -#include -#include "../log.h" -#include - -#undef LOG_PREFIX -#define LOG_PREFIX "test_main: " - -int main() -{ - int ret = 0; - - if ((ret = sr_lib_init()) != SR_OK) - { - return 0; - } - sr_info("%s", "start."); - - char c = 0; - - while (1) - { - c = getchar(); - - if (c == 'x'){ - sr_lib_exit(); - sr_info("%s", "exit."); - break; - } - } - - - return 0; -} \ No newline at end of file diff --git a/libsigrok4DSL/tests/test_main.cpp b/libsigrok4DSL/tests/test_main.cpp new file mode 100644 index 00000000..6bcc30ed --- /dev/null +++ b/libsigrok4DSL/tests/test_main.cpp @@ -0,0 +1,68 @@ + +#include +#include "../log.h" +#include +#include +#include +#include + +#include +#include +#include + +using namespace std; + +#undef LOG_PREFIX +#define LOG_PREFIX "test_main: " + +int b_exit = 0; + +void print_log(const char *data, int len){ + if (len > 0){ + //*(data + len-1) = 0; + QString s(data); + // qDebug()<