Tree-wide cleanup of trailing whitespace
[barry.git] / src / m_serial.cc
blobf1cc61169d2b3122d18b32926d9e0f0916fc38d4
1 ///
2 /// \file m_serial.cc
3 /// Mode class for serial / GPRS modem mode
4 ///
6 /*
7 Copyright (C) 2008-2009, 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(void *context, Data *data)
57 ddout("Serial::DataCallback called");
59 Serial *ser = (Serial*) context;
61 if( data->GetSize() <= 4 )
62 return; // nothing to do
64 // call callback if available
65 if( ser->m_callback ) {
66 (*ser->m_callback)(ser->m_callback_context,
67 data->GetData() + 4,
68 data->GetSize() - 4);
70 // else {
71 // // append data to readCache
72 // FIXME;
73 // }
76 void Serial::CtrlCallback(void *context, Data *data)
78 // Serial *ser = (Serial*) context;
80 // just dump to stdout, and do nothing
81 ddout("CtrlCallback received:\n" << *data);
84 //////////////////////////////////////////////////////////////////////////////
85 // public API
87 void Serial::Open(const char *password)
89 if( m_ModeSocket ) {
90 m_data->Close();
91 m_data.reset();
92 m_ModeSocket = 0;
95 if( m_CtrlSocket ) {
96 m_ctrl->Close();
97 m_ctrl.reset();
98 m_CtrlSocket = 0;
101 m_ModeSocket = m_con.SelectMode(Controller::UsbSerData);
102 m_data = m_con.m_zero.Open(m_ModeSocket, password);
104 m_CtrlSocket = m_con.SelectMode(Controller::UsbSerCtrl);
105 m_ctrl = m_con.m_zero.Open(m_CtrlSocket, password);
107 // register callback for incoming data, for speed
108 m_data->RegisterInterest(DataCallback, this);
109 m_ctrl->RegisterInterest(CtrlCallback, this);
111 const unsigned char start[] =
112 { 0, 0, 0x0a, 0, 0x01, 0x01, 0xc2, 0x00, 0x40, 0x00 };
113 Data block(start, sizeof(start));
114 m_ctrl->Send(block);
117 void Serial::Close()
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
151 if( !m_data.get() )
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