# 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