[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