All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opencoap.transport.mbedtls.MbedtlsCoapTransport Maven / Gradle / Ivy

There is a newer version: 6.25.2
Show newest version
/*
 * Copyright (C) 2022-2023 java-coap contributors (https://github.com/open-coap/java-coap)
 * SPDX-License-Identifier: Apache-2.0
 * Licensed 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 org.opencoap.transport.mbedtls;

import static java.util.concurrent.CompletableFuture.completedFuture;
import static org.opencoap.transport.mbedtls.DtlsTransportContext.toTransportContext;
import com.mbed.coap.exception.CoapException;
import com.mbed.coap.packet.CoapPacket;
import com.mbed.coap.packet.CoapSerializer;
import com.mbed.coap.transport.CoapTransport;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.time.Duration;
import java.util.concurrent.CompletableFuture;
import org.opencoap.ssl.transport.DtlsTransmitter;
import org.opencoap.ssl.transport.Packet;
import org.opencoap.ssl.transport.Transport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MbedtlsCoapTransport implements CoapTransport {
    private static final Logger LOGGER = LoggerFactory.getLogger(MbedtlsCoapTransport.class);
    private final Transport> dtlsTransport;

    public MbedtlsCoapTransport(Transport> dtlsTransport) {
        this.dtlsTransport = dtlsTransport;
    }

    public static MbedtlsCoapTransport of(DtlsTransmitter dtlsTransmitter) {
        InetSocketAddress adr = dtlsTransmitter.getRemoteAddress();

        return new MbedtlsCoapTransport(dtlsTransmitter.map(
                bytes -> new Packet<>(bytes, adr),
                Packet::getBuffer
        ));
    }

    public static MbedtlsCoapTransport of(Transport transport, InetSocketAddress adr) {
        return new MbedtlsCoapTransport(transport.map(
                bytes -> new Packet<>(bytes, adr),
                Packet::getBuffer
        ));
    }

    @Override
    public void start() {
        // do nothing
    }

    @Override
    public void stop() {
        try {
            dtlsTransport.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public CompletableFuture sendPacket(CoapPacket coapPacket) {
        ByteBuffer buf = ByteBuffer.wrap(CoapSerializer.serialize(coapPacket));
        return dtlsTransport.send(new Packet<>(buf, coapPacket.getRemoteAddress()));
    }

    @Override
    public CompletableFuture receive() {
        return dtlsTransport.receive(Duration.ofSeconds(1)).thenCompose(this::deserialize);
    }

    private CompletableFuture deserialize(Packet packet) {
        CoapPacket coapPacket = deserializeCoap(packet);
        if (coapPacket != null) {
            return completedFuture(coapPacket);
        }

        // keep waiting
        return receive();
    }

    static CoapPacket deserializeCoap(Packet packet) {
        if (packet.getBuffer().remaining() > 0) {
            try {
                ByteArrayInputStream bufInput = toInputStream(packet.getBuffer());
                CoapPacket coapPacket = CoapSerializer.deserialize(packet.getPeerAddress(), bufInput);
                coapPacket.setTransportContext(toTransportContext(packet.getSessionContext()));
                return coapPacket;
            } catch (CoapException e) {
                LOGGER.warn("[{}] Received malformed coap. {}", packet.getPeerAddress(), e.toString());
            }
        }
        return null;
    }

    private static ByteArrayInputStream toInputStream(ByteBuffer byteBuffer) {
        return new ByteArrayInputStream(byteBuffer.array(), byteBuffer.position(), byteBuffer.remaining());
    }

    @Override
    public InetSocketAddress getLocalSocketAddress() {
        return new InetSocketAddress("0.0." + "0.0", dtlsTransport.localPort());
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy