m_raw_channel.h

Go to the documentation of this file.
00001 ///
00002 /// \file       m_raw_channel.h
00003 ///             Mode class for a raw channel
00004 ///
00005 
00006 /*
00007     Copyright (C) 2005-2011, Net Direct Inc. (http://www.netdirect.ca/)
00008     Portions Copyright (C) 2010 RealVNC Ltd.
00009 
00010     This program is free software; you can redistribute it and/or modify
00011     it under the terms of the GNU General Public License as published by
00012     the Free Software Foundation; either version 2 of the License, or
00013     (at your option) any later version.
00014 
00015     This program is distributed in the hope that it will be useful,
00016     but WITHOUT ANY WARRANTY; without even the implied warranty of
00017     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00018 
00019     See the GNU General Public License in the COPYING file at the
00020     root directory of this project for more details.
00021 */
00022 
00023 #ifndef __BARRY_M_RAW_CHANNEL_H__
00024 #define __BARRY_M_RAW_CHANNEL_H__
00025 
00026 #include "dll.h"
00027 #include "m_mode_base.h"
00028 #include "socket.h"
00029 #include "data.h"
00030 
00031 #include <string>
00032 #include <pthread.h>
00033 
00034 namespace Barry {
00035 
00036 class semaphore;
00037 
00038 namespace Mode {
00039 
00040 // Forward declaration of internal classes
00041 class RawChannelSocketHandler;
00042 class RawChannelZeroSocketHandler;
00043 
00044 // Callback from the raw channel.
00045 
00046 class BXEXPORT RawChannelDataCallback
00047 {
00048 public:
00049         virtual ~RawChannelDataCallback() {}
00050 
00051         // Called when data has been received on the channel
00052         virtual void DataReceived(Data &data) = 0;
00053         // Called when the channel has an error
00054         virtual void ChannelError(std::string msg) = 0;
00055         // Called when the channel has been asked to close by the other side
00056         virtual void ChannelClose() = 0;
00057 };
00058 
00059 //
00060 // Raw channel class
00061 //
00062 /// The main class for creating a raw channel session.
00063 ///
00064 /// To use this class, use the following steps:
00065 ///
00066 /// - Implement RawChannelDataCallback
00067 ///     - Create a Controller object (see Controller class for more details)
00068 ///     - Create this Mode::RawChannel object, passing in the Controller
00069 ///             object during construction
00070 ///     - Call Open() to open the channel and finish constructing.
00071 ///     - Call GetData() to fetch data
00072 ///     - Call SendData() to send data
00073 ///
00074 class BXEXPORT RawChannel : public Mode
00075 {
00076         friend class RawChannelSocketHandler;
00077         friend class RawChannelZeroSocketHandler;
00078 
00079         // Mutex for signalling between read and write threads
00080         pthread_mutex_t m_mutex;
00081         bool m_mutex_valid;
00082         // Condvar for signalling between read and write threads
00083         pthread_cond_t m_cv;
00084         bool m_cv_valid;
00085 
00086         semaphore *m_semaphore;
00087         RawChannelDataCallback *m_callback;
00088         unsigned char *m_send_buffer;
00089         bool m_zero_registered;
00090         std::string *m_pending_error;
00091 
00092         Data m_receive_data;
00093 
00094 protected:
00095         void CheckQueueAvailable();
00096         void InitBuffer();
00097         void InitSemaphore();
00098         void SetPendingError(const char *msg);
00099         void UnregisterZeroSocketInterest();
00100 
00101         // Used to validate a packet is a valid channel data packet
00102         void ValidateDataPacket(Data &data);
00103 
00104         // Not intended for use by users of this class.
00105         // Used for handling zero-socket packets.
00106         void HandleReceivedZeroPacket(Data &data);
00107 
00108         // Not intended for use by users of this class.
00109         // Instead data received will come in via the
00110         // RawChannelDataCallback::DataReceived callback
00111         // or using Receive().
00112         void HandleReceivedData(Data &data);
00113 
00114         // Not intended for use by users of this class.
00115         void HandleError(Barry::Error &data);
00116 
00117         // Not intended for use by users of this class.
00118         // This method is called by the internals of
00119         // Barry when setting up a connection.
00120         void OnOpen();
00121 public:
00122         // Creates a raw channel in non-callback mode.
00123         // This requires all data to be sent and received
00124         // via calls to Send and Receive.
00125         // As there are no notifications of data being
00126         // available to send or receive, this is only recommended
00127         // for use with synchronous protocols over the channel.
00128         //
00129         // Will throw a Barry::Error if the provided controller
00130         // doesn't have a routing queue set.
00131         RawChannel(Controller &con);
00132 
00133         // Creates a raw channel in callback mode.
00134         // This requires all data to be sent via calls to Send, but
00135         // the Receive method must never be called.
00136         // Instead the DataReceive
00137         //
00138         // Will throw a Barry::Error if the provided controller
00139         // doesn't have a routing queue set.
00140         RawChannel(Controller &con, RawChannelDataCallback &callback);
00141 
00142         virtual ~RawChannel();
00143 
00144         //////////////////////////////////
00145         // Raw channel mode specific methods
00146 
00147         // Send some data on the raw channel.
00148         // Will throw a Barry::Error if data is longer than
00149         // MaximumPacketContentsSize or a Usb::Error if there
00150         // is an underlying USB error.
00151         //
00152         // If using a raw channel in callback mode then care must be
00153         // taken to ensure another thread is running during any calls
00154         // to Send. See the comment in the constructor of RawChannel
00155         // for further information.
00156         void Send(Data &data, int timeout = -1);
00157 
00158         // Receive some data on the raw channel.
00159         // Will throw a Barry::Error if a disconnect occurs
00160         // or a Usb::Error if there is an underlying USB error
00161         // or a Usb::Timeout if the receive times out.
00162         //
00163         // Only valid to call this if the raw channel was created in non-callback
00164         // mode. If this is called when the raw channel was created with a
00165         // callback then a std::logic_error will be thrown.
00166         void Receive(Data &data, int timeout = -1);
00167 
00168         // Returns the maximum quantity of data which
00169         // can be sent
00170         size_t MaximumSendSize();
00171 };
00172 
00173 }} // namespace Barry::Mode
00174 
00175 #endif
00176