m_serial.cc

Go to the documentation of this file.
00001 ///
00002 /// \file       m_serial.cc
00003 ///             Mode class for serial / GPRS modem mode
00004 ///
00005 
00006 /*
00007     Copyright (C) 2008-2010, Net Direct Inc. (http://www.netdirect.ca/)
00008 
00009     This program is free software; you can redistribute it and/or modify
00010     it under the terms of the GNU General Public License as published by
00011     the Free Software Foundation; either version 2 of the License, or
00012     (at your option) any later version.
00013 
00014     This program is distributed in the hope that it will be useful,
00015     but WITHOUT ANY WARRANTY; without even the implied warranty of
00016     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00017 
00018     See the GNU General Public License in the COPYING file at the
00019     root directory of this project for more details.
00020 */
00021 
00022 #include "m_serial.h"
00023 #include "controller.h"
00024 #include "protostructs.h"
00025 #include "endian.h"
00026 #include "debug.h"
00027 #include <stdexcept>
00028 
00029 namespace Barry { namespace Mode {
00030 
00031 //////////////////////////////////////////////////////////////////////////////
00032 // Mode::Serial class
00033 
00034 Serial::Serial( Controller &con,
00035                 DeviceDataCallback callback,
00036                 void *callback_context)
00037         : m_con(con)
00038         , m_ModeSocket(0)
00039         , m_CtrlSocket(0)
00040         , m_callback(callback)
00041         , m_callback_context(callback_context)
00042 {
00043         if( !m_con.HasQueue() )
00044                 throw std::logic_error("A SocketRoutingQueue is required in the Controller class when using Mode::Serial.");
00045 }
00046 
00047 Serial::~Serial()
00048 {
00049 }
00050 
00051 
00052 //////////////////////////////////////////////////////////////////////////////
00053 // protected API / static functions
00054 
00055 void Serial::DataCallback(void *context, Data *data)
00056 {
00057         ddout("Serial::DataCallback called");
00058 
00059         Serial *ser = (Serial*) context;
00060 
00061         if( data->GetSize() <= 4 )
00062                 return; // nothing to do
00063 
00064         // call callback if available
00065         if( ser->m_callback ) {
00066                 (*ser->m_callback)(ser->m_callback_context,
00067                         data->GetData() + 4,
00068                         data->GetSize() - 4);
00069         }
00070 //      else {
00071 //              // append data to readCache
00072 //              FIXME;
00073 //      }
00074 }
00075 
00076 void Serial::CtrlCallback(void *context, Data *data)
00077 {
00078 //      Serial *ser = (Serial*) context;
00079 
00080         // just dump to stdout, and do nothing
00081         ddout("CtrlCallback received:\n" << *data);
00082 }
00083 
00084 //////////////////////////////////////////////////////////////////////////////
00085 // public API
00086 
00087 void Serial::Open(const char *password)
00088 {
00089         if( m_ModeSocket ) {
00090                 m_data->Close();
00091                 m_data.reset();
00092                 m_ModeSocket = 0;
00093         }
00094 
00095         if( m_CtrlSocket ) {
00096                 m_ctrl->Close();
00097                 m_ctrl.reset();
00098                 m_CtrlSocket = 0;
00099         }
00100 
00101         m_ModeSocket = m_con.SelectMode(Controller::UsbSerData);
00102         m_data = m_con.m_zero.Open(m_ModeSocket, password);
00103 
00104         m_CtrlSocket = m_con.SelectMode(Controller::UsbSerCtrl);
00105         m_ctrl = m_con.m_zero.Open(m_CtrlSocket, password);
00106 
00107         // register callback for incoming data, for speed
00108         m_data->RegisterInterest(DataCallback, this);
00109         m_ctrl->RegisterInterest(CtrlCallback, this);
00110 
00111         const unsigned char start[] =
00112                 { 0, 0, 0x0a, 0, 0x01, 0x01, 0xc2, 0x00, 0x40, 0x00 };
00113         Data block(start, sizeof(start));
00114         m_ctrl->Send(block);
00115 }
00116 
00117 void Serial::Close()
00118 {
00119         ddout("Serial:: Closing connection.");
00120 }
00121 
00122 /*
00123 // FIXME - if this behaviour is truly common between modes, create
00124 // a common base class for this.
00125 void Serial::RetryPassword(const char *password)
00126 {
00127         if( m_data.get() || m_ctrl.get() )
00128                 throw std::logic_error("Socket already open in Serial::RetryPassword");
00129 
00130         m_data = m_con.m_zero.OpenDBSocket(m_ModeSocket, password);
00131         m_ctrl = m_con.m_zero.OpenDBSocket(m_CtrlSocket, password);
00132 
00133         // register callback for incoming data, for speed
00134         m_data->RegisterInterest(DataCallback, this);
00135 }
00136 */
00137 
00138 /*
00139 // can be called from separate thread
00140 void Serial::SerialRead(Data &data, int timeout)
00141 {
00142         m_socket.Receive(data, timeout);
00143 }
00144 */
00145 
00146 void Serial::Write(const Data &data, int timeout)
00147 {
00148         if( data.GetSize() <= 0 )
00149                 return; // nothing to do
00150 
00151         if( !m_data.get() )
00152                 throw std::logic_error("Must call Open() before Write() in Mode::Serial");
00153 
00154         // filter data for PPP, and prepend 4 bytes
00155         Data &filtered = m_filter.Write(data, 4);
00156 
00157         // setup header (only size needed, as socket will be set by socket class)
00158         unsigned char *buf = filtered.GetBuffer();
00159         MAKE_PACKETPTR_BUF(spack, buf);
00160         spack->size = htobs(filtered.GetSize());
00161 
00162         // send via appropriate socket
00163         m_data->Send(filtered, timeout);
00164 }
00165 
00166 }} // namespace Barry::Mode
00167 
Generated by  doxygen 1.6.2-20100208