Added new constructor. May need to tighten down interfaces in the future.
[packetcable.git] / packetcable-driver / src / main / java / org / umu / cops / stack / COPSContext.java
1 /*
2  * Copyright (c) 2003 University of Murcia.  All rights reserved.
3  * --------------------------------------------------------------
4  * For more information, please see <http://www.umu.euro6ix.org/>.
5  */
6
7 package org.umu.cops.stack;
8
9 import org.umu.cops.stack.COPSObjHeader.CNum;
10 import org.umu.cops.stack.COPSObjHeader.CType;
11
12 import java.io.IOException;
13 import java.io.OutputStream;
14 import java.net.Socket;
15 import java.util.Map;
16 import java.util.concurrent.ConcurrentHashMap;
17
18 /**
19  * COPS Context Object (RFC 2748)
20  *
21  * Specifies the type of event(s) that triggered the query. Required for
22  * request messages. Admission control, resource allocation, and
23  * forwarding requests are all amenable to client-types that outsource
24  * their decision making facility to the PDP. For applicable client-
25  * types a PEP can also make a request to receive named configuration
26  * information from the PDP. This named configuration data may be in a
27  * form useful for setting system attributes on a PEP, or it may be in
28  * the form of policy rules that are to be directly verified by the PEP.
29  *
30  * Multiple flags can be set for the same request. This is only allowed,
31  * however, if the set of client specific information in the combined
32  * request is identical to the client specific information that would be
33  * specified if individual requests were made for each specified flag.
34  *
35  * C-num = 2, C-Type = 1
36  *
37  * R-Type (Request Type Flag)
38  *
39  * 0x01 = Incoming-Message/Admission Control request
40  * 0x02 = Resource-Allocation request
41  * 0x04 = Outgoing-Message request
42  * 0x08 = Configuration request
43  *
44  * M-Type (Message Type)
45  *
46  * Client Specific 16 bit values of protocol message types
47  */
48 public class COPSContext extends COPSObjBase {
49
50     /**
51      * A Map containing each RType by the byte value
52      */
53     public final static Map<Integer, RType> VAL_TO_RTYPE = new ConcurrentHashMap<>();
54     static {
55         VAL_TO_RTYPE.put(1, RType.IN_ADMIN);
56         VAL_TO_RTYPE.put(2, RType.RES_ALLOC);
57         VAL_TO_RTYPE.put(4, RType.OUT);
58         VAL_TO_RTYPE.put(8, RType.CONFIG);
59     }
60
61     /**
62      * A Map containing the byte value by RType
63      */
64     private final static Map<RType, Integer> RTYPE_TO_VAL = new ConcurrentHashMap<>();
65     static {
66         for (final Map.Entry<Integer, RType> entry : VAL_TO_RTYPE.entrySet()) {
67             RTYPE_TO_VAL.put(entry.getValue(), entry.getKey());
68         }
69     }
70
71     /**
72      * The request type
73      */
74     private final RType _rType;
75
76     /**
77      * The message type
78      * Cannot find a list of types in order to make this an enumeration
79      */
80     private short _mType;
81
82     /**
83      * Constructor generally used for sending messages
84      * @param rType - the type of request
85      * @param mType - the type of message
86      * @throws java.lang.IllegalArgumentException
87      */
88     public COPSContext(final RType rType, final short mType ) {
89         this(new COPSObjHeader(CNum.CONTEXT, CType.DEF), rType, mType);
90     }
91
92     /**
93      * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the
94      * COPSObjHeader information is known
95      * @param rType - the type of request
96      * @param mType - the type of message
97      * @throws java.lang.IllegalArgumentException
98      */
99     protected COPSContext(final COPSObjHeader objHdr, final RType rType, final short mType ) {
100         super(objHdr);
101
102         if (!objHdr.getCNum().equals(CNum.CONTEXT))
103             throw new IllegalArgumentException("CNum must be equal to " + CNum.CONTEXT);
104         if (!objHdr.getCType().equals(CType.DEF))
105             throw new IllegalArgumentException("Invalid CType value. Must be " + CType.DEF);
106         if (rType == null) throw new IllegalArgumentException("Must have a valid RType");
107
108         _rType = rType;
109         _mType = mType;
110     }
111
112     @Override
113     public void writeBody(final Socket socket) throws IOException {
114         byte[] buf = new byte[4];
115
116         final int rType = RTYPE_TO_VAL.get(_rType);
117         buf[0] = (byte)((byte)rType >> 8);
118         buf[1] = (byte)rType;
119
120         buf[2] = (byte)(_mType >> 8);
121         buf[3] = (byte)_mType;
122
123         COPSUtil.writeData(socket, buf, 4);
124     }
125
126     @Override
127     public int getDataLength() {
128         return 4;
129     }
130
131     /**
132      * Returns the detail description of the request type
133      * @return   a String
134      */
135     public String getDescription() {
136         switch (_rType) {
137             case IN_ADMIN: return "Incoming Message/Admission Control";
138             case RES_ALLOC: return "Resource allocation";
139             case OUT: return "Outgoing message";
140             case CONFIG: return "Configuration";
141             default: return "";
142         }
143     }
144
145     @Override
146     public void dumpBody(final OutputStream os) throws IOException {
147         os.write(("context: " + getDescription() + "," + _mType + "\n").getBytes());
148     }
149
150     @Override
151     public boolean equals(Object o) {
152         if (this == o) {
153             return true;
154         }
155         if (!(o instanceof COPSContext)) {
156             return false;
157         }
158         if (!super.equals(o)) {
159             return false;
160         }
161
162         final COPSContext that = (COPSContext) o;
163
164         return _mType == that._mType && _rType == that._rType;
165
166     }
167
168     @Override
169     public int hashCode() {
170         int result = super.hashCode();
171         result = 31 * result + _rType.hashCode();
172         result = 31 * result + (int) _mType;
173         return result;
174     }
175
176     /**
177      * Parses bytes to return a COPSContext object
178      * @param objHdrData - the associated header
179      * @param dataPtr - the data to parse
180      * @return - the object
181      * @throws java.lang.IllegalArgumentException
182      */
183     public static COPSContext parse(final COPSObjHeaderData objHdrData, final byte[] dataPtr) {
184         short rType = 0;
185         rType |= ((short) dataPtr[4]) << 8;
186         rType |= ((short) dataPtr[5]) & 0xFF;
187
188         short mType = 0;
189         mType |= ((short) dataPtr[6]) << 8;
190         mType |= ((short) dataPtr[7]) & 0xFF;
191
192         return new COPSContext(objHdrData.header, VAL_TO_RTYPE.get((int)rType), mType);
193     }
194
195     /**
196      * The request type
197      */
198     public enum RType {
199         IN_ADMIN, RES_ALLOC, OUT, CONFIG,
200     }
201
202 }
203
204