9d91d76286801d8f58b27b8522ba697c67d68f25
[packetcable.git] / packetcable-driver / src / main / java / org / umu / cops / stack / COPSHandle.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.ArrayList;
16 import java.util.List;
17
18 /**
19  * COPS Handle Object (RFC 2748 pag. 9)
20  *
21  *   The Handle Object encapsulates a unique value that identifies an
22  *   installed state. This identification is used by most COPS operations.
23  *
24  *           C-Num = 1
25  *
26  *           C-Type = 1, Client Handle.
27  *
28  *   Variable-length field, no implied format other than it is unique from
29  *   other client handles from the same PEP (a.k.a. COPS TCP connection)
30  *   for a particular client-type. It is always initially chosen by the
31  *   PEP and then deleted by the PEP when no longer applicable. The client
32  *   handle is used to refer to a request state initiated by a particular
33  *   PEP and installed at the PDP for a client-type. A PEP will specify a
34  *   client handle in its Request messages, Report messages and Delete
35  *   messages sent to the PDP. In all cases, <b>the client handle is used to
36  *   uniquely identify a particular PEP's request for a client-type</b>.
37  *
38  *   The client handle value is set by the PEP and is opaque to the PDP.
39  *   The PDP simply performs a byte-wise comparison on the value in this
40  *   object with respect to the handle object values of other currently
41  *   installed requests.
42  *
43  */
44 public class COPSHandle extends COPSObjBase {
45
46     /**
47      * The payload data
48      */
49     private final COPSData _data;
50
51     /**
52      * Bytes to add to outbound payload to ensure the length is divisible by 4 bytes
53      */
54     private final COPSData _padding;
55
56     /**
57      * Constructor generally used for sending messages
58      * @param id - the identifier (must not be null)
59      * @throws java.lang.IllegalArgumentException when the id parameter is null
60      */
61     public COPSHandle(final COPSData id) {
62         this(new COPSObjHeader(CNum.HANDLE, CType.DEF), id);
63     }
64
65     /**
66      * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the
67      * COPSObjHeader information is known
68      * @param objHdr - the object header
69      * @param data - the ID
70      * @throws java.lang.IllegalArgumentException
71      */
72     protected COPSHandle(final COPSObjHeader objHdr, final COPSData data) {
73         super(objHdr);
74         if (!objHdr.getCNum().equals(CNum.HANDLE))
75             throw new IllegalArgumentException("CNum on header must be of type HANDLE");
76         if (!objHdr.getCType().equals(CType.DEF))
77             throw new IllegalArgumentException("Invalid CType value. Must be " + CType.DEF);
78         if (data == null) throw new IllegalArgumentException("COPSData must not be null");
79
80         _data = data;
81
82         if ((_data.length() % 4) != 0) {
83             final int padLen = 4 - (_data.length() % 4);
84             _padding = COPSObjectParser.getPadding(padLen);
85         } else {
86             _padding = new COPSData();
87         }
88     }
89
90     @Override
91     public int getDataLength() {
92         return _data.length() + _padding.length();
93     }
94
95     /**
96      * Get handle value
97      * @return   a COPSData
98      */
99     public COPSData getId() {
100         return _data;
101     }
102
103     @Override
104     protected void writeBody(final Socket socket) throws IOException {
105         COPSUtil.writeData(socket, _data.getData(), _data.length());
106         if (_padding.length() != 0) COPSUtil.writeData(socket, _padding.getData(), _padding.length());
107     }
108
109     @Override
110     public void dumpBody(final OutputStream os) throws IOException {
111         os.write(("client-handle: " + _data.str() + "\n").getBytes());
112     }
113
114     @Override
115     public boolean equals(final Object o) {
116         if (this == o) {
117             return true;
118         }
119         if (!(o instanceof COPSHandle)) {
120             return false;
121         }
122         if (!super.equals(o)) {
123             return false;
124         }
125
126         final COPSHandle that = (COPSHandle) o;
127
128         return _data.equals(that._data) && _padding.equals(that._padding) ||
129                 COPSUtil.copsDataPaddingEquals(this._data, this._padding, that._data, that._padding);
130     }
131
132     @Override
133     public int hashCode() {
134         int result = super.hashCode();
135         List<Byte> allBytes = new ArrayList<>();
136         for (final byte val : _data.getData()) {
137             allBytes.add(val);
138         }
139         for (final byte val : _padding.getData()) {
140             allBytes.add(val);
141         }
142         result = 31 * allBytes.hashCode();
143         return result;
144     }
145
146     /**
147      * Parses bytes to return a COPSHandle object
148      * @param objHdrData - the associated header
149      * @param dataPtr - the data to parse
150      * @return - the object
151      * @throws java.lang.IllegalArgumentException
152      */
153     public static COPSHandle parse(final COPSObjHeaderData objHdrData, final byte[] dataPtr) {
154         if (dataPtr == null || dataPtr.length < 5)
155             throw new IllegalArgumentException("Data cannot be null or fewer than 5 bytes");
156
157         //Get the length of data following the obj header
158         final COPSData id = new COPSData(dataPtr, 4, objHdrData.msgByteCount - objHdrData.header.getHdrLength());
159         return new COPSHandle(objHdrData.header, id);
160     }
161
162 }
163