3 /// Mode class for serial / GPRS modem mode
7 Copyright (C) 2008-2010, Net Direct Inc. (http://www.netdirect.ca/)
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18 See the GNU General Public License in the COPYING file at the
19 root directory of this project for more details.
23 #include "controller.h"
24 #include "protostructs.h"
29 namespace Barry
{ namespace Mode
{
31 //////////////////////////////////////////////////////////////////////////////
34 Serial::Serial( Controller
&con
,
35 DeviceDataCallback callback
,
36 void *callback_context
)
40 , m_callback(callback
)
41 , m_callback_context(callback_context
)
43 if( !m_con
.HasQueue() )
44 throw std::logic_error("A SocketRoutingQueue is required in the Controller class when using Mode::Serial.");
52 //////////////////////////////////////////////////////////////////////////////
53 // protected API / static functions
55 void Serial::DataCallback(Serial
&ser
, Data
*data
)
57 ddout("Serial::DataCallback called");
59 if( data
->GetSize() <= 4 )
60 return; // nothing to do
62 // call callback if available
63 if( ser
.m_callback
) {
64 (*ser
.m_callback
)(ser
.m_callback_context
,
69 // // append data to readCache
74 void Serial::CtrlCallback(Serial
&ser
, Data
*data
)
76 // just dump to stdout, and do nothing
77 ddout("CtrlCallback received:\n" << *data
);
80 //////////////////////////////////////////////////////////////////////////////
83 void Serial::Open(const char *password
)
97 m_ModeSocket
= m_con
.SelectMode(Controller::UsbSerData
);
98 m_data
= m_con
.m_zero
.Open(m_ModeSocket
, password
);
100 m_CtrlSocket
= m_con
.SelectMode(Controller::UsbSerCtrl
);
101 m_ctrl
= m_con
.m_zero
.Open(m_CtrlSocket
, password
);
103 // register callback for incoming data, for speed
104 SocketRoutingQueue::SocketDataHandlerPtr data_callback
105 (new SocketRoutingQueue::SimpleSocketDataHandler
<Serial
>(*this, DataCallback
));
106 m_data
->RegisterInterest(data_callback
);
107 SocketRoutingQueue::SocketDataHandlerPtr ctrl_callback
108 (new SocketRoutingQueue::SimpleSocketDataHandler
<Serial
>(*this, CtrlCallback
));
109 m_ctrl
->RegisterInterest(ctrl_callback
);
111 const unsigned char start
[] =
112 { 0, 0, 0x0a, 0, 0x01, 0x01, 0xc2, 0x00, 0x40, 0x00 };
113 Data
block(start
, sizeof(start
));
119 ddout("Serial:: Closing connection.");
123 // FIXME - if this behaviour is truly common between modes, create
124 // a common base class for this.
125 void Serial::RetryPassword(const char *password)
127 if( m_data.get() || m_ctrl.get() )
128 throw std::logic_error("Socket already open in Serial::RetryPassword");
130 m_data = m_con.m_zero.OpenDBSocket(m_ModeSocket, password);
131 m_ctrl = m_con.m_zero.OpenDBSocket(m_CtrlSocket, password);
133 // register callback for incoming data, for speed
134 m_data->RegisterInterest(DataCallback, this);
139 // can be called from separate thread
140 void Serial::SerialRead(Data &data, int timeout)
142 m_socket.Receive(data, timeout);
146 void Serial::Write(const Data
&data
, int timeout
)
148 if( data
.GetSize() <= 0 )
149 return; // nothing to do
152 throw std::logic_error("Must call Open() before Write() in Mode::Serial");
154 // filter data for PPP, and prepend 4 bytes
155 Data
&filtered
= m_filter
.Write(data
, 4);
157 // setup header (only size needed, as socket will be set by socket class)
158 unsigned char *buf
= filtered
.GetBuffer();
159 MAKE_PACKETPTR_BUF(spack
, buf
);
160 spack
->size
= htobs(filtered
.GetSize());
162 // send via appropriate socket
163 m_data
->Send(filtered
, timeout
);
166 }} // namespace Barry::Mode