Merged barry-b1-socket-arch-branch into MAIN.
[barry.git] / src / m_serial.cc
blob97efb2edabdeef6402637e47ff4a6cb02b2e11b0
1 ///
2 /// \file m_serial.cc
3 /// Mode class for serial / GPRS modem mode
4 ///
6 #include "m_serial.h"
7 #include "controller.h"
8 #include "protostructs.h"
9 #include "endian.h"
10 #include <stdexcept>
12 namespace Barry { namespace Mode {
14 //////////////////////////////////////////////////////////////////////////////
15 // Mode::Serial class
17 Serial::Serial( Controller &con,
18 DeviceDataCallback callback,
19 void *callback_context)
20 : m_con(con)
21 , m_ModeSocket(0)
22 , m_CtrlSocket(0)
23 , m_callback(callback)
24 , m_callback_context(callback_context)
26 if( !m_con.HasQueue() )
27 throw std::logic_error("A SocketRoutingQueue is required in the Controller class when using Mode::Serial.");
30 Serial::~Serial()
35 //////////////////////////////////////////////////////////////////////////////
36 // protected API / static functions
38 void Serial::DataCallback(void *context, Data *data)
40 Serial *ser = (Serial*) context;
42 if( data->GetSize() <= 4 )
43 return; // nothing to do
45 // call callback if available
46 if( ser->m_callback ) {
47 (*ser->m_callback)(ser->m_callback_context,
48 data->GetData() + 4,
49 data->GetSize() - 4);
51 // else {
52 // // append data to readCache
53 // FIXME;
54 // }
57 //////////////////////////////////////////////////////////////////////////////
58 // public API
60 void Serial::Open(const char *password)
62 if( m_ModeSocket ) {
63 m_data->Close();
64 m_data.reset();
65 m_ModeSocket = 0;
68 if( m_CtrlSocket ) {
69 m_ctrl->Close();
70 m_ctrl.reset();
71 m_CtrlSocket = 0;
74 m_ModeSocket = m_con.SelectMode(Controller::UsbSerData);
75 // m_CtrlSocket = m_con.SelectMode(Controller::UsbSerCtrl);
76 RetryPassword(password);
79 // FIXME - if this behaviour is truly common between modes, create
80 // a common base class for this.
81 void Serial::RetryPassword(const char *password)
83 if( m_data.get() || m_ctrl.get() )
84 throw std::logic_error("Socket already open in Serial::RetryPassword");
86 m_data = m_con.m_zero.Open(m_ModeSocket, password);
87 // m_ctrl = m_con.m_zero.Open(m_CtrlSocket, password);
89 // register callback for incoming data, for speed
90 m_data->RegisterInterest(DataCallback, this);
94 // can be called from separate thread
95 void Serial::SerialRead(Data &data, int timeout)
97 m_socket.Receive(data, timeout);
101 // based on Rick Scott's XmBlackBerry's serdata.c
102 void Serial::Write(const Data &data)
104 if( data.GetSize() <= 0 )
105 return; // nothing to do
107 if( !m_data.get() )
108 throw std::logic_error("Must call Open() before Write() in Mode::Serial");
110 // make room in write cache buffer for the 4 byte header
111 int size = data.GetSize() + 4;
112 unsigned char *buf = m_writeCache.GetBuffer(size);
113 MAKE_PACKETPTR_BUF(spack, buf);
115 // copy data over to cache packet
116 memcpy(&buf[4], data.GetData(), data.GetSize());
118 // setup header (only size needed, as socket will be set by socket class)
119 spack->size = htobs(size);
121 // release and send
122 m_writeCache.ReleaseBuffer(size);
123 m_data->Send(m_writeCache);
125 ///////////////////////////////////////////////////////////////////////
126 // unsigned char buf[0x400];
127 // int num_read;
128 // int i;
130 // //
131 // // This is pretty ugly, but I have to put the HDLC flags into
132 // // the packets. RIM seems to need flags around every frame, and
133 // // a flag _cannot_ be an end and a start flag.
134 // //
135 // for (i = 0; i < num_read; i++) {
136 // BufferAdd(&serdata->data, &buf[i], 1);
137 // if (BufferData(&serdata->data)[0] == 0x7e && buf[i] == 0x7e) {
138 // if (BufferLen(&serdata->data) > 1 &&
139 // BufferData(&serdata->data)[0] == 0x7e &&
140 // BufferData(&serdata->data)[1] == 0x7e)
141 // {
142 // BufferPullHead(&serdata->data, 1);
143 // }
144 // else
145 // {
146 // }
147 // if (BufferLen(&serdata->data) > 2)
148 // {
149 // if ((BufferLen(&serdata->data) + 4) % 16 == 0)
150 // {
151 // BufferAdd(&serdata->data, (unsigned char *)"\0", 1);
152 // }
153 // send_packet(serdata, BufferData(&serdata->data), BufferLen(&serdata->data));
154 // BufferEmpty(&serdata->data);
155 // BufferAdd(&serdata->data, (unsigned char *)"\176", 1);
156 // }
157 // if (BufferLen(&serdata->data) == 2)
158 // {
159 // BufferPullTail(&serdata->data, 1);
160 // }
161 // else
162 // {
163 // }
164 // }
165 // else
166 // {
167 // }
168 // }
169 // if (BufferData(&serdata->data)[0] == 0x7e &&
170 // memcmp(&BufferData(&serdata->data)[1], "AT", 2) == 0)
171 // {
172 // BufferPullHead(&serdata->data, 1);
173 // }
174 // if (BufferData(&serdata->data)[0] != 0x7e)
175 // {
176 // debug(9, "%s:%s(%d) - %i\n",
177 // __FILE__, __FUNCTION__, __LINE__,
178 // BufferLen(&serdata->data));
179 // send_packet(serdata, BufferData(&serdata->data), BufferLen(&serdata->data));
180 // BufferEmpty(&serdata->data);
181 // }
184 }} // namespace Barry::Mode