d02e585b1e43dee29b8c659dab57f773ed459a64
[netconf.git] / netconf / netconf-netty-util / src / main / java / org / opendaylight / netconf / nettyutil / handler / ssh / client / NettyPipelineAwareChannelSubsystem.java
1 /*
2  * Copyright (c) 2021 PANTHEON.tech, s.r.o. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.netconf.nettyutil.handler.ssh.client;
9
10 import static java.util.Objects.requireNonNull;
11
12 import io.netty.buffer.Unpooled;
13 import io.netty.channel.ChannelPipeline;
14 import java.io.IOException;
15 import org.opendaylight.netconf.shaded.sshd.client.channel.ChannelSubsystem;
16 import org.slf4j.Logger;
17 import org.slf4j.LoggerFactory;
18
19 /**
20  * A {@link ChannelSubsystem} for subsystem which routes incoming data to a particular {@link ChannelPipeline}.
21  */
22 public class NettyPipelineAwareChannelSubsystem extends ChannelSubsystem {
23     private static final Logger LOG = LoggerFactory.getLogger(NettyPipelineAwareChannelSubsystem.class);
24
25     private final ChannelPipeline pipeline;
26
27     public NettyPipelineAwareChannelSubsystem(final String subsystem, final ChannelPipeline pipeline) {
28         super(subsystem);
29         this.pipeline = requireNonNull(pipeline);
30     }
31
32     @Override
33     protected void doWriteData(final byte[] data, final int off, final long len) throws IOException {
34         // If we're already closing, ignore incoming data
35         if (isClosing()) {
36             return;
37         }
38         // TODO: consider using context's allocator for heap buffer here
39         final int reqLen = (int) len;
40         pipeline.firstContext().fireChannelRead(Unpooled.copiedBuffer(data, off, reqLen));
41         if (reqLen > 0) {
42             getLocalWindow().release(reqLen);
43         }
44     }
45
46     @Override
47     protected void doWriteExtendedData(final byte[] data, final int off, final long len) throws IOException {
48         // If we're already closing, ignore incoming data
49         if (isClosing()) {
50             return;
51         }
52
53         LOG.debug("Discarding {} bytes of extended data", len);
54         if (len > 0) {
55             getLocalWindow().release(len);
56         }
57     }
58
59     @Override
60     public void close() {
61         super.close(false);
62     }
63 }