X-Git-Url: http://sigrok.org/gitweb/?a=blobdiff_plain;f=serialport.c;h=ef619418a7eadd235c9f98bf157b06a7f30b45f5;hb=970f279ae4767819a816573ae354813d37d5091d;hp=558322ecfff4e3d529d46998fc7e365b5135a147;hpb=65172beffe8d9c4aa4b72782a9b76a4972be3c69;p=libserialport.git diff --git a/serialport.c b/serialport.c index 558322e..ef61941 100644 --- a/serialport.c +++ b/serialport.c @@ -52,7 +52,7 @@ static enum sp_return get_config(struct sp_port *port, struct port_data *data, static enum sp_return set_config(struct sp_port *port, struct port_data *data, const struct sp_port_config *config); -enum sp_return sp_get_port_by_name(const char *portname, struct sp_port **port_ptr) +SP_API enum sp_return sp_get_port_by_name(const char *portname, struct sp_port **port_ptr) { struct sp_port *port; enum sp_return ret; @@ -99,17 +99,19 @@ enum sp_return sp_get_port_by_name(const char *portname, struct sp_port **port_p port->usb_serial = NULL; port->bluetooth_address = NULL; +#ifndef NO_PORT_METADATA if ((ret = get_port_details(port)) != SP_OK) { sp_free_port(port); return ret; } +#endif *port_ptr = port; RETURN_OK(); } -char *sp_get_port_name(const struct sp_port *port) +SP_API char *sp_get_port_name(const struct sp_port *port) { TRACE("%p", port); @@ -119,7 +121,7 @@ char *sp_get_port_name(const struct sp_port *port) RETURN_VALUE("%s", port->name); } -char *sp_get_port_description(struct sp_port *port) +SP_API char *sp_get_port_description(struct sp_port *port) { TRACE("%p", port); @@ -129,7 +131,7 @@ char *sp_get_port_description(struct sp_port *port) RETURN_VALUE("%s", port->description); } -enum sp_transport sp_get_port_transport(struct sp_port *port) +SP_API enum sp_transport sp_get_port_transport(struct sp_port *port) { TRACE("%p", port); @@ -139,8 +141,8 @@ enum sp_transport sp_get_port_transport(struct sp_port *port) RETURN_VALUE("%d", port->transport); } -enum sp_return sp_get_port_usb_bus_address(const struct sp_port *port, - int *usb_bus, int *usb_address) +SP_API enum sp_return sp_get_port_usb_bus_address(const struct sp_port *port, + int *usb_bus,int *usb_address) { TRACE("%p", port); @@ -157,8 +159,8 @@ enum sp_return sp_get_port_usb_bus_address(const struct sp_port *port, RETURN_OK(); } -enum sp_return sp_get_port_usb_vid_pid(const struct sp_port *port, - int *usb_vid, int *usb_pid) +SP_API enum sp_return sp_get_port_usb_vid_pid(const struct sp_port *port, + int *usb_vid, int *usb_pid) { TRACE("%p", port); @@ -175,7 +177,7 @@ enum sp_return sp_get_port_usb_vid_pid(const struct sp_port *port, RETURN_OK(); } -char *sp_get_port_usb_manufacturer(const struct sp_port *port) +SP_API char *sp_get_port_usb_manufacturer(const struct sp_port *port) { TRACE("%p", port); @@ -185,7 +187,7 @@ char *sp_get_port_usb_manufacturer(const struct sp_port *port) RETURN_VALUE("%s", port->usb_manufacturer); } -char *sp_get_port_usb_product(const struct sp_port *port) +SP_API char *sp_get_port_usb_product(const struct sp_port *port) { TRACE("%p", port); @@ -195,7 +197,7 @@ char *sp_get_port_usb_product(const struct sp_port *port) RETURN_VALUE("%s", port->usb_product); } -char *sp_get_port_usb_serial(const struct sp_port *port) +SP_API char *sp_get_port_usb_serial(const struct sp_port *port) { TRACE("%p", port); @@ -205,7 +207,7 @@ char *sp_get_port_usb_serial(const struct sp_port *port) RETURN_VALUE("%s", port->usb_serial); } -char *sp_get_port_bluetooth_address(const struct sp_port *port) +SP_API char *sp_get_port_bluetooth_address(const struct sp_port *port) { TRACE("%p", port); @@ -216,7 +218,8 @@ char *sp_get_port_bluetooth_address(const struct sp_port *port) RETURN_VALUE("%s", port->bluetooth_address); } -enum sp_return sp_get_port_handle(const struct sp_port *port, void *result_ptr) +SP_API enum sp_return sp_get_port_handle(const struct sp_port *port, + void *result_ptr) { TRACE("%p, %p", port, result_ptr); @@ -234,7 +237,8 @@ enum sp_return sp_get_port_handle(const struct sp_port *port, void *result_ptr) RETURN_OK(); } -enum sp_return sp_copy_port(const struct sp_port *port, struct sp_port **copy_ptr) +SP_API enum sp_return sp_copy_port(const struct sp_port *port, + struct sp_port **copy_ptr) { TRACE("%p, %p", port, copy_ptr); @@ -254,7 +258,7 @@ enum sp_return sp_copy_port(const struct sp_port *port, struct sp_port **copy_pt RETURN_VALUE("%p", sp_get_port_by_name(port->name, copy_ptr)); } -void sp_free_port(struct sp_port *port) +SP_API void sp_free_port(struct sp_port *port) { TRACE("%p", port); @@ -287,7 +291,8 @@ void sp_free_port(struct sp_port *port) RETURN(); } -static struct sp_port **list_append(struct sp_port **list, const char *portname) +SP_PRIV struct sp_port **list_append(struct sp_port **list, + const char *portname) { void *tmp; unsigned int count; @@ -306,10 +311,10 @@ fail: return NULL; } -enum sp_return sp_list_ports(struct sp_port ***list_ptr) +SP_API enum sp_return sp_list_ports(struct sp_port ***list_ptr) { struct sp_port **list; - int ret = SP_ERR_SUPP; + int ret; TRACE("%p", list_ptr); @@ -323,175 +328,10 @@ enum sp_return sp_list_ports(struct sp_port ***list_ptr) list[0] = NULL; -#ifdef _WIN32 - HKEY key; - TCHAR *value, *data; - DWORD max_value_len, max_data_size, max_data_len; - DWORD value_len, data_size, data_len; - DWORD type, index = 0; - char *name; - int name_len; - - ret = SP_OK; - - DEBUG("Opening registry key"); - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("HARDWARE\\DEVICEMAP\\SERIALCOMM"), - 0, KEY_QUERY_VALUE, &key) != ERROR_SUCCESS) { - SET_FAIL(ret, "RegOpenKeyEx() failed"); - goto out_done; - } - DEBUG("Querying registry key value and data sizes"); - if (RegQueryInfoKey(key, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - &max_value_len, &max_data_size, NULL, NULL) != ERROR_SUCCESS) { - SET_FAIL(ret, "RegQueryInfoKey() failed"); - goto out_close; - } - max_data_len = max_data_size / sizeof(TCHAR); - if (!(value = malloc((max_value_len + 1) * sizeof(TCHAR)))) { - SET_ERROR(ret, SP_ERR_MEM, "registry value malloc failed"); - goto out_close; - } - if (!(data = malloc((max_data_len + 1) * sizeof(TCHAR)))) { - SET_ERROR(ret, SP_ERR_MEM, "registry data malloc failed"); - goto out_free_value; - } - DEBUG("Iterating over values"); - while ( - value_len = max_value_len + 1, - data_size = max_data_size, - RegEnumValue(key, index, value, &value_len, - NULL, &type, (LPBYTE)data, &data_size) == ERROR_SUCCESS) - { - data_len = data_size / sizeof(TCHAR); - data[data_len] = '\0'; -#ifdef UNICODE - name_len = WideCharToMultiByte(CP_ACP, 0, data, -1, NULL, 0, NULL, NULL); -#else - name_len = data_len + 1; -#endif - if (!(name = malloc(name_len))) { - SET_ERROR(ret, SP_ERR_MEM, "registry port name malloc failed"); - goto out; - } -#ifdef UNICODE - WideCharToMultiByte(CP_ACP, 0, data, -1, name, name_len, NULL, NULL); +#ifdef NO_ENUMERATION + ret = SP_ERR_SUPP; #else - strcpy(name, data); -#endif - if (type == REG_SZ) { - DEBUG("Found port %s", name); - if (!(list = list_append(list, name))) { - SET_ERROR(ret, SP_ERR_MEM, "list append failed"); - goto out; - } - } - index++; - } -out: - free(data); -out_free_value: - free(value); -out_close: - RegCloseKey(key); -out_done: -#endif -#ifdef __APPLE__ - CFMutableDictionaryRef classes; - io_iterator_t iter; - char path[PATH_MAX]; - io_object_t port; - CFTypeRef cf_path; - Boolean result; - - ret = SP_OK; - - DEBUG("Creating matching dictionary"); - if (!(classes = IOServiceMatching(kIOSerialBSDServiceValue))) { - SET_FAIL(ret, "IOServiceMatching() failed"); - goto out_done; - } - - DEBUG("Getting matching services"); - if (IOServiceGetMatchingServices(kIOMasterPortDefault, classes, - &iter) != KERN_SUCCESS) { - SET_FAIL(ret, "IOServiceGetMatchingServices() failed"); - goto out_done; - } - - DEBUG("Iterating over results"); - while ((port = IOIteratorNext(iter))) { - cf_path = IORegistryEntryCreateCFProperty(port, - CFSTR(kIOCalloutDeviceKey), kCFAllocatorDefault, 0); - if (cf_path) { - result = CFStringGetCString(cf_path, path, sizeof(path), - kCFStringEncodingASCII); - CFRelease(cf_path); - if (result) { - DEBUG("Found port %s", path); - if (!(list = list_append(list, path))) { - SET_ERROR(ret, SP_ERR_MEM, "list append failed"); - IOObjectRelease(port); - goto out; - } - } - } - IOObjectRelease(port); - } -out: - IOObjectRelease(iter); -out_done: -#endif -#ifdef __linux__ - char name[PATH_MAX], target[PATH_MAX]; - struct dirent entry, *result; - struct serial_struct serial_info; - int len, fd, ioctl_result; - DIR *dir; - - ret = SP_OK; - - DEBUG("Enumerating tty devices"); - if (!(dir = opendir("/sys/class/tty"))) - RETURN_FAIL("could not open /sys/class/tty"); - - DEBUG("Iterating over results"); - while (!readdir_r(dir, &entry, &result) && result) { - len = readlinkat(dirfd(dir), entry.d_name, target, sizeof(target)); - if (len <= 0 || len >= (int) sizeof(target)-1) - continue; - target[len] = 0; - if (strstr(target, "virtual")) - continue; - snprintf(name, sizeof(name), "/dev/%s", entry.d_name); - DEBUG("Found device %s", name); - if (strstr(target, "serial8250")) { - /* The serial8250 driver has a hardcoded number of ports. - * The only way to tell which actually exist on a given system - * is to try to open them and make an ioctl call. */ - DEBUG("serial8250 device, attempting to open"); - if ((fd = open(name, O_RDWR | O_NONBLOCK | O_NOCTTY)) < 0) { - DEBUG("open failed, skipping"); - continue; - } - ioctl_result = ioctl(fd, TIOCGSERIAL, &serial_info); - close(fd); - if (ioctl_result != 0) { - DEBUG("ioctl failed, skipping"); - continue; - } - if (serial_info.type == PORT_UNKNOWN) { - DEBUG("port type is unknown, skipping"); - continue; - } - } - DEBUG("Found port %s", name); - list = list_append(list, name); - if (!list) { - SET_ERROR(ret, SP_ERR_MEM, "list append failed"); - break; - } - } - closedir(dir); + ret = list_ports(&list); #endif switch (ret) { @@ -508,7 +348,7 @@ out_done: } } -void sp_free_port_list(struct sp_port **list) +SP_API void sp_free_port_list(struct sp_port **list) { unsigned int i; @@ -550,7 +390,7 @@ void sp_free_port_list(struct sp_port **list) CHECK_PORT_HANDLE(); \ } while (0) -enum sp_return sp_open(struct sp_port *port, enum sp_mode flags) +SP_API enum sp_return sp_open(struct sp_port *port, enum sp_mode flags) { struct port_data data; struct sp_port_config config; @@ -716,7 +556,7 @@ enum sp_return sp_open(struct sp_port *port, enum sp_mode flags) RETURN_OK(); } -enum sp_return sp_close(struct sp_port *port) +SP_API enum sp_return sp_close(struct sp_port *port) { TRACE("%p", port); @@ -750,7 +590,7 @@ enum sp_return sp_close(struct sp_port *port) RETURN_OK(); } -enum sp_return sp_flush(struct sp_port *port, enum sp_buffer buffers) +SP_API enum sp_return sp_flush(struct sp_port *port, enum sp_buffer buffers) { TRACE("%p, 0x%x", port, buffers); @@ -789,7 +629,7 @@ enum sp_return sp_flush(struct sp_port *port, enum sp_buffer buffers) RETURN_OK(); } -enum sp_return sp_drain(struct sp_port *port) +SP_API enum sp_return sp_drain(struct sp_port *port) { TRACE("%p", port); @@ -825,7 +665,8 @@ enum sp_return sp_drain(struct sp_port *port) #endif } -enum sp_return sp_blocking_write(struct sp_port *port, const void *buf, size_t count, unsigned int timeout) +SP_API enum sp_return sp_blocking_write(struct sp_port *port, const void *buf, + size_t count, unsigned int timeout) { TRACE("%p, %p, %d, %d", port, buf, count, timeout); @@ -939,7 +780,8 @@ enum sp_return sp_blocking_write(struct sp_port *port, const void *buf, size_t c #endif } -enum sp_return sp_nonblocking_write(struct sp_port *port, const void *buf, size_t count) +SP_API enum sp_return sp_nonblocking_write(struct sp_port *port, + const void *buf, size_t count) { TRACE("%p, %p, %d", port, buf, count); @@ -1018,7 +860,8 @@ enum sp_return sp_nonblocking_write(struct sp_port *port, const void *buf, size_ #endif } -enum sp_return sp_blocking_read(struct sp_port *port, void *buf, size_t count, unsigned int timeout) +SP_API enum sp_return sp_blocking_read(struct sp_port *port, void *buf, + size_t count, unsigned int timeout) { TRACE("%p, %p, %d, %d", port, buf, count, timeout); @@ -1129,7 +972,8 @@ enum sp_return sp_blocking_read(struct sp_port *port, void *buf, size_t count, u #endif } -enum sp_return sp_nonblocking_read(struct sp_port *port, void *buf, size_t count) +SP_API enum sp_return sp_nonblocking_read(struct sp_port *port, void *buf, + size_t count) { TRACE("%p, %p, %d", port, buf, count); @@ -1182,7 +1026,7 @@ enum sp_return sp_nonblocking_read(struct sp_port *port, void *buf, size_t count #endif } -enum sp_return sp_input_waiting(struct sp_port *port) +SP_API enum sp_return sp_input_waiting(struct sp_port *port) { TRACE("%p", port); @@ -1205,7 +1049,7 @@ enum sp_return sp_input_waiting(struct sp_port *port) #endif } -enum sp_return sp_output_waiting(struct sp_port *port) +SP_API enum sp_return sp_output_waiting(struct sp_port *port) { TRACE("%p", port); @@ -1228,7 +1072,7 @@ enum sp_return sp_output_waiting(struct sp_port *port) #endif } -enum sp_return sp_new_event_set(struct sp_event_set **result_ptr) +SP_API enum sp_return sp_new_event_set(struct sp_event_set **result_ptr) { struct sp_event_set *result; @@ -1276,7 +1120,7 @@ static enum sp_return add_handle(struct sp_event_set *event_set, RETURN_OK(); } -enum sp_return sp_add_port_events(struct sp_event_set *event_set, +SP_API enum sp_return sp_add_port_events(struct sp_event_set *event_set, const struct sp_port *port, enum sp_event mask) { TRACE("%p, %p, %d", event_set, port, mask); @@ -1306,7 +1150,7 @@ enum sp_return sp_add_port_events(struct sp_event_set *event_set, RETURN_OK(); } -void sp_free_event_set(struct sp_event_set *event_set) +SP_API void sp_free_event_set(struct sp_event_set *event_set) { TRACE("%p", event_set); @@ -1327,7 +1171,8 @@ void sp_free_event_set(struct sp_event_set *event_set) RETURN(); } -enum sp_return sp_wait(struct sp_event_set *event_set, unsigned int timeout) +SP_API enum sp_return sp_wait(struct sp_event_set *event_set, + unsigned int timeout) { TRACE("%p, %d", event_set, timeout); @@ -2116,7 +1961,7 @@ static enum sp_return set_config(struct sp_port *port, struct port_data *data, RETURN_OK(); } -enum sp_return sp_new_config(struct sp_port_config **config_ptr) +SP_API enum sp_return sp_new_config(struct sp_port_config **config_ptr) { struct sp_port_config *config; @@ -2144,7 +1989,7 @@ enum sp_return sp_new_config(struct sp_port_config **config_ptr) RETURN_OK(); } -void sp_free_config(struct sp_port_config *config) +SP_API void sp_free_config(struct sp_port_config *config) { TRACE("%p", config); @@ -2156,7 +2001,8 @@ void sp_free_config(struct sp_port_config *config) RETURN(); } -enum sp_return sp_get_config(struct sp_port *port, struct sp_port_config *config) +SP_API enum sp_return sp_get_config(struct sp_port *port, + struct sp_port_config *config) { struct port_data data; @@ -2172,7 +2018,8 @@ enum sp_return sp_get_config(struct sp_port *port, struct sp_port_config *config RETURN_OK(); } -enum sp_return sp_set_config(struct sp_port *port, const struct sp_port_config *config) +SP_API enum sp_return sp_set_config(struct sp_port *port, + const struct sp_port_config *config) { struct port_data data; struct sp_port_config prev_config; @@ -2191,7 +2038,7 @@ enum sp_return sp_set_config(struct sp_port *port, const struct sp_port_config * } #define CREATE_ACCESSORS(x, type) \ -enum sp_return sp_set_##x(struct sp_port *port, type x) { \ +SP_API enum sp_return sp_set_##x(struct sp_port *port, type x) { \ struct port_data data; \ struct sp_port_config config; \ TRACE("%p, %d", port, x); \ @@ -2201,14 +2048,16 @@ enum sp_return sp_set_##x(struct sp_port *port, type x) { \ TRY(set_config(port, &data, &config)); \ RETURN_OK(); \ } \ -enum sp_return sp_get_config_##x(const struct sp_port_config *config, type *x) { \ +SP_API enum sp_return sp_get_config_##x(const struct sp_port_config *config, \ + type *x) { \ TRACE("%p, %p", config, x); \ if (!config) \ RETURN_ERROR(SP_ERR_ARG, "Null config"); \ *x = config->x; \ RETURN_OK(); \ } \ -enum sp_return sp_set_config_##x(struct sp_port_config *config, type x) { \ +SP_API enum sp_return sp_set_config_##x(struct sp_port_config *config, \ + type x) { \ TRACE("%p, %d", config, x); \ if (!config) \ RETURN_ERROR(SP_ERR_ARG, "Null config"); \ @@ -2226,7 +2075,8 @@ CREATE_ACCESSORS(dtr, enum sp_dtr) CREATE_ACCESSORS(dsr, enum sp_dsr) CREATE_ACCESSORS(xon_xoff, enum sp_xonxoff) -enum sp_return sp_set_config_flowcontrol(struct sp_port_config *config, enum sp_flowcontrol flowcontrol) +SP_API enum sp_return sp_set_config_flowcontrol(struct sp_port_config *config, + enum sp_flowcontrol flowcontrol) { if (!config) RETURN_ERROR(SP_ERR_ARG, "Null configuration"); @@ -2260,7 +2110,8 @@ enum sp_return sp_set_config_flowcontrol(struct sp_port_config *config, enum sp_ RETURN_OK(); } -enum sp_return sp_set_flowcontrol(struct sp_port *port, enum sp_flowcontrol flowcontrol) +SP_API enum sp_return sp_set_flowcontrol(struct sp_port *port, + enum sp_flowcontrol flowcontrol) { struct port_data data; struct sp_port_config config; @@ -2278,7 +2129,8 @@ enum sp_return sp_set_flowcontrol(struct sp_port *port, enum sp_flowcontrol flow RETURN_OK(); } -enum sp_return sp_get_signals(struct sp_port *port, enum sp_signal *signals) +SP_API enum sp_return sp_get_signals(struct sp_port *port, + enum sp_signal *signals) { TRACE("%p, %p", port, signals); @@ -2318,7 +2170,7 @@ enum sp_return sp_get_signals(struct sp_port *port, enum sp_signal *signals) RETURN_OK(); } -enum sp_return sp_start_break(struct sp_port *port) +SP_API enum sp_return sp_start_break(struct sp_port *port) { TRACE("%p", port); @@ -2334,7 +2186,7 @@ enum sp_return sp_start_break(struct sp_port *port) RETURN_OK(); } -enum sp_return sp_end_break(struct sp_port *port) +SP_API enum sp_return sp_end_break(struct sp_port *port) { TRACE("%p", port); @@ -2350,7 +2202,7 @@ enum sp_return sp_end_break(struct sp_port *port) RETURN_OK(); } -int sp_last_error_code(void) +SP_API int sp_last_error_code(void) { TRACE(""); #ifdef _WIN32 @@ -2360,7 +2212,7 @@ int sp_last_error_code(void) #endif } -char *sp_last_error_message(void) +SP_API char *sp_last_error_message(void) { TRACE(""); @@ -2384,7 +2236,7 @@ char *sp_last_error_message(void) #endif } -void sp_free_error_message(char *message) +SP_API void sp_free_error_message(char *message) { TRACE("%s", message); @@ -2397,7 +2249,7 @@ void sp_free_error_message(char *message) RETURN(); } -void sp_set_debug_handler(void (*handler)(const char *format, ...)) +SP_API void sp_set_debug_handler(void (*handler)(const char *format, ...)) { TRACE("%p", handler); @@ -2406,7 +2258,7 @@ void sp_set_debug_handler(void (*handler)(const char *format, ...)) RETURN(); } -void sp_default_debug_handler(const char *format, ...) +SP_API void sp_default_debug_handler(const char *format, ...) { va_list args; va_start(args, format); @@ -2417,42 +2269,42 @@ void sp_default_debug_handler(const char *format, ...) va_end(args); } -int sp_get_major_package_version(void) +SP_API int sp_get_major_package_version(void) { return SP_PACKAGE_VERSION_MAJOR; } -int sp_get_minor_package_version(void) +SP_API int sp_get_minor_package_version(void) { return SP_PACKAGE_VERSION_MINOR; } -int sp_get_micro_package_version(void) +SP_API int sp_get_micro_package_version(void) { return SP_PACKAGE_VERSION_MICRO; } -const char *sp_get_package_version_string(void) +SP_API const char *sp_get_package_version_string(void) { return SP_PACKAGE_VERSION_STRING; } -int sp_get_current_lib_version(void) +SP_API int sp_get_current_lib_version(void) { return SP_LIB_VERSION_CURRENT; } -int sp_get_revision_lib_version(void) +SP_API int sp_get_revision_lib_version(void) { return SP_LIB_VERSION_REVISION; } -int sp_get_age_lib_version(void) +SP_API int sp_get_age_lib_version(void) { return SP_LIB_VERSION_AGE; } -const char *sp_get_lib_version_string(void) +SP_API const char *sp_get_lib_version_string(void) { return SP_LIB_VERSION_STRING; }