hdlc fixes
cover hdlc fixes
Kristen Carlson Accardi (2):
hdlc: allow for scanning and escaping
hdlc: handle wrapped buffers
gatchat/gathdlc.c | 121 ++++++++++++++++++++++++++++++++++++++-------------- gatchat/gathdlc.h | 12 +++++ 2 files changed, 100 insertions(+), 33 deletions(-)
PATCH 1/2 hdlc: allow for scanning and escaping
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(-)
gatchat/gathdlc.c +55 -5
@@ -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 ;
gatchat/gathdlc.h +12 -0
@@ -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
Signature · 1 line
1.6.6.1
PATCH 2/2 hdlc: handle wrapped buffers
In reply to Kristen Carlson Accardi--- gatchat/gathdlc.c | 75 ++++++++++++++++++++++++++++------------------------ 1 files changed, 40 insertions(+), 35 deletions(-)
gatchat/gathdlc.c +40 -35
@@ -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);
Signature · 1 line
1.6.6.1
Quoted 8 lines · On Fri, 16 Apr 2010 19:31:01 -0700 Kristen Carlson Accardi…
Kristen Carlson Accardi (2):
hdlc: allow for scanning and escaping
hdlc: handle wrapped buffersgatchat/gathdlc.c | 121 ++++++++++++++++++++++++++++++++++++++-------------- gatchat/gathdlc.h | 12 +++++ 2 files changed, 100 insertions(+), 33 deletions(-)
Please disregard this series, I will resend with an additional patch.