3 /// Mode class for serial / GPRS modem mode
7 #include "controller.h"
8 #include "protostructs.h"
12 namespace Barry
{ namespace Mode
{
14 //////////////////////////////////////////////////////////////////////////////
17 Serial::Serial( Controller
&con
,
18 DeviceDataCallback callback
,
19 void *callback_context
)
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.");
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
,
52 // // append data to readCache
57 //////////////////////////////////////////////////////////////////////////////
60 void Serial::Open(const char *password
)
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
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
);
122 m_writeCache
.ReleaseBuffer(size
);
123 m_data
->Send(m_writeCache
);
125 ///////////////////////////////////////////////////////////////////////
126 // unsigned char buf[0x400];
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.
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)
142 // BufferPullHead(&serdata->data, 1);
147 // if (BufferLen(&serdata->data) > 2)
149 // if ((BufferLen(&serdata->data) + 4) % 16 == 0)
151 // BufferAdd(&serdata->data, (unsigned char *)"\0", 1);
153 // send_packet(serdata, BufferData(&serdata->data), BufferLen(&serdata->data));
154 // BufferEmpty(&serdata->data);
155 // BufferAdd(&serdata->data, (unsigned char *)"\176", 1);
157 // if (BufferLen(&serdata->data) == 2)
159 // BufferPullTail(&serdata->data, 1);
169 // if (BufferData(&serdata->data)[0] == 0x7e &&
170 // memcmp(&BufferData(&serdata->data)[1], "AT", 2) == 0)
172 // BufferPullHead(&serdata->data, 1);
174 // if (BufferData(&serdata->data)[0] != 0x7e)
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);
184 }} // namespace Barry::Mode