1/*
2 * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25package com.sun.nio.sctp;
26
27import java.net.SocketAddress;
28
29/**
30 * The {@code MessageInfo} class provides additional ancillary information about
31 * messages.
32 *
33 * <P> Received SCTP messages, returned by
34 * {@link SctpChannel#receive SctpChannel.receive} and {@link
35 * SctpMultiChannel#receive SctpMultiChannel.receive},
36 * return a {@code MessageInfo} instance that can be queried to determine
37 * ancillary information about the received message. Messages being sent should
38 * use one of the {@link #createOutgoing(java.net.SocketAddress,int)
39 * createOutgoing} methods to provide ancillary data for the message being
40 * sent, and may use the appropriate setter methods to override the default
41 * values provided for {@link #isUnordered() unordered}, {@link #timeToLive()
42 * timeToLive}, {@link #isComplete() complete} and {@link #payloadProtocolID()
43 * payloadProtocolID}, before sending the message.
44 *
45 * <P> For out going messages the {@code timeToLive} parameter is a time period
46 * that the sending side SCTP stack may expire the message if it has not been
47 * sent. This time period is an indication to the stack that the message is no
48 * longer required to be sent after the time period expires. It is not a hard
49 * timeout and may be influenced by whether the association supports the partial
50 * reliability extension, <a href=http://www.ietf.org/rfc/rfc3758.txt>RFC 3758
51 * </a>.
52 *
53 * <P> {@code MessageInfo} instances are not safe for use by multiple concurrent
54 * threads. If a MessageInfo is to be used by more than one thread then access
55 * to the MessageInfo should be controlled by appropriate synchronization.
56 *
57 * @since 1.7
58 */
59public abstract class MessageInfo {
60    /**
61     * Initializes a new instance of this class.
62     */
63    protected MessageInfo() {}
64
65    /**
66     * Creates a {@code MessageInfo} instance suitable for use when
67     * sending a message.
68     *
69     * <P> The returned instance will have its {@link #isUnordered() unordered}
70     * value set to {@code false}, its {@link #timeToLive() timeToLive} value
71     * set to {@code 0}, its {@link #isComplete() complete} value set
72     * to {@code true}, and its {@link #payloadProtocolID() payloadProtocolID}
73     * value set to {@code 0}. These values, if required, can be set through
74     * the appropriate setter method before sending the message.
75     *
76     * @param  address
77     *         For a connected {@code SctpChannel} the address is the
78     *         preferred peer address of the association to send the message
79     *         to, or {@code null} to use the peer primary address. For an
80     *         {@code SctpMultiChannel} the address is used to determine
81     *         the association, or if no association exists with a peer of that
82     *         address then one is setup.
83     *
84     * @param  streamNumber
85     *         The stream number that the message will be sent on
86     *
87     * @return  The outgoing message info
88     *
89     * @throws  IllegalArgumentException
90     *          If the streamNumber is negative or greater than {@code 65536}
91     */
92    public static MessageInfo createOutgoing(SocketAddress address,
93                                             int streamNumber) {
94        if (streamNumber < 0 || streamNumber > 65536)
95            throw new IllegalArgumentException("Invalid stream number");
96
97        return new sun.nio.ch.sctp.MessageInfoImpl(null, address, streamNumber);
98    }
99    /**
100     * Creates a {@code MessageInfo} instance suitable for use when
101     * sending a message to a given association. Typically used for
102     * {@code SctpMultiChannel} when an association has already been setup.
103     *
104     * <P> The returned instance will have its {@link #isUnordered() unordered}
105     * value set to {@code false}, its {@link #timeToLive() timeToLive} value
106     * set to {@code 0}, its {@link #isComplete() complete} value set
107     * to {@code true}, and its {@link #payloadProtocolID() payloadProtocolID}
108     * value set to {@code 0}. These values, if required, can be set through
109     * the appropriate setter method before sending the message.
110     *
111     * @param  association
112     *         The association to send the message on
113     *
114     * @param  address
115     *         The preferred peer address of the association to send the message
116     *         to, or {@code null} to use the peer primary address
117     *
118     * @param  streamNumber
119     *         The stream number that the message will be sent on.
120     *
121     * @return  The outgoing message info
122     *
123     * @throws  IllegalArgumentException
124     *          If {@code association} is {@code null}, or the streamNumber is
125     *          negative or greater than {@code 65536}
126     */
127    public static MessageInfo createOutgoing(Association association,
128                                             SocketAddress address,
129                                             int streamNumber) {
130        if (association == null)
131            throw new IllegalArgumentException("association cannot be null");
132
133        if (streamNumber < 0 || streamNumber > 65536)
134            throw new IllegalArgumentException("Invalid stream number");
135
136        return new sun.nio.ch.sctp.MessageInfoImpl(association,
137                                                   address, streamNumber);
138    }
139
140    /**
141     * Returns the source socket address if the message has been received,
142     * otherwise the preferred destination of the message to be sent.
143     *
144     * @return  The socket address, or {@code null} if this instance is to be
145     *          used for sending a message and has been construced without
146     *          specifying a preferred destination address
147     *
148     */
149    public abstract SocketAddress address();
150
151    /**
152     * Returns the association that the message was received on, if the message
153     * has been received, otherwise the association that the message is to be
154     * sent on.
155     *
156     * @return The association, or {@code null} if this instance is to be
157     *         used for sending a message and has been construced using the
158     *         the {@link #createOutgoing(SocketAddress,int)
159     *         createOutgoing(SocketAddress,int)} static factory method
160     */
161    public abstract Association association();
162
163    /**
164     * Returns the number of bytes read for the received message.
165     *
166     * <P> This method is only appicable for received messages, it has no
167     * meaning for messages being sent.
168     *
169     * @return  The number of bytes read, {@code -1} if the channel is an {@link
170     *          SctpChannel} that has reached end-of-stream, otherwise
171     *          {@code 0}
172     */
173    public abstract int bytes();
174
175    /**
176     * Tells whether or not the message is complete.
177     *
178     * <P> For received messages {@code true} indicates that the message was
179     * completely received. For messages being sent {@code true} indicates that
180     * the message is complete, {@code false} indicates that the message is not
181     * complete. How the send channel interprets this value depends on the value
182     * of its {@link SctpStandardSocketOptions#SCTP_EXPLICIT_COMPLETE
183     * SCTP_EXPLICIT_COMPLETE} socket option.
184     *
185     * @return  {@code true} if, and only if, the message is complete
186     */
187    public abstract boolean isComplete();
188
189    /**
190     * Sets whether or not the message is complete.
191     *
192     * <P> For messages being sent {@code true} indicates that
193     * the message is complete, {@code false} indicates that the message is not
194     * complete. How the send channel interprets this value depends on the value
195     * of its {@link SctpStandardSocketOptions#SCTP_EXPLICIT_COMPLETE
196     * SCTP_EXPLICIT_COMPLETE} socket option.
197     *
198     * @param  complete
199     *         {@code true} if, and only if, the message is complete
200     *
201     * @return  This MessageInfo
202     *
203     * @see  MessageInfo#isComplete()
204     */
205    public abstract MessageInfo complete(boolean complete);
206
207    /**
208     * Tells whether or not the message is unordered. For received messages
209     * {@code true} indicates that the message was sent non-ordered. For
210     * messages being sent {@code true} requests the un-ordered delivery of the
211     * message, {@code false} indicates that the message is ordered.
212     *
213     * @return  {@code true} if the message is unordered, otherwise
214     *          {@code false}
215     */
216    public abstract boolean isUnordered();
217
218    /**
219     * Sets whether or not the message is unordered.
220     *
221     * @param  unordered
222     *         {@code true} requests the un-ordered delivery of the message,
223     *         {@code false} indicates that the message is ordered.
224     *
225     * @return  This MessageInfo
226     *
227     * @see  MessageInfo#isUnordered()
228     */
229    public abstract MessageInfo unordered(boolean unordered);
230
231    /**
232     * Returns the payload protocol Identifier.
233     *
234     * <P> A value indicating the type of payload protocol data being
235     * transmitted/received. This value is passed as opaque data by SCTP.
236     * {@code 0} indicates an unspecified payload protocol identifier.
237     *
238     * @return  The Payload Protocol Identifier
239     */
240    public abstract int payloadProtocolID();
241
242    /**
243     * Sets the payload protocol Identifier.
244     *
245     * <P> A value indicating the type of payload protocol data being
246     * transmitted. This value is passed as opaque data by SCTP.
247     *
248     * @param  ppid
249     *         The Payload Protocol Identifier, or {@code 0} indicate an
250     *         unspecified payload protocol identifier.
251     *
252     * @return  This MessageInfo
253     *
254     * @see  MessageInfo#payloadProtocolID()
255     */
256    public abstract MessageInfo payloadProtocolID(int ppid);
257
258    /**
259     * Returns the stream number that the message was received on, if the
260     * message has been received, otherwise the stream number that the message
261     * is to be sent on.
262     *
263     * @return  The stream number
264     */
265    public abstract int streamNumber();
266
267    /**
268     * Sets the stream number that the message is to be sent on.
269     *
270     * @param  streamNumber
271     *         The stream number
272     *
273     * @throws  IllegalArgumentException
274     *          If the streamNumber is negative or greater than {@code 65536}
275     *
276     * @return  This MessageInfo
277     */
278    public abstract MessageInfo streamNumber(int streamNumber);
279
280    /**
281     * The time period that the sending side may expire the message if it has
282     * not been sent, or {@code 0} to indicate that no timeout should occur. This
283     * value is only applicable for messages being sent, it has no meaning for
284     * received messages.
285     *
286     * @return  The time period in milliseconds, or {@code 0}
287     */
288    public abstract long timeToLive();
289
290    /**
291     * Sets the time period that the sending side may expire the message if it
292     * has not been sent.
293     *
294     * @param  millis
295     *         The time period in milliseconds, or {@code 0} to indicate that no
296     *         timeout should occur
297     *
298     * @return  This MessageInfo
299     *
300     * @see MessageInfo#timeToLive()
301     */
302    public abstract MessageInfo timeToLive(long millis);
303}
304