Fixing coding standards violations from Chris Frey's review. Also adding error detect...
[barry.git] / src / m_raw_channel.cc
blob04c92db780a47f61d3366bffa0fbd825f61ccc6b
1 ///
2 /// \file m_raw_channel.cc
3 /// Mode class for a raw channel
4 ///
6 /*
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"
24 #include "data.h"
25 #include "protocol.h"
26 #include "protostructs.h"
27 #include "packet.h"
28 #include "endian.h"
29 #include "error.h"
30 #include "usbwrap.h"
31 #include "controller.h"
32 #include <stdexcept>
33 #include <sstream>
34 #include <cstring>
35 #include "protostructs.h"
37 #include "debug.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)
53 , m_sendBuffer(0)
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
68 // implemented
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 ///////////////////////////////////////////////////////////////////////////////
76 // public API
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();
111 break;
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();
118 break;
119 default:
120 UnregisterZeroSocketInterest();
121 m_callback.ChannelError("RawChannel: Got unexpected socket zero packet");
122 break;
125 else {
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