udev: added 69-blackberry.rules for Fedora 12 systems
[barry.git] / src / pppfilter.cc
blob7a532fcc33636ded5fd5a64ac9bbcc320ef14d81
1 ///
2 /// \file pppfilter.cc
3 /// Data filter class, to morph PPP data into something that
4 /// the Blackberry / Rogers / ISP can handle.
5 /// This logic is based partly on XmBlackBerry's
6 /// gprs_protocol_fix.c program.
7 ///
9 /*
10 Copyright (C) 2008-2009, Net Direct Inc. (http://www.netdirect.ca/)
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
21 See the GNU General Public License in the COPYING file at the
22 root directory of this project for more details.
25 #include "pppfilter.h"
26 #include <string.h>
28 namespace Barry {
30 //////////////////////////////////////////////////////////////////////////////
31 // PppFilter class
33 PppFilter::PppFilter()
34 : m_ppp_mode(false)
35 , m_last(0x7e)
40 // Filter
42 /// Copy PPP data from src to dest, creating needed space in dest,
43 /// and inserting missing 0x7e characters wherever they are detected.
44 /// Starts writing at the start of the dest buffer + destoffset.
45 ///
46 void PppFilter::Filter(Data &dest, const Data &src, unsigned int destoffset)
48 const unsigned char *b = src.GetData(), *e = src.GetData() + src.GetSize();
49 size_t needed = src.GetSize() / 2 * 3 + 4 + destoffset; // worst case
50 unsigned char *buf = dest.GetBuffer(needed) + destoffset;
51 unsigned char *put = buf;
53 while( b != e ) {
54 // if last character was 0x7e, then next one must be,
55 // or else we insert it ourselves
56 if( m_last == 0x7e ) {
57 m_last = 0;
58 if( *b != 0x7e )
59 *put++ = 0x7e;
60 else
61 *put++ = *b++;
64 // copy all non-0x7e chars verbatim
65 while( b != e && *b != 0x7e ) {
66 *put++ = *b++;
69 if( b != e ) { // if b!=e then *b == 0x7e and must keep going
70 *put++ = *b++;
71 m_last = 0x7e;
75 dest.ReleaseBuffer(put - buf + destoffset);
79 // Write
81 /// If PPP mode has not been detected, just return the data buffer.
82 /// If in PPP mode, then filter data into internal write buffer,
83 /// inserting any missing 0x7e characters and return reference
84 /// to internal write buffer.
85 ///
86 const Data& PppFilter::Write(const Data &data)
88 if( data.GetSize() == 0 )
89 return data; // nothing to do
91 const unsigned char *b = data.GetData();
93 if( !m_ppp_mode ) {
94 if( *b == 0x7e ) {
95 m_ppp_mode = true;
96 // fall through
98 else {
99 // not in ppp mode yet, so just pass the buffer
100 // straight back to the caller
101 return data;
105 Filter(m_writeBuf, data, 0);
106 return m_writeBuf;
110 // Write (with prepend)
112 /// Same as Write(data), but makes sure that prepend bytes are available
113 /// at the beginning of the returned buffer.
114 /// If not in PPP mode, the extra bytes are still provided.
116 Data& PppFilter::Write(const Data &data, unsigned int prepend)
118 const unsigned char *b = data.GetData(), *e = data.GetData() + data.GetSize();
120 if( !m_ppp_mode ) {
121 if( b != e && *b == 0x7e ) {
122 m_ppp_mode = true;
123 // fall through
125 else {
126 // make space, copy, return
127 unsigned int size = data.GetSize() + prepend;
128 unsigned char *buf = m_writeBuf.GetBuffer(size);
129 memcpy(&buf[prepend], data.GetData(), data.GetSize());
130 m_writeBuf.ReleaseBuffer(size);
131 return m_writeBuf;
135 Filter(m_writeBuf, data, prepend);
136 return m_writeBuf;
139 } // namespace Barry