Package org.jnode.net.util

Source Code of org.jnode.net.util.AbstractDatagramSocketImpl

/*
* $Id$
*
* Copyright (C) 2003-2014 JNode.org
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; If not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.jnode.net.util;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocketImpl;
import java.net.ExSocketOptions;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketAddress;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import org.jnode.bootlog.BootLogInstance;
import org.jnode.driver.Device;
import org.jnode.driver.DeviceNotFoundException;
import org.jnode.driver.DeviceUtils;
import org.jnode.net.SocketBuffer;
import org.jnode.net.ethernet.EthernetConstants;
import org.jnode.util.Queue;

/**
* @author epr
*/
public abstract class AbstractDatagramSocketImpl extends DatagramSocketImpl implements
        ExSocketOptions {

    /** The receive queue of SocketBuffer instances */
    private final Queue<SocketBuffer> receiveQueue = new Queue<SocketBuffer>();
   
    /** Have I been closed? */
    private boolean closed;
   
    /** Time to live */
    private int ttl = 0xFF;
   
    /** Type of service */
    private int tos = 0;
   
    /** Timeout of network operations */
    private int timeout = 0;
   
    /** Local address */
    private InetAddress laddr;
   
    /** Send using broadcast addresses? */
    private boolean broadcast = true;
   
    /** Device used for transmission (can be null) */
    private Device device;

    /**
     * Create a new instance
     */
    public AbstractDatagramSocketImpl() {
        this.closed = false;
    }

    /**
     * @see java.net.DatagramSocketImpl#bind(int, java.net.InetAddress)
     */
    protected final synchronized void bind(int lport, InetAddress laddr) throws SocketException {
        this.localPort = lport;
        this.laddr = laddr;
        doBind(lport, laddr);
    }

    protected abstract void doBind(int lport, InetAddress laddr) throws SocketException;

    /**
     * @see java.net.DatagramSocketImpl#close()
     */
    protected final synchronized void close() {
        if (!closed) {
            this.closed = true;
            doClose();
            receiveQueue.close();
        }
    }

    protected abstract void doClose();

    /**
     * @see java.net.DatagramSocketImpl#create()
     */
    protected void create() throws SocketException {
        // Nothing todo here
    }

    /**
     * @see java.net.SocketOptions#getOption(int)
     */
    public final synchronized Object getOption(int option_id) throws SocketException {
        if (closed) {
            throw new SocketException("DatagramSocket closed");
        }
        switch (option_id) {
            case IP_TOS:
                return tos;
            case SO_BINDADDR:
                return laddr;
            case SO_BROADCAST:
                return broadcast;
            case SO_RCVBUF:
                return EthernetConstants.ETH_FRAME_LEN;
            case SO_SNDBUF:
                return EthernetConstants.ETH_FRAME_LEN;
            case SO_TRANSMIT_IF:
                return (device == null) ? null : NetworkInterface.getByName(device.getId());
            case SO_TIMEOUT:
                return timeout;
            default:
                return doGetOption(option_id);
        }
    }

    protected Object doGetOption(int option_id) throws SocketException {
        throw new SocketException("Unknown option " + option_id);
    }

    /**
     * @see java.net.SocketOptions#setOption(int, java.lang.Object)
     */
    public final synchronized void setOption(int option_id, Object val) throws SocketException {
        if (closed) {
            throw new SocketException("DatagramSocket closed");
        }
        try {
            switch (option_id) {
                case IP_TOS:
                    tos = (Integer) val;
                    break;
                case SO_BINDADDR:
                    throw new SocketException("Get only option: SO_BINDADDR");
                case SO_BROADCAST:
                    broadcast = (Boolean) val;
                    break;
                case SO_RCVBUF: /* ignore */
                    break;
                case SO_SNDBUF: /* ignore */
                    break;
                case SO_TRANSMIT_IF:
                    if (val == null) {
                        device = null;
                    } else {
                        final NetworkInterface netIf = (NetworkInterface) val;
                        try {
                            device = DeviceUtils.getDevice(netIf.getName());
                        } catch (DeviceNotFoundException ex) {
                            throw new SocketException("Unknown networkinterface " + netIf.getName());
                        }
                    }
                    break;
                case SO_TIMEOUT:
                    timeout = (Integer) val;
                    break;
                case SO_REUSEADDR:
                    // Ignored for now
                    break;
                default:
                    doSetOption(option_id, val);
            }
        } catch (ClassCastException ex) {
            throw (SocketException) new SocketException("Invalid option type").initCause(ex);
        }
    }

    protected void doSetOption(int option_id, Object val) throws SocketException {
        BootLogInstance.get().error("Unknown option " + option_id);
    }

    /**
     * @see java.net.DatagramSocketImpl#getTimeToLive()
     */
    protected final int getTimeToLive() throws IOException {
        return ttl;
    }

    /**
     * @see java.net.DatagramSocketImpl#join(java.net.InetAddress)
     */
    protected void join(InetAddress inetaddr) throws IOException {
        // TODO Auto-generated method stub
    }

    /**
     * @see java.net.DatagramSocketImpl#joinGroup(java.net.SocketAddress,
     *      java.net.NetworkInterface)
     */
    protected void joinGroup(SocketAddress mcastaddr, NetworkInterface netIf) throws IOException {
        // TODO Auto-generated method stub
    }

    /**
     * @see java.net.DatagramSocketImpl#leave(java.net.InetAddress)
     */
    protected void leave(InetAddress inetaddr) throws IOException {
        // TODO Auto-generated method stub
    }

    /**
     * @see java.net.DatagramSocketImpl#leaveGroup(java.net.SocketAddress,
     *      java.net.NetworkInterface)
     */
    protected void leaveGroup(SocketAddress mcastaddr, NetworkInterface netIf) throws IOException {
        // TODO Auto-generated method stub
    }

    /**
     * @see java.net.DatagramSocketImpl#peek(java.net.InetAddress)
     */
    protected int peek(InetAddress i) throws IOException {
        // TODO Auto-generated method stub
        return 0;
    }

    /**
     * @see java.net.DatagramSocketImpl#peekData(java.net.DatagramPacket)
     */
    protected int peekData(DatagramPacket p) throws IOException {
        throw new IOException("Not implemented");
    }

    /**
     * @see java.net.DatagramSocketImpl#receive(java.net.DatagramPacket)
     */
    protected final void receive(DatagramPacket p) throws IOException {
        if (closed) {
            throw new SocketException("DatagramSocket has been closed");
        }
        final SocketBuffer skbuf = (SocketBuffer) receiveQueue.get(timeout);
        if (skbuf == null) {
            if (closed) {
                throw new SocketException("DatagramSocket has been closed");
            } else {
                throw new SocketTimeoutException("Timeout in receive");
            }
        } else {
            onReceive(p, skbuf);
        }
    }

    protected abstract void onReceive(DatagramPacket p, SocketBuffer skbuf) throws IOException;

    /**
     * Deliver a packet to this socket. This will put the packet in the
     * receive queue if this socket has not been closed.
     * @param skbuf
     */
    public final boolean deliverReceived(SocketBuffer skbuf) {
        if (!closed) {
            receiveQueue.add(skbuf);
            return true;
        } else {
            return false;
        }
    }

    /**
     * @see java.net.DatagramSocketImpl#setTimeToLive(int)
     */
    protected final void setTimeToLive(int ttl) {
        this.ttl = ttl;
    }

    /**
     * Gets the local port of this socket
     * @see java.net.DatagramSocketImpl#getLocalPort()
     */
    public final int getLocalPort() {
        return super.getLocalPort();
    }

    /**
     * Gets the local port of this socket
     */
    public final InetAddress getLocalAddress() {
        return laddr;
    }

    /**
     * @see java.lang.Object#finalize()
     */
    protected void finalize() throws Throwable {
        close();
        super.finalize();
    }

    /**
     * Gets the device used to send/receive packets.
     */
    protected Device getDevice() {
        return device;
    }

    /**
     * Gets the timeout used in receive
     */
    protected int getTimeout() {
        return timeout;
    }

    /**
     * Gets the Type of Service, used in send
     */
    protected int getTos() {
        return tos;
    }
}
TOP

Related Classes of org.jnode.net.util.AbstractDatagramSocketImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.