| // 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 + "\"."); |
| |
| } |
| } |