summaryrefslogtreecommitdiffstats
path: root/gatchat/gathdlc.c
diff options
context:
space:
mode:
authorDenis Kenzior <denkenz@gmail.com>2010-04-28 17:06:03 -0500
committerDenis Kenzior <denkenz@gmail.com>2010-04-28 17:27:36 -0500
commit3b98ed067a1d4c4916d928f6e08e7907cee462ed (patch)
tree1f48807d8fc29609e729581a162dfe9f29ac7706 /gatchat/gathdlc.c
parentd27121611285819f9aeeafe860cf01e2f0f6c4cd (diff)
downloadofono-3b98ed067a1d4c4916d928f6e08e7907cee462ed.tar.bz2
gathdlc: Port GAtHDLC to use GAtIO
Diffstat (limited to 'gatchat/gathdlc.c')
-rw-r--r--gatchat/gathdlc.c153
1 files changed, 24 insertions, 129 deletions
diff --git a/gatchat/gathdlc.c b/gatchat/gathdlc.c
index 9520ff87..a5e8ed41 100644
--- a/gatchat/gathdlc.c
+++ b/gatchat/gathdlc.c
@@ -34,7 +34,7 @@
#include "crc-ccitt.h"
#include "ringbuffer.h"
-#include "gatutil.h"
+#include "gatio.h"
#include "gathdlc.h"
#define BUFFER_SIZE 2048
@@ -50,12 +50,9 @@
struct _GAtHDLC {
gint ref_count;
- GIOChannel *channel;
- guint read_watch;
+ GAtIO *io;
guint write_watch;
- struct ring_buffer *read_buffer;
struct ring_buffer *write_buffer;
- guint max_read_attempts;
unsigned char *decode_buffer;
guint decode_offset;
guint16 decode_fcs;
@@ -126,13 +123,16 @@ guint32 g_at_hdlc_get_recv_accm(GAtHDLC *hdlc)
return hdlc->recv_accm;
}
-static void new_bytes(GAtHDLC *hdlc)
+static void new_bytes(struct ring_buffer *rbuf, gpointer user_data)
{
- unsigned int len = ring_buffer_len(hdlc->read_buffer);
- unsigned int wrap = ring_buffer_len_no_wrap(hdlc->read_buffer);
- unsigned char *buf = ring_buffer_read_ptr(hdlc->read_buffer, 0);
+ GAtHDLC *hdlc = user_data;
+ unsigned int len = ring_buffer_len(rbuf);
+ unsigned int wrap = ring_buffer_len_no_wrap(rbuf);
+ unsigned char *buf = ring_buffer_read_ptr(rbuf, 0);
unsigned int pos = 0;
+ hdlc_record(hdlc->record_fd, TRUE, buf, wrap);
+
while (pos < len) {
if (hdlc->decode_escape == TRUE) {
unsigned char val = *buf ^ HDLC_TRANS;
@@ -162,69 +162,13 @@ static void new_bytes(GAtHDLC *hdlc)
buf++;
pos++;
- if (pos == wrap)
- buf = ring_buffer_read_ptr(hdlc->read_buffer, pos);
+ if (pos == wrap) {
+ buf = ring_buffer_read_ptr(rbuf, pos);
+ hdlc_record(hdlc->record_fd, TRUE, buf, len - wrap);
+ }
}
- ring_buffer_drain(hdlc->read_buffer, pos);
-}
-
-static gboolean received_data(GIOChannel *channel, GIOCondition cond,
- gpointer user_data)
-{
- GAtHDLC *hdlc = user_data;
- unsigned char *buf;
- GIOError err;
- gsize rbytes;
- gsize toread;
- gsize total_read = 0;
- guint read_count = 0;
-
- if (cond & G_IO_NVAL)
- return FALSE;
-
- /* Regardless of condition, try to read all the data available */
- do {
- toread = ring_buffer_avail_no_wrap(hdlc->read_buffer);
-
- if (toread == 0)
- break;
-
- rbytes = 0;
- buf = ring_buffer_write_ptr(hdlc->read_buffer, 0);
-
- err = g_io_channel_read(channel, (char *) buf, toread, &rbytes);
- hdlc_record(hdlc->record_fd, TRUE, buf, rbytes);
- g_at_util_debug_dump(TRUE, buf, rbytes,
- hdlc->debugf, hdlc->debug_data);
-
- read_count++;
-
- total_read += rbytes;
-
- if (rbytes > 0)
- ring_buffer_write_advance(hdlc->read_buffer, rbytes);
-
- } while (err == G_IO_ERROR_NONE && rbytes > 0 &&
- read_count < hdlc->max_read_attempts);
-
- if (total_read > 0)
- new_bytes(hdlc);
-
- if (cond & (G_IO_HUP | G_IO_ERR))
- return FALSE;
-
- if (read_count > 0 && rbytes == 0 && err != G_IO_ERROR_AGAIN)
- return FALSE;
-
- return TRUE;
-}
-
-static void read_watch_destroy(gpointer user_data)
-{
- GAtHDLC *hdlc = user_data;
-
- hdlc->read_watch = 0;
+ ring_buffer_drain(rbuf, pos);
}
GAtHDLC *g_at_hdlc_new(GIOChannel *channel)
@@ -243,15 +187,12 @@ GAtHDLC *g_at_hdlc_new(GIOChannel *channel)
hdlc->decode_fcs = HDLC_INITFCS;
hdlc->decode_offset = 0;
hdlc->decode_escape = FALSE;
- hdlc->max_read_attempts = 8;
hdlc->xmit_accm[0] = ~0U;
hdlc->xmit_accm[3] = 0x60000000; /* 0x7d, 0x7e */
hdlc->recv_accm = ~0U;
- hdlc->read_buffer = ring_buffer_new(BUFFER_SIZE);
- if (!hdlc->read_buffer)
- goto error;
+ hdlc->io = g_at_io_new(channel);
hdlc->write_buffer = ring_buffer_new(BUFFER_SIZE * 2);
if (!hdlc->write_buffer)
@@ -266,24 +207,15 @@ GAtHDLC *g_at_hdlc_new(GIOChannel *channel)
if (!hdlc->decode_buffer)
goto error;
- if (g_at_util_setup_io(channel, G_IO_FLAG_NONBLOCK) == FALSE)
- goto error;
-
- hdlc->channel = g_io_channel_ref(channel);
-
- g_io_channel_set_buffered(hdlc->channel, FALSE);
-
- hdlc->read_watch = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT,
- G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
- received_data, hdlc, read_watch_destroy);
+ g_at_io_set_read_handler(hdlc->io, new_bytes, hdlc);
hdlc->record_fd = -1;
return hdlc;
error:
- if (hdlc->read_buffer)
- ring_buffer_free(hdlc->read_buffer);
+ if (hdlc->io)
+ g_at_io_unref(hdlc->io);
if (hdlc->write_buffer)
ring_buffer_free(hdlc->write_buffer);
@@ -314,17 +246,14 @@ void g_at_hdlc_unref(GAtHDLC *hdlc)
if (g_atomic_int_dec_and_test(&hdlc->ref_count) == FALSE)
return;
- if (hdlc->read_watch > 0)
- g_source_remove(hdlc->read_watch);
-
if (hdlc->record_fd > fileno(stderr)) {
close(hdlc->record_fd);
hdlc->record_fd = -1;
}
- g_io_channel_unref(hdlc->channel);
+ g_at_io_unref(hdlc->io);
+ hdlc->io = NULL;
- ring_buffer_free(hdlc->read_buffer);
ring_buffer_free(hdlc->write_buffer);
g_free(hdlc->decode_buffer);
}
@@ -348,33 +277,18 @@ void g_at_hdlc_set_receive(GAtHDLC *hdlc, GAtReceiveFunc func,
hdlc->receive_data = user_data;
}
-static gboolean can_write_data(GIOChannel *channel, GIOCondition cond,
- gpointer user_data)
+static gboolean can_write_data(gpointer data)
{
- GAtHDLC *hdlc = user_data;
- GIOError err;
+ GAtHDLC *hdlc = data;
unsigned int len;
unsigned char *buf;
gsize bytes_written;
- if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
- return FALSE;
-
len = ring_buffer_len_no_wrap(hdlc->write_buffer);
buf = ring_buffer_read_ptr(hdlc->write_buffer, 0);
- err = g_io_channel_write(hdlc->channel, (const char *) buf,
- len, &bytes_written);
-
- if (err != G_IO_ERROR_NONE) {
- g_source_remove(hdlc->read_watch);
- return FALSE;
- }
-
+ bytes_written = g_at_io_write(hdlc->io, (gchar *) buf, len);
hdlc_record(hdlc->record_fd, FALSE, buf, bytes_written);
- g_at_util_debug_dump(FALSE, buf, bytes_written,
- hdlc->debugf, hdlc->debug_data);
-
ring_buffer_drain(hdlc->write_buffer, bytes_written);
if (ring_buffer_len(hdlc->write_buffer) > 0)
@@ -383,25 +297,6 @@ static gboolean can_write_data(GIOChannel *channel, GIOCondition cond,
return FALSE;
}
-static void write_watch_destroy(gpointer user_data)
-{
- GAtHDLC *hdlc = user_data;
-
- hdlc->write_watch = 0;
-}
-
-static void wakeup_write(GAtHDLC *hdlc)
-{
- GIOChannel *channel = hdlc->channel;
-
- if (hdlc->write_watch > 0)
- return;
-
- hdlc->write_watch = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT,
- G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
- can_write_data, hdlc, write_watch_destroy);
-}
-
void g_at_hdlc_set_xmit_accm(GAtHDLC *hdlc, guint32 accm)
{
if (hdlc == NULL)
@@ -494,7 +389,7 @@ gboolean g_at_hdlc_send(GAtHDLC *hdlc, const unsigned char *data, gsize size)
ring_buffer_write_advance(hdlc->write_buffer, pos);
- wakeup_write(hdlc);
+ g_at_io_set_write_handler(hdlc->io, can_write_data, hdlc);
return TRUE;
}