menu: added new Keywords tag to .desktop files
[barry.git] / src / m_serial.cc
blob303e62ecc1f00aad250e2a7f72f1df3d05ea3e0a
1 ///
2 /// \file m_serial.cc
3 /// Mode class for serial / GPRS modem mode
4 ///
6 /*
7 Copyright (C) 2008-2013, 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 "i18n.h"
23 #include "m_serial.h"
24 #include "controller.h"
25 #include "protostructs.h"
26 #include "endian.h"
27 #include "debug.h"
28 #include <stdexcept>
30 namespace Barry { namespace Mode {
32 //////////////////////////////////////////////////////////////////////////////
33 // Mode::Serial class
35 Serial::Serial( Controller &con,
36 DeviceDataCallback callback,
37 void *callback_context)
38 : m_con(con)
39 , m_ModeSocket(0)
40 , m_CtrlSocket(0)
41 , m_callback(callback)
42 , m_callback_context(callback_context)
44 if( !m_con.HasQueue() )
45 throw std::logic_error(_("A SocketRoutingQueue is required in the Controller class when using Mode::Serial."));
48 Serial::~Serial()
53 //////////////////////////////////////////////////////////////////////////////
54 // protected API / static functions
56 void Serial::DataCallback(Serial &ser, Data *data)
58 ddout("Serial::DataCallback called");
60 if( data->GetSize() <= 4 )
61 return; // nothing to do
63 // call callback if available
64 if( ser.m_callback ) {
65 (*ser.m_callback)(ser.m_callback_context,
66 data->GetData() + 4,
67 data->GetSize() - 4);
69 // else {
70 // // append data to readCache
71 // FIXME;
72 // }
75 void Serial::CtrlCallback(Serial &ser, Data *data)
77 // just dump to stdout, and do nothing
78 ddout("CtrlCallback received:\n" << *data);
81 //////////////////////////////////////////////////////////////////////////////
82 // public API
84 void Serial::Open(const char *password)
86 if( m_ModeSocket ) {
87 m_data->Close();
88 m_data.reset();
89 m_ModeSocket = 0;
92 if( m_CtrlSocket ) {
93 m_ctrl->Close();
94 m_ctrl.reset();
95 m_CtrlSocket = 0;
98 m_ModeSocket = m_con.SelectMode(Controller::UsbSerData);
99 m_data = m_con.OpenSocket(m_ModeSocket, password);
101 m_CtrlSocket = m_con.SelectMode(Controller::UsbSerCtrl);
102 m_ctrl = m_con.OpenSocket(m_CtrlSocket, password);
104 // register callback for incoming data, for speed
105 SocketRoutingQueue::SocketDataHandlerPtr data_callback
106 (new SocketRoutingQueue::SimpleSocketDataHandler<Serial>(*this, DataCallback));
107 m_data->UnregisterInterest();
108 m_data->RegisterInterest(data_callback);
109 SocketRoutingQueue::SocketDataHandlerPtr ctrl_callback
110 (new SocketRoutingQueue::SimpleSocketDataHandler<Serial>(*this, CtrlCallback));
111 m_ctrl->UnregisterInterest();
112 m_ctrl->RegisterInterest(ctrl_callback);
114 const unsigned char start[] =
115 { 0, 0, 0x0a, 0, 0x01, 0x01, 0xc2, 0x00, 0x40, 0x00 };
116 Data block(start, sizeof(start));
117 m_ctrl->RawSend(block);
120 void Serial::Close()
122 ddout("Serial:: Closing connection.");
126 // FIXME - if this behaviour is truly common between modes, create
127 // a common base class for this.
128 void Serial::RetryPassword(const char *password)
130 if( m_data.get() || m_ctrl.get() )
131 throw std::logic_error("Socket already open in Serial::RetryPassword");
133 m_data = m_con.m_zero.OpenDBSocket(m_ModeSocket, password);
134 m_ctrl = m_con.m_zero.OpenDBSocket(m_CtrlSocket, password);
136 // register callback for incoming data, for speed
137 m_data->UnregisterInterest();
138 m_data->RegisterInterest(DataCallback, this);
143 // can be called from separate thread
144 void Serial::SerialRead(Data &data, int timeout)
146 m_socket.Receive(data, timeout);
150 void Serial::Write(const Data &data, int timeout)
152 if( data.GetSize() <= 0 )
153 return; // nothing to do
155 if( !m_data.get() )
156 throw std::logic_error(_("Must call Open() before Write() in Mode::Serial"));
158 // filter data for PPP, and prepend 4 bytes
159 Data &filtered = m_filter.Write(data, 4);
161 // setup header (only size needed, as socket will be set by socket class)
162 unsigned char *buf = filtered.GetBuffer();
163 MAKE_PACKETPTR_BUF(spack, buf);
164 spack->size = htobs(filtered.GetSize());
166 // send via appropriate socket
167 m_data->RawSend(filtered, timeout);
170 }} // namespace Barry::Mode