1/*
2 * Copyright (c) 2011 jMonkeyEngine
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 *   notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 *   notice, this list of conditions and the following disclaimer in the
14 *   documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
17 *   may be used to endorse or promote products derived from this software
18 *   without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33package com.jme3.network.kernel.udp;
34
35import com.jme3.network.kernel.Endpoint;
36import com.jme3.network.kernel.Kernel;
37import com.jme3.network.kernel.KernelException;
38import java.io.IOException;
39import java.net.DatagramPacket;
40import java.net.DatagramSocket;
41import java.net.SocketAddress;
42import java.nio.ByteBuffer;
43
44
45/**
46 *  Endpoint implementation that encapsulates the
47 *  UDP connection information for return messaging,
48 *  identification of envelope sources, etc.
49 *
50 *  @version   $Revision: 8843 $
51 *  @author    Paul Speed
52 */
53public class UdpEndpoint implements Endpoint
54{
55    private long id;
56    private SocketAddress address;
57    private DatagramSocket socket;
58    private UdpKernel kernel;
59    private boolean connected = true; // it's connectionless but we track logical state
60
61    public UdpEndpoint( UdpKernel kernel, long id, SocketAddress address, DatagramSocket socket )
62    {
63        this.id = id;
64        this.address = address;
65        this.socket = socket;
66        this.kernel = kernel;
67    }
68
69    public Kernel getKernel()
70    {
71        return kernel;
72    }
73
74    protected SocketAddress getRemoteAddress()
75    {
76        return address;
77    }
78
79    public void close()
80    {
81        close( false );
82    }
83
84    public void close( boolean flush )
85    {
86        // No real reason to flush UDP traffic yet... especially
87        // when considering that the outbound UDP isn't even
88        // queued.
89
90        try {
91            kernel.closeEndpoint(this);
92            connected = false;
93        } catch( IOException e ) {
94            throw new KernelException( "Error closing endpoint for socket:" + socket, e );
95        }
96    }
97
98    public long getId()
99    {
100        return id;
101    }
102
103    public String getAddress()
104    {
105        return String.valueOf(address);
106    }
107
108    public boolean isConnected()
109    {
110        // The socket is always unconnected anyway so we track our
111        // own logical state for the kernel's benefit.
112        return connected;
113    }
114
115    public void send( ByteBuffer data )
116    {
117        if( !isConnected() ) {
118            throw new KernelException( "Endpoint is not connected:" + this );
119        }
120
121
122        try {
123            DatagramPacket p = new DatagramPacket( data.array(), data.position(),
124                                                   data.remaining(), address );
125
126            // Just queue it up for the kernel threads to write
127            // out
128            kernel.enqueueWrite( this, p );
129
130            //socket.send(p);
131        } catch( IOException e ) {
132            throw new KernelException( "Error sending datagram to:" + address, e );
133        }
134    }
135
136    public String toString()
137    {
138        return "UdpEndpoint[" + id + ", " + address + "]";
139    }
140}
141