Commit b29828e8daaabf747cf84c93957efb549400af77

Kano 2013-03-16T21:54:34

usbutils allow read termination match to be a string

diff --git a/usbutils.c b/usbutils.c
index 750755b..10a9dea 100644
--- a/usbutils.c
+++ b/usbutils.c
@@ -1559,7 +1559,7 @@ static void rejected_inc(struct cgpu_info *cgpu)
 }
 #endif
 
-int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *processed, unsigned int timeout, int eol, enum usb_cmds cmd, bool ftdi)
+int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *processed, unsigned int timeout, const char *end, enum usb_cmds cmd, bool ftdi)
 {
 	struct cg_usb_device *usbdev = cgpu->usbdev;
 #if DO_USB_STATS
@@ -1568,8 +1568,10 @@ int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pro
 	struct timeval read_start, tv_finish;
 	unsigned int initial_timeout;
 	double max, done;
-	int err, got, tot, i;
+	int err, got, tot;
 	bool first = true;
+	char *search;
+	int endlen;
 
 	if (cgpu->usbinfo.nodev) {
 		*buf = '\0';
@@ -1583,7 +1585,7 @@ int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pro
 	if (timeout == DEVTIMEOUT)
 		timeout = usbdev->found->timeout;
 
-	if (eol == -1) {
+	if (end == NULL) {
 		got = 0;
 		STATS_TIMEVAL(&tv_start);
 		err = libusb_bulk_transfer(usbdev->handle,
@@ -1613,6 +1615,7 @@ int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pro
 	}
 
 	tot = 0;
+	endlen = strlen(end);
 	err = LIBUSB_SUCCESS;
 	initial_timeout = timeout;
 	max = ((double)timeout) / 1000.0;
@@ -1643,10 +1646,23 @@ int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pro
 		if (err)
 			break;
 
-		// WARNING - this will return data past EOL ('if' there is extra data)
-		for (i = 0; i < got; i++)
-			if (buf[i] == eol)
-				goto goteol;
+		// WARNING - this will return data past END ('if' there is extra data)
+		if (endlen <= tot) {
+			// If END is only 1 char - do a faster search
+			if (endlen == 1) {
+				if (strchr(buf, *end))
+					break;
+			} else {
+				// must allow END to have been chopped in 2 transfers
+				if ((tot - got) >= (endlen - 1))
+					search = buf - (endlen - 1);
+				else
+					search = buf - (tot - got);
+
+				if (strstr(search, end))
+					break;
+			}
+		}
 
 		buf += got;
 		bufsiz -= got;
@@ -1661,8 +1677,6 @@ int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pro
 		timeout = initial_timeout - (done * 1000);
 	}
 
-goteol:
-
 	*processed = tot;
 
 	if (NODEV(err))
diff --git a/usbutils.h b/usbutils.h
index de79312..5b5c133 100644
--- a/usbutils.h
+++ b/usbutils.h
@@ -135,26 +135,26 @@ bool usb_init(struct cgpu_info *cgpu, struct libusb_device *dev, struct usb_find
 void usb_detect(struct device_drv *drv, bool (*device_detect)(struct libusb_device *, struct usb_find_devices *));
 struct api_data *api_usb_stats(int *count);
 void update_usb_stats(struct cgpu_info *cgpu);
-int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *processed, unsigned int timeout, int eol, enum usb_cmds, bool ftdi);
+int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *processed, unsigned int timeout, const char *end, enum usb_cmds cmd, bool ftdi);
 int _usb_write(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *processed, unsigned int timeout, enum usb_cmds);
 int _usb_transfer(struct cgpu_info *cgpu, uint8_t request_type, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, unsigned int timeout, enum usb_cmds cmd);
 void usb_cleanup();
 void usb_initialise();
 
 #define usb_read(cgpu, buf, bufsiz, read, cmd) \
-	_usb_read(cgpu, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, -1, cmd, false)
+	_usb_read(cgpu, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, NULL, cmd, false)
 
 #define usb_read_nl(cgpu, buf, bufsiz, read, cmd) \
-	_usb_read(cgpu, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, '\n', cmd, false)
+	_usb_read(cgpu, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, "\n", cmd, false)
 
 #define usb_read_ep(cgpu, ep, buf, bufsiz, read, cmd) \
-	_usb_read(cgpu, ep, buf, bufsiz, read, DEVTIMEOUT, -1, cmd, false)
+	_usb_read(cgpu, ep, buf, bufsiz, read, DEVTIMEOUT, NULL, cmd, false)
 
 #define usb_read_timeout(cgpu, buf, bufsiz, read, timeout, cmd) \
-	_usb_read(cgpu, DEFAULT_EP_IN, buf, bufsiz, read, timeout, -1, cmd, false)
+	_usb_read(cgpu, DEFAULT_EP_IN, buf, bufsiz, read, timeout, NULL, cmd, false)
 
 #define usb_read_ep_timeout(cgpu, ep, buf, bufsiz, read, timeout, cmd) \
-	_usb_read(cgpu, ep, buf, bufsiz, read, timeout, -1, cmd, false)
+	_usb_read(cgpu, ep, buf, bufsiz, read, timeout, NULL, cmd, false)
 
 #define usb_write(cgpu, buf, bufsiz, wrote, cmd) \
 	_usb_write(cgpu, DEFAULT_EP_OUT, buf, bufsiz, wrote, DEVTIMEOUT, cmd)
@@ -169,7 +169,10 @@ void usb_initialise();
 	_usb_write(cgpu, ep, buf, bufsiz, wrote, timeout, cmd)
 
 #define usb_ftdi_read_nl(cgpu, buf, bufsiz, read, cmd) \
-	_usb_read(cgpu, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, '\n', cmd, true)
+	_usb_read(cgpu, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, "\n", cmd, true)
+
+#define usb_ftdi_read_ok(cgpu, buf, bufsiz, read, cmd) \
+	_usb_read(cgpu, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, "OK\n", cmd, true)
 
 #define usb_transfer(cgpu, typ, req, val, idx, cmd) \
 	_usb_transfer(cgpu, typ, req, val, idx, DEVTIMEOUT, cmd)