* [PATCH 1/2] hdlc: allow for scanning and escaping
2010-04-17 2:31 [PATCH 0/2] hdlc fixes Kristen Carlson Accardi
@ 2010-04-17 2:31 ` Kristen Carlson Accardi
2010-04-17 2:31 ` [PATCH 2/2] hdlc: handle wrapped buffers Kristen Carlson Accardi
2010-04-17 18:13 ` [PATCH 0/2] hdlc fixes Kristen Carlson Accardi
2 siblings, 0 replies; 4+ messages in thread
From: Kristen Carlson Accardi @ 2010-04-17 2:31 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 4536 bytes --]
PPP needs to inspect the packet protocol to see if a character
should be escaped. Additionally, it needs to be able to compare
against recv and xmit accm.
---
gatchat/gathdlc.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++----
gatchat/gathdlc.h | 12 ++++++++++
2 files changed, 67 insertions(+), 5 deletions(-)
diff --git a/gatchat/gathdlc.c b/gatchat/gathdlc.c
index 19df9c6..c5c02cf 100644
--- a/gatchat/gathdlc.c
+++ b/gatchat/gathdlc.c
@@ -47,6 +47,12 @@ struct _GAtHDLC {
gpointer receive_data;
GAtDebugFunc debugf;
gpointer debug_data;
+ GAtHDLCScanFunc scan_func;
+ gpointer scan_data;
+ GAtHDLCSendEscapeFunc send_escape_func;
+ gpointer send_escape_data;
+ GAtHDLCRecvEscapeFunc recv_escape_func;
+ gpointer recv_escape_data;
};
static void new_bytes(GAtHDLC *hdlc)
@@ -71,6 +77,13 @@ static void new_bytes(GAtHDLC *hdlc)
continue;
}
+ if (hdlc->recv_escape_func &&
+ hdlc->recv_escape_func(hdlc->recv_escape_data,
+ buf[pos])) {
+ pos++;
+ continue;
+ }
+
if (buf[pos] == 0x7d) {
if (pos + 2 > len)
break;
@@ -249,6 +262,35 @@ void g_at_hdlc_set_receive(GAtHDLC *hdlc, GAtReceiveFunc func,
hdlc->receive_data = user_data;
}
+void g_at_hdlc_set_scan(GAtHDLC *hdlc, GAtHDLCScanFunc func, gpointer user_data)
+{
+ if (!hdlc)
+ return;
+
+ hdlc->scan_func = func;
+ hdlc->scan_data = user_data;
+}
+
+void g_at_hdlc_set_send_escape(GAtHDLC *hdlc, GAtHDLCSendEscapeFunc func,
+ gpointer user_data)
+{
+ if (!hdlc)
+ return;
+
+ hdlc->send_escape_func = func;
+ hdlc->send_escape_data = user_data;
+}
+
+void g_at_hdlc_set_recv_escape(GAtHDLC *hdlc, GAtHDLCRecvEscapeFunc func,
+ gpointer user_data)
+{
+ if (!hdlc)
+ return;
+
+ hdlc->recv_escape_func = func;
+ hdlc->recv_escape_data = user_data;
+}
+
static gboolean can_write_data(GIOChannel *channel, GIOCondition cond,
gpointer user_data)
{
@@ -302,11 +344,15 @@ static void wakeup_write(GAtHDLC *hdlc)
can_write_data, hdlc, write_watch_destroy);
}
-static inline void hdlc_put(GAtHDLC *hdlc, guint8 *buf, gsize *pos, guint8 c)
+static inline void hdlc_put(GAtHDLC *hdlc, guint8 *buf, gsize *pos, guint8 c,
+ gboolean scan_result)
{
gsize i = *pos;
- if (c == 0x7e || c == 0x7d) {
+ if ((hdlc->send_escape_func &&
+ hdlc->send_escape_func(hdlc->send_escape_data,
+ c, scan_result))
+ || c == 0x7e || c == 0x7d) {
buf[i++] = 0x7d;
buf[i++] = c ^ 0x20;
} else
@@ -321,6 +367,10 @@ gboolean g_at_hdlc_send(GAtHDLC *hdlc, const unsigned char *data, gsize size)
unsigned int space, i = 0;
guint16 fcs = 0xffff;
gsize pos;
+ gboolean scan_result = FALSE;
+
+ if (hdlc->scan_func)
+ scan_result = hdlc->scan_func(hdlc->scan_data, data);
do {
space = ring_buffer_avail_no_wrap(hdlc->write_buffer);
@@ -332,12 +382,12 @@ gboolean g_at_hdlc_send(GAtHDLC *hdlc, const unsigned char *data, gsize size)
while (size--) {
fcs = crc_ccitt_byte(fcs, data[i]);
- hdlc_put(hdlc, buf, &pos, data[i++]);
+ hdlc_put(hdlc, buf, &pos, data[i++], scan_result);
}
fcs ^= 0xffff;
- hdlc_put(hdlc, buf, &pos, fcs & 0xff);
- hdlc_put(hdlc, buf, &pos, fcs >> 8);
+ hdlc_put(hdlc, buf, &pos, fcs & 0xff, scan_result);
+ hdlc_put(hdlc, buf, &pos, fcs >> 8, scan_result);
buf[pos++] = 0x7e;
diff --git a/gatchat/gathdlc.h b/gatchat/gathdlc.h
index a295f08..f1adeb7 100644
--- a/gatchat/gathdlc.h
+++ b/gatchat/gathdlc.h
@@ -32,6 +32,12 @@ struct _GAtHDLC;
typedef struct _GAtHDLC GAtHDLC;
+typedef gboolean (*GAtHDLCSendEscapeFunc)(gpointer user_data, guint8 c,
+ gboolean scan_result);
+typedef gboolean (*GAtHDLCRecvEscapeFunc)(gpointer user_data, guint8 c);
+
+typedef gboolean (*GAtHDLCScanFunc)(gpointer user_data,
+ const unsigned char *data);
GAtHDLC *g_at_hdlc_new(GIOChannel *channel);
GAtHDLC *g_at_hdlc_ref(GAtHDLC *hdlc);
@@ -43,6 +49,12 @@ void g_at_hdlc_set_receive(GAtHDLC *hdlc, GAtReceiveFunc func,
gpointer user_data);
gboolean g_at_hdlc_send(GAtHDLC *hdlc, const unsigned char *data, gsize size);
+void g_at_hdlc_set_scan(GAtHDLC *hdlc, GAtHDLCScanFunc func,
+ gpointer user_data);
+void g_at_hdlc_set_send_escape(GAtHDLC *hdlc, GAtHDLCSendEscapeFunc func,
+ gpointer user_data);
+void g_at_hdlc_set_recv_escape(GAtHDLC *hdlc, GAtHDLCRecvEscapeFunc func,
+ gpointer user_data);
#ifdef __cplusplus
}
#endif
--
1.6.6.1
^ permalink raw reply related [flat|nested] 4+ messages in thread* [PATCH 2/2] hdlc: handle wrapped buffers
2010-04-17 2:31 [PATCH 0/2] hdlc fixes Kristen Carlson Accardi
2010-04-17 2:31 ` [PATCH 1/2] hdlc: allow for scanning and escaping Kristen Carlson Accardi
@ 2010-04-17 2:31 ` Kristen Carlson Accardi
2010-04-17 18:13 ` [PATCH 0/2] hdlc fixes Kristen Carlson Accardi
2 siblings, 0 replies; 4+ messages in thread
From: Kristen Carlson Accardi @ 2010-04-17 2:31 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 3997 bytes --]
---
gatchat/gathdlc.c | 75 ++++++++++++++++++++++++++++------------------------
1 files changed, 40 insertions(+), 35 deletions(-)
diff --git a/gatchat/gathdlc.c b/gatchat/gathdlc.c
index c5c02cf..13e15a1 100644
--- a/gatchat/gathdlc.c
+++ b/gatchat/gathdlc.c
@@ -59,11 +59,12 @@ static void new_bytes(GAtHDLC *hdlc)
{
unsigned int len = ring_buffer_len(hdlc->read_buffer);
unsigned char *buf = ring_buffer_read_ptr(hdlc->read_buffer, 0);
+ unsigned int wrap = ring_buffer_len_no_wrap(hdlc->read_buffer);
unsigned char val;
unsigned int pos = 0;
while (pos < len) {
- if (buf[pos] == 0x7e) {
+ if (*buf == 0x7e) {
if (hdlc->receive_func && hdlc->decode_offset > 2 &&
hdlc->decode_fcs == 0xf0b8) {
hdlc->receive_func(hdlc->decode_buffer,
@@ -74,29 +75,44 @@ static void new_bytes(GAtHDLC *hdlc)
hdlc->decode_fcs = 0xffff;
hdlc->decode_offset = 0;
pos++;
+ buf++;
+ if (pos == wrap)
+ buf = ring_buffer_read_ptr(hdlc->read_buffer,
+ pos);
continue;
}
if (hdlc->recv_escape_func &&
hdlc->recv_escape_func(hdlc->recv_escape_data,
- buf[pos])) {
+ *buf)) {
pos++;
+ buf++;
+ if (pos == wrap)
+ buf = ring_buffer_read_ptr(hdlc->read_buffer,
+ pos);
continue;
}
- if (buf[pos] == 0x7d) {
+ if (*buf == 0x7d) {
if (pos + 2 > len)
break;
pos++;
- val = buf[pos] ^ 0x20;
+ buf++;
+ if (pos == wrap)
+ buf = ring_buffer_read_ptr(hdlc->read_buffer,
+ pos);
+ val = *buf ^ 0x20;
} else
- val = buf[pos];
+ val = *buf;
hdlc->decode_buffer[hdlc->decode_offset] = val;
hdlc->decode_fcs = crc_ccitt_byte(hdlc->decode_fcs, val);
hdlc->decode_offset++;
pos++;
+ buf++;
+ if (pos == wrap)
+ buf = ring_buffer_read_ptr(hdlc->read_buffer, pos);
}
ring_buffer_drain(hdlc->read_buffer, pos);
@@ -344,55 +360,44 @@ static void wakeup_write(GAtHDLC *hdlc)
can_write_data, hdlc, write_watch_destroy);
}
-static inline void hdlc_put(GAtHDLC *hdlc, guint8 *buf, gsize *pos, guint8 c,
- gboolean scan_result)
+static inline void hdlc_buffer_put_char(struct ring_buffer *buffer,
+ const char val)
{
- gsize i = *pos;
+ ring_buffer_write(buffer, &val, 1);
+}
+static inline void hdlc_put(GAtHDLC *hdlc, guint8 c, gboolean scan_result)
+{
if ((hdlc->send_escape_func &&
hdlc->send_escape_func(hdlc->send_escape_data,
c, scan_result))
|| c == 0x7e || c == 0x7d) {
- buf[i++] = 0x7d;
- buf[i++] = c ^ 0x20;
+ hdlc_buffer_put_char(hdlc->write_buffer, 0x7d);
+ hdlc_buffer_put_char(hdlc->write_buffer, c ^ 0x20);
} else
- buf[i++] = c;
-
- *pos = i;
+ hdlc_buffer_put_char(hdlc->write_buffer, c);
}
gboolean g_at_hdlc_send(GAtHDLC *hdlc, const unsigned char *data, gsize size)
{
- unsigned char *buf;
- unsigned int space, i = 0;
guint16 fcs = 0xffff;
- gsize pos;
gboolean scan_result = FALSE;
+ unsigned int i = 0;
if (hdlc->scan_func)
scan_result = hdlc->scan_func(hdlc->scan_data, data);
- do {
- space = ring_buffer_avail_no_wrap(hdlc->write_buffer);
- if (space == 0)
- break;
+ hdlc_buffer_put_char(hdlc->write_buffer, 0x7e);
- buf = ring_buffer_write_ptr(hdlc->write_buffer);
- pos = 0;
-
- while (size--) {
- fcs = crc_ccitt_byte(fcs, data[i]);
- hdlc_put(hdlc, buf, &pos, data[i++], scan_result);
- }
-
- fcs ^= 0xffff;
- hdlc_put(hdlc, buf, &pos, fcs & 0xff, scan_result);
- hdlc_put(hdlc, buf, &pos, fcs >> 8, scan_result);
-
- buf[pos++] = 0x7e;
+ while (size--) {
+ fcs = crc_ccitt_byte(fcs, data[i]);
+ hdlc_put(hdlc, data[i++], scan_result);
+ }
- ring_buffer_write_advance(hdlc->write_buffer, pos);
- } while (0);
+ fcs ^= 0xffff;
+ hdlc_put(hdlc, fcs & 0xff, scan_result);
+ hdlc_put(hdlc, fcs >> 8, scan_result);
+ hdlc_buffer_put_char(hdlc->write_buffer, 0x7e);
wakeup_write(hdlc);
--
1.6.6.1
^ permalink raw reply related [flat|nested] 4+ messages in thread