aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Schink <jaylink-dev@marcschink.de>2016-07-29 10:33:03 +0200
committerMarc Schink <jaylink-dev@marcschink.de>2016-08-03 01:01:43 +0200
commitaee8ed0d9449a2157b1f19ba1a0de0992593d803 (patch)
treeb1459f43d3f2c7d22122d787750016e7f71f448a
parentabb7feafed252eefef9c8a16d0120a3017b1d934 (diff)
Use string for IPv4 address in jaylink_connection
Instead of representing the IPv4 address as 32-bit integer, use the much more convenient quad-dotted decimal string representation. Signed-off-by: Marc Schink <jaylink-dev@marcschink.de>
-rw-r--r--configure.ac4
-rw-r--r--libjaylink/core.c29
-rw-r--r--libjaylink/device.c86
-rw-r--r--libjaylink/discovery.c7
-rw-r--r--libjaylink/libjaylink-internal.h7
-rw-r--r--libjaylink/libjaylink.h11
6 files changed, 125 insertions, 19 deletions
diff --git a/configure.ac b/configure.ac
index d8c15d7..e8780fc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -111,6 +111,10 @@ AS_CASE([$host_os], [mingw*],
[AC_DEFINE([__USE_MINGW_ANSI_STDIO], [1],
[Define to 1 to use C99 compatible stdio functions on MinGW.])])
+# Add the Winsock2 library on MinGW for socket and other network-related
+# functions.
+AS_CASE([$host_os], [mingw*], [LIBS="$LIBS -lws2_32"])
+
AC_CONFIG_FILES([Makefile])
AC_CONFIG_FILES([libjaylink/Makefile])
AC_CONFIG_FILES([libjaylink/version.h])
diff --git a/libjaylink/core.c b/libjaylink/core.c
index 45b6138..9eb444e 100644
--- a/libjaylink/core.c
+++ b/libjaylink/core.c
@@ -18,6 +18,9 @@
*/
#include <stdlib.h>
+#ifdef _WIN32
+#include <winsock2.h>
+#endif
#include <libusb.h>
#include "libjaylink.h"
@@ -48,6 +51,9 @@ JAYLINK_API int jaylink_init(struct jaylink_context **ctx)
{
int ret;
struct jaylink_context *context;
+#ifdef _WIN32
+ WSADATA wsa_data;
+#endif
if (!ctx)
return JAYLINK_ERR_ARG;
@@ -62,6 +68,22 @@ JAYLINK_API int jaylink_init(struct jaylink_context **ctx)
return JAYLINK_ERR;
}
+#ifdef _WIN32
+ ret = WSAStartup(MAKEWORD(2, 2), &wsa_data);
+
+ if (ret != 0) {
+ libusb_exit(context->usb_ctx);
+ free(context);
+ return JAYLINK_ERR;
+ }
+
+ if (LOBYTE(wsa_data.wVersion) != 2 || HIBYTE(wsa_data.wVersion) != 2) {
+ libusb_exit(context->usb_ctx);
+ free(context);
+ return JAYLINK_ERR;
+ }
+#endif
+
context->devs = NULL;
context->discovered_devs = NULL;
@@ -74,6 +96,9 @@ JAYLINK_API int jaylink_init(struct jaylink_context **ctx)
ret = jaylink_log_set_domain(context, JAYLINK_LOG_DOMAIN_DEFAULT);
if (ret != JAYLINK_OK) {
+#ifdef _WIN32
+ WSACleanup();
+#endif
free(context);
return ret;
}
@@ -111,6 +136,10 @@ JAYLINK_API int jaylink_exit(struct jaylink_context *ctx)
list_free(ctx->devs);
libusb_exit(ctx->usb_ctx);
+#ifdef _WIN32
+ WSACleanup();
+#endif
+
free(ctx);
return JAYLINK_OK;
diff --git a/libjaylink/device.c b/libjaylink/device.c
index 73e5537..cadddd8 100644
--- a/libjaylink/device.c
+++ b/libjaylink/device.c
@@ -21,6 +21,12 @@
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
+#ifdef _WIN32
+#include <winsock2.h>
+#else
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#endif
#include <libusb.h>
#include "libjaylink.h"
@@ -1022,12 +1028,20 @@ static void parse_conntable(struct jaylink_connection *conns,
{
unsigned int i;
size_t offset;
+ struct in_addr in;
offset = 0;
for (i = 0; i < num; i++) {
conns[i].pid = buffer_get_u32(buffer, offset);
- conns[i].hid = buffer_get_u32(buffer, offset + 4);
+
+ in.s_addr = buffer_get_u32(buffer, offset + 4);
+ /*
+ * Use inet_ntoa() instead of inet_ntop() because the latter
+ * requires at least Windows Vista.
+ */
+ strcpy(conns[i].hid, inet_ntoa(in));
+
conns[i].iid = buffer[offset + 8];
conns[i].cid = buffer[offset + 9];
conns[i].handle = buffer_get_u16(buffer, offset + 10);
@@ -1036,6 +1050,34 @@ static void parse_conntable(struct jaylink_connection *conns,
}
}
+static bool _inet_pton(const char *str, struct in_addr *in)
+{
+#ifdef _WIN32
+ int ret;
+ struct sockaddr_in sock_in;
+ int length;
+
+ length = sizeof(sock_in);
+
+ /*
+ * Use WSAStringToAddress() instead of inet_pton() because the latter
+ * requires at least Windows Vista.
+ */
+ ret = WSAStringToAddress((LPTSTR)str, AF_INET, NULL,
+ (LPSOCKADDR)&sock_in, &length);
+
+ if (ret != 0)
+ return false;
+
+ *in = sock_in.sin_addr;
+#else
+ if (inet_pton(AF_INET, str, in) != 1)
+ return false;
+#endif
+
+ return true;
+}
+
/**
* Register a connection on a device.
*
@@ -1088,26 +1130,33 @@ JAYLINK_API int jaylink_register(struct jaylink_device_handle *devh,
uint32_t size;
uint32_t table_size;
uint16_t addinfo_size;
+ struct in_addr in;
if (!devh || !connection || !connections || !count)
return JAYLINK_ERR_ARG;
ctx = devh->dev->ctx;
- ret = transport_start_write_read(devh, 14, REG_MIN_SIZE, true);
-
- if (ret != JAYLINK_OK) {
- log_err(ctx, "transport_start_write_read() failed: %i.", ret);
- return ret;
- }
buf[0] = CMD_REGISTER;
buf[1] = REG_CMD_REGISTER;
buffer_set_u32(buf, connection->pid, 2);
- buffer_set_u32(buf, connection->hid, 6);
+
+ if (!_inet_pton(connection->hid, &in))
+ return JAYLINK_ERR_ARG;
+
+ buffer_set_u32(buf, in.s_addr, 6);
+
buf[10] = connection->iid;
buf[11] = connection->cid;
buffer_set_u16(buf, connection->handle, 12);
+ ret = transport_start_write_read(devh, 14, REG_MIN_SIZE, true);
+
+ if (ret != JAYLINK_OK) {
+ log_err(ctx, "transport_start_write_read() failed: %i.", ret);
+ return ret;
+ }
+
ret = transport_write(devh, buf, 14);
if (ret != JAYLINK_OK) {
@@ -1225,26 +1274,33 @@ JAYLINK_API int jaylink_unregister(struct jaylink_device_handle *devh,
uint32_t size;
uint32_t table_size;
uint16_t addinfo_size;
+ struct in_addr in;
if (!devh || !connection || !connections || !count)
return JAYLINK_ERR_ARG;
ctx = devh->dev->ctx;
- ret = transport_start_write_read(devh, 14, REG_MIN_SIZE, true);
-
- if (ret != JAYLINK_OK) {
- log_err(ctx, "transport_start_write_read() failed: %i.", ret);
- return ret;
- }
buf[0] = CMD_REGISTER;
buf[1] = REG_CMD_UNREGISTER;
buffer_set_u32(buf, connection->pid, 2);
- buffer_set_u32(buf, connection->hid, 6);
+
+ if (!_inet_pton(connection->hid, &in))
+ return JAYLINK_ERR_ARG;
+
+ buffer_set_u32(buf, in.s_addr, 6);
+
buf[10] = connection->iid;
buf[11] = connection->cid;
buffer_set_u16(buf, connection->handle, 12);
+ ret = transport_start_write_read(devh, 14, REG_MIN_SIZE, true);
+
+ if (ret != JAYLINK_OK) {
+ log_err(ctx, "transport_start_write_read() failed: %i.", ret);
+ return ret;
+ }
+
ret = transport_write(devh, buf, 14);
if (ret != JAYLINK_OK) {
diff --git a/libjaylink/discovery.c b/libjaylink/discovery.c
index da20d17..fa72da4 100644
--- a/libjaylink/discovery.c
+++ b/libjaylink/discovery.c
@@ -23,11 +23,16 @@
#include <stdbool.h>
#include <string.h>
#include <sys/types.h>
-#include <libusb.h>
#include "libjaylink.h"
#include "libjaylink-internal.h"
+/*
+ * libusb.h includes windows.h and therefore must be included after anything
+ * that includes winsock2.h.
+ */
+#include <libusb.h>
+
/**
* @file
*
diff --git a/libjaylink/libjaylink-internal.h b/libjaylink/libjaylink-internal.h
index 47a24a1..f22cb2a 100644
--- a/libjaylink/libjaylink-internal.h
+++ b/libjaylink/libjaylink-internal.h
@@ -24,10 +24,15 @@
#include <stdint.h>
#include <stdbool.h>
#include <sys/types.h>
-#include <libusb.h>
#include "libjaylink.h"
+/*
+ * libusb.h includes windows.h and therefore must be included after anything
+ * that includes winsock2.h.
+ */
+#include <libusb.h>
+
/**
* @file
*
diff --git a/libjaylink/libjaylink.h b/libjaylink/libjaylink.h
index a1f72a0..760bdee 100644
--- a/libjaylink/libjaylink.h
+++ b/libjaylink/libjaylink.h
@@ -25,6 +25,11 @@
#include <stdbool.h>
#include <stdarg.h>
#include <sys/types.h>
+#ifdef _WIN32
+#include <ws2tcpip.h>
+#else
+#include <arpa/inet.h>
+#endif
/**
* @file
@@ -272,9 +277,11 @@ struct jaylink_connection {
/**
* Host ID (HID).
*
- * IP address of the client in network byte order.
+ * IPv4 address string of the client in quad-dotted decimal format
+ * (e.g. 192.0.2.235). The address 0.0.0.0 should be used for the
+ * registration of an USB connection.
*/
- uint32_t hid;
+ char hid[INET_ADDRSTRLEN];
/** IID. */
uint8_t iid;
/** CID. */