2 /// \file m_raw_channel.cc
3 /// Mode class for a raw channel
7 Copyright (C) 2005-2010, Net Direct Inc. (http://www.netdirect.ca/)
8 Portions Copyright (C) 2010 RealVNC Ltd.
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License in the COPYING file at the
20 root directory of this project for more details.
23 #include "m_raw_channel.h"
26 #include "protostructs.h"
31 #include "controller.h"
35 #include "protostructs.h"
39 #define RAW_HEADER_SIZE 4
41 namespace Barry
{ namespace Mode
{
43 static void HandleReceivedDataCallback(void* ctx
, Data
* data
) {
44 ((RawChannel
*)ctx
)->HandleReceivedData(*data
);
47 ///////////////////////////////////////////////////////////////////////////////
48 // RawChannel Mode class
50 RawChannel::RawChannel(Controller
&con
, RawChannelDataCallback
& callback
)
51 : Mode(con
, Controller::RawChannel
)
52 , m_callback(callback
)
54 , m_zeroRegistered(false)
56 m_sendBuffer
= new unsigned char[MAX_PACKET_SIZE
];
59 RawChannel::~RawChannel()
61 UnregisterZeroSocketInterest();
62 delete[] m_sendBuffer
;
65 void RawChannel::OnOpen()
67 // Enable sequence packets so that DataSendAck callback and close can be
69 m_zeroRegistered
= true;
70 m_socket
->HideSequencePacket(false);
71 m_con
.m_queue
->RegisterInterest(0, HandleReceivedDataCallback
, this);
72 m_socket
->RegisterInterest(HandleReceivedDataCallback
, this);
75 ///////////////////////////////////////////////////////////////////////////////
78 void RawChannel::Send(Data
& data
, int timeout
)
80 size_t packetSize
= RAW_HEADER_SIZE
+ data
.GetSize();
82 if( packetSize
> MAX_PACKET_SIZE
) {
83 throw Barry::Error("RawChannel: send data size larger than MaximumPacketSize");
86 // setup header and copy data in
87 MAKE_PACKETPTR_BUF(packet
, m_sendBuffer
);
88 packet
->socket
= htobs(m_socket
->GetSocket());
89 packet
->size
= htobs(packetSize
);
90 std::memcpy(&(m_sendBuffer
[RAW_HEADER_SIZE
]), data
.GetData(), data
.GetSize());
92 Data
toSend(m_sendBuffer
, packetSize
);
93 m_socket
->Send(toSend
, timeout
);
96 size_t RawChannel::MaximumSendSize()
98 return MAX_PACKET_SIZE
- RAW_HEADER_SIZE
;
101 void RawChannel::HandleReceivedData(Data
& data
)
103 Protocol::CheckSize(data
, MIN_PACKET_DATA_SIZE
);
104 MAKE_PACKETPTR_BUF(packet
, data
.GetData());
106 if( packet
->socket
== 0 ) {
107 switch( btohs(packet
->command
) )
109 case SB_COMMAND_SEQUENCE_HANDSHAKE
:
110 m_callback
.DataSendAck();
112 case SB_COMMAND_CLOSE_SOCKET
:
113 case SB_COMMAND_REMOTE_CLOSE_SOCKET
:
114 // Stop listening to socket 0 messages
115 // so that socket close work.
116 UnregisterZeroSocketInterest();
117 m_callback
.ChannelClose();
120 UnregisterZeroSocketInterest();
121 m_callback
.ChannelError("RawChannel: Got unexpected socket zero packet");
126 // Should be a socket packet for us, so remove packet headers
127 Data
partial(data
.GetData() + RAW_HEADER_SIZE
, data
.GetSize() - RAW_HEADER_SIZE
);
128 m_callback
.DataReceived(partial
);
132 void RawChannel::UnregisterZeroSocketInterest()
134 if( m_zeroRegistered
) {
135 m_con
.m_queue
->UnregisterInterest(0);
136 m_socket
->HideSequencePacket(true);
137 m_zeroRegistered
= false;
141 }} // namespace Barry::Mode