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