blob: 812c6a8364453c940242179693921a942981859d [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package vncclient.vnc;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import streamer.ByteBuffer;
import streamer.InputStreamSource;
import streamer.Link;
import streamer.OneTimeSwitch;
import streamer.OutputStreamSink;
import streamer.Pipeline;
import streamer.PipelineImpl;
/**
* VNC server sends hello packet with RFB protocol version, e.g.
* "RFB 003.007\n". We need to send response packet with supported protocol
* version, e.g. "RFB 003.003\n".
*/
public class Vnc33Hello extends OneTimeSwitch {
public Vnc33Hello(String id) {
super(id);
}
@Override
protected void handleOneTimeData(ByteBuffer buf, Link link) {
if (verbose)
System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
// Initial packet is exactly 12 bytes long
if (!cap(buf, 12, 12, link, false))
return;
// Read protocol version
String rfbProtocol = new String(buf.data, buf.offset, buf.length, RfbConstants.US_ASCII_CHARSET);
buf.unref();
// Server should use RFB protocol 3.x
if (!rfbProtocol.contains(RfbConstants.RFB_PROTOCOL_VERSION_MAJOR))
throw new RuntimeException("Cannot handshake with VNC server. Unsupported protocol version: \"" + rfbProtocol + "\".");
// Send response: we support RFB 3.3 only
String ourProtocolString = RfbConstants.RFB_PROTOCOL_VERSION + "\n";
ByteBuffer outBuf = new ByteBuffer(ourProtocolString.getBytes(RfbConstants.US_ASCII_CHARSET));
if (verbose) {
outBuf.putMetadata("sender", this);
outBuf.putMetadata("version", RfbConstants.RFB_PROTOCOL_VERSION);
}
pushDataToOTOut(outBuf);
// Switch off this element from circuit
switchOff();
}
@Override
public String toString() {
return "Vnc3.3 Hello(" + id + ")";
}
/**
* Example.
*/
public static void main(String args[]) {
// System.setProperty("streamer.Link.debug", "true");
System.setProperty("streamer.Element.debug", "true");
// System.setProperty("streamer.Pipeline.debug", "true");
InputStream is = new ByteArrayInputStream("RFB 003.007\ntest".getBytes(RfbConstants.US_ASCII_CHARSET));
ByteArrayOutputStream initOS = new ByteArrayOutputStream();
ByteArrayOutputStream mainOS = new ByteArrayOutputStream();
InputStreamSource inputStreamSource = new InputStreamSource("source", is);
OutputStreamSink outputStreamSink = new OutputStreamSink("mainSink", mainOS);
Vnc33Hello hello = new Vnc33Hello("hello");
Pipeline pipeline = new PipelineImpl("test");
pipeline.addAndLink(inputStreamSource, hello, outputStreamSink);
pipeline.add(new OutputStreamSink("initSink", initOS));
pipeline.link("hello >" + OneTimeSwitch.OTOUT, "initSink");
pipeline.runMainLoop("source", STDOUT, false, false);
String initOut = new String(initOS.toByteArray(), RfbConstants.US_ASCII_CHARSET);
String mainOut = new String(mainOS.toByteArray(), RfbConstants.US_ASCII_CHARSET);
if (!"RFB 003.003\n".equals(initOut))
System.err.println("Unexpected value for hello response: \"" + initOut + "\".");
if (!"test".equals(mainOut))
System.err.println("Unexpected value for main data: \"" + mainOut + "\".");
}
}