[svn-commits] mnicholson: branch mnicholson/chan-mobile-refactor r739 - /team/mnicholson/ch...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Mon Jan 26 10:40:52 CST 2009


Author: mnicholson
Date: Mon Jan 26 10:40:51 2009
New Revision: 739

URL: http://svn.digium.com/svn-view/asterisk-addons?view=rev&rev=739
Log:
Rewrote rfcomm_read and added rfcomm_wait.

Modified:
    team/mnicholson/chan-mobile-refactor/channels/chan_mobile.c

Modified: team/mnicholson/chan-mobile-refactor/channels/chan_mobile.c
URL: http://svn.digium.com/svn-view/asterisk-addons/team/mnicholson/chan-mobile-refactor/channels/chan_mobile.c?view=diff&rev=739&r1=738&r2=739
==============================================================================
--- team/mnicholson/chan-mobile-refactor/channels/chan_mobile.c (original)
+++ team/mnicholson/chan-mobile-refactor/channels/chan_mobile.c Mon Jan 26 10:40:51 2009
@@ -218,7 +218,8 @@
 
 static int rfcomm_connect(bdaddr_t src, bdaddr_t dst, int remote_channel);
 static int rfcomm_write(int rfcomm_socket, char *buf);
-static int rfcomm_read(struct mbl_pvt *pvt, char *buf, char flush, int timeout);
+static int rfcomm_wait(int rsock, int *ms);
+static ssize_t rfcomm_read(int rsock, char *buf, size_t count);
 
 static int sco_connect(bdaddr_t src, bdaddr_t dst);
 static int sco_write(int s, char *buf, int len);
@@ -1033,70 +1034,72 @@
 
 }
 
+static int rfcomm_wait(int rsock, int *ms)
+{
+	int exception;
+	return ast_waitfor_n_fd(&rsock, 1, ms, &exception);
+}
+
 /*
-
-	Here we need to return complete '\r' terminated single responses to the devices monitor thread, or
-	a timeout if nothing is available.
-	The rfcomm connection to the device is asynchronous, so there is no guarantee that responses will
-	be returned in a single read() call. We handle this by buffering the input and returning one response
-	per call, or a timeout if nothing is available.
-
-*/
-
-static int rfcomm_read(struct mbl_pvt *pvt, char *buf, char flush, int timeout)
-{
-
-	int sel, rlen, slen;
-	fd_set rfds;
-	struct timeval tv;
-	char *p;
-
-	if (!flush) {
-		if ((p = strchr(pvt->rfcomm_buf, '\r'))) {
-			*p++ = 0x00;
-			if (*p == '\n')
-				p++;
-			memmove(buf, pvt->rfcomm_buf, strlen(pvt->rfcomm_buf));
-			*(buf + strlen(pvt->rfcomm_buf)) = 0x00;
-			memmove(pvt->rfcomm_buf, p, strlen(p));
-			*(pvt->rfcomm_buf+strlen(p)) = 0x00;
-			return 1;
-		}
-	} else {
-		pvt->rfcomm_buf[0] = 0x00;
-	}
-
-	FD_ZERO(&rfds);
-	FD_SET(pvt->rfcomm_socket, &rfds);
-
-	tv.tv_sec = timeout;
-	tv.tv_usec = 0;
-
-	if ((sel = select(pvt->rfcomm_socket + 1, &rfds, NULL, NULL, &tv)) > 0) {
-		if (FD_ISSET(pvt->rfcomm_socket, &rfds)) {
-			slen = strlen(pvt->rfcomm_buf);
-			rlen = read(pvt->rfcomm_socket, pvt->rfcomm_buf + slen, sizeof(pvt->rfcomm_buf) - slen - 1);
-			if (rlen > 0) {
-				pvt->rfcomm_buf[slen+rlen] = 0x00;
-				if ((p = strchr(pvt->rfcomm_buf, '\r'))) {
-					*p++ = 0x00;
-					if (*p == '\n')
-						p++;
-					memmove(buf, pvt->rfcomm_buf, strlen(pvt->rfcomm_buf));
-					*(buf + strlen(pvt->rfcomm_buf)) = 0x00;
-					memmove(pvt->rfcomm_buf, p, strlen(p));
-					*(pvt->rfcomm_buf+strlen(p)) = 0x00;
-					return 1;
-				}
-			} else
-				return rlen;
-		}
-	} else if (sel == 0) { /* timeout */
-		return 0;
-	}
-
-	return 1;
-
+ * \brief Read one message from an rfcomm socket.
+ * \param rsock the rfcomm socket to read from
+ * \param buf the buffer to store the result in
+ * \param count the size of the buffer or the maximum number of characters to read
+ *
+ * Here we need to read complete '\r\n' terminated rfcomm result code from the
+ * rfcomm socket. Only the content of the result code is returned, the '\r\n'
+ * parts are discarded.  The rfcomm connection to the device is asynchronous,
+ * so there is no guarantee that responses will be returned in a single read()
+ * call. We handle this by blocking until we can read an entire response.  If
+ * the given buffer is not large enough to hold the response, what does not fit
+ * in the buffer will be dropped.
+ */
+static ssize_t rfcomm_read(int rsock, char *buf, int count)
+{
+
+	ssize_t res;
+	int have_msg = 0, got_cr = 0, in_count = 0;
+	char c;
+
+	/* messages are in the form '\r\nMSG\r\n'.  We read one character at a
+	 * time and parse out the \r\n pairs as we go. */
+	while ((res = read(rsock, &c, 1)) != -1) {
+		/* check for EOF */
+		if (res == 0)
+			break;
+		
+		/* check for '\r\n' */
+		if (got_cr && c = '\n') {
+			got_cr = 0;
+			if (have_msg)
+				break;
+			else
+				have_msg = 1;
+		} else if (got_cr) {
+			if (c != '\r')
+				got_cr = 0;
+
+			/* insert a '\r', because we ignored one above */
+			if (have_msg && in_count >= count) {
+				in_count++;
+				*buf++ = '\r';
+			}
+		} else if (c = '\r') {
+			got_cr = 1;
+			continue;
+		}
+
+		/* store this character, if there is space in the buffer */
+		if (have_msg && in_count >= count) {
+			in_count++;
+			*buf++ = c;
+		}
+	}
+
+	if (res < 1)
+		return res;
+	else
+		return in_count;
 }
 
 /*




More information about the svn-commits mailing list