3 /// Mode class for serial / GPRS modem mode
7 #include "controller.h"
8 #include "protostructs.h"
13 namespace Barry
{ namespace Mode
{
15 //////////////////////////////////////////////////////////////////////////////
18 Serial::Serial( Controller
&con
,
19 DeviceDataCallback callback
,
20 void *callback_context
)
24 , m_callback(callback
)
25 , m_callback_context(callback_context
)
27 if( !m_con
.HasQueue() )
28 throw std::logic_error("A SocketRoutingQueue is required in the Controller class when using Mode::Serial.");
36 //////////////////////////////////////////////////////////////////////////////
37 // protected API / static functions
39 void Serial::DataCallback(void *context
, Data
*data
)
41 ddout("Serial::DataCallback called");
43 Serial
*ser
= (Serial
*) context
;
45 if( data
->GetSize() <= 4 )
46 return; // nothing to do
48 // call callback if available
49 if( ser
->m_callback
) {
50 (*ser
->m_callback
)(ser
->m_callback_context
,
55 // // append data to readCache
60 void Serial::CtrlCallback(void *context
, Data
*data
)
62 // Serial *ser = (Serial*) context;
64 // just dump to stdout, and do nothing
65 ddout("CtrlCallback received:\n" << *data
);
68 //////////////////////////////////////////////////////////////////////////////
71 void Serial::Open(const char *password
)
85 m_ModeSocket
= m_con
.SelectMode(Controller::UsbSerData
);
86 m_data
= m_con
.m_zero
.Open(m_ModeSocket
, password
);
88 m_CtrlSocket
= m_con
.SelectMode(Controller::UsbSerCtrl
);
89 m_ctrl
= m_con
.m_zero
.Open(m_CtrlSocket
, password
);
91 // register callback for incoming data, for speed
92 m_data
->RegisterInterest(DataCallback
, this);
93 m_ctrl
->RegisterInterest(CtrlCallback
, this);
95 const unsigned char start
[] =
96 { 0, 0, 0x0a, 0, 0x01, 0x01, 0xc2, 0x00, 0x40, 0x00 };
97 Data
block(start
, sizeof(start
));
102 // FIXME - if this behaviour is truly common between modes, create
103 // a common base class for this.
104 void Serial::RetryPassword(const char *password)
106 if( m_data.get() || m_ctrl.get() )
107 throw std::logic_error("Socket already open in Serial::RetryPassword");
109 m_data = m_con.m_zero.OpenDBSocket(m_ModeSocket, password);
110 m_ctrl = m_con.m_zero.OpenDBSocket(m_CtrlSocket, password);
112 // register callback for incoming data, for speed
113 m_data->RegisterInterest(DataCallback, this);
118 // can be called from separate thread
119 void Serial::SerialRead(Data &data, int timeout)
121 m_socket.Receive(data, timeout);
125 void Serial::Write(const Data
&data
, int timeout
)
127 if( data
.GetSize() <= 0 )
128 return; // nothing to do
131 throw std::logic_error("Must call Open() before Write() in Mode::Serial");
133 // filter data for PPP, and prepend 4 bytes
134 Data
&filtered
= m_filter
.Write(data
, 4);
136 // setup header (only size needed, as socket will be set by socket class)
137 unsigned char *buf
= filtered
.GetBuffer();
138 MAKE_PACKETPTR_BUF(spack
, buf
);
139 spack
->size
= htobs(filtered
.GetSize());
141 // send via appropriate socket
142 m_data
->Send(filtered
, timeout
);
145 }} // namespace Barry::Mode