debian: updated Build-Depends
[barry.git] / src / m_serial.cc
blob8d5da36631d0fada735e69712a764dd239cb45ec
1 ///
2 /// \file m_serial.cc
3 /// Mode class for serial / GPRS modem mode
4 ///
6 /*
7 Copyright (C) 2008-2012, 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.
22 #include "m_serial.h"
23 #include "controller.h"
24 #include "protostructs.h"
25 #include "endian.h"
26 #include "debug.h"
27 #include <stdexcept>
29 namespace Barry { namespace Mode {
31 //////////////////////////////////////////////////////////////////////////////
32 // Mode::Serial class
34 Serial::Serial( Controller &con,
35 DeviceDataCallback callback,
36 void *callback_context)
37 : m_con(con)
38 , m_ModeSocket(0)
39 , m_CtrlSocket(0)
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.");
47 Serial::~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,
65 data->GetData() + 4,
66 data->GetSize() - 4);
68 // else {
69 // // append data to readCache
70 // FIXME;
71 // }
74 void Serial::CtrlCallback(Serial &ser, Data *data)
76 // just dump to stdout, and do nothing
77 ddout("CtrlCallback received:\n" << *data);
80 //////////////////////////////////////////////////////////////////////////////
81 // public API
83 void Serial::Open(const char *password)
85 if( m_ModeSocket ) {
86 m_data->Close();
87 m_data.reset();
88 m_ModeSocket = 0;
91 if( m_CtrlSocket ) {
92 m_ctrl->Close();
93 m_ctrl.reset();
94 m_CtrlSocket = 0;
97 m_ModeSocket = m_con.SelectMode(Controller::UsbSerData);
98 m_data = m_con.OpenSocket(m_ModeSocket, password);
100 m_CtrlSocket = m_con.SelectMode(Controller::UsbSerCtrl);
101 m_ctrl = m_con.OpenSocket(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->UnregisterInterest();
107 m_data->RegisterInterest(data_callback);
108 SocketRoutingQueue::SocketDataHandlerPtr ctrl_callback
109 (new SocketRoutingQueue::SimpleSocketDataHandler<Serial>(*this, CtrlCallback));
110 m_ctrl->UnregisterInterest();
111 m_ctrl->RegisterInterest(ctrl_callback);
113 const unsigned char start[] =
114 { 0, 0, 0x0a, 0, 0x01, 0x01, 0xc2, 0x00, 0x40, 0x00 };
115 Data block(start, sizeof(start));
116 m_ctrl->RawSend(block);
119 void Serial::Close()
121 ddout("Serial:: Closing connection.");
125 // FIXME - if this behaviour is truly common between modes, create
126 // a common base class for this.
127 void Serial::RetryPassword(const char *password)
129 if( m_data.get() || m_ctrl.get() )
130 throw std::logic_error("Socket already open in Serial::RetryPassword");
132 m_data = m_con.m_zero.OpenDBSocket(m_ModeSocket, password);
133 m_ctrl = m_con.m_zero.OpenDBSocket(m_CtrlSocket, password);
135 // register callback for incoming data, for speed
136 m_data->UnregisterInterest();
137 m_data->RegisterInterest(DataCallback, this);
142 // can be called from separate thread
143 void Serial::SerialRead(Data &data, int timeout)
145 m_socket.Receive(data, timeout);
149 void Serial::Write(const Data &data, int timeout)
151 if( data.GetSize() <= 0 )
152 return; // nothing to do
154 if( !m_data.get() )
155 throw std::logic_error("Must call Open() before Write() in Mode::Serial");
157 // filter data for PPP, and prepend 4 bytes
158 Data &filtered = m_filter.Write(data, 4);
160 // setup header (only size needed, as socket will be set by socket class)
161 unsigned char *buf = filtered.GetBuffer();
162 MAKE_PACKETPTR_BUF(spack, buf);
163 spack->size = htobs(filtered.GetSize());
165 // send via appropriate socket
166 m_data->RawSend(filtered, timeout);
169 }} // namespace Barry::Mode