Start of the COPS message refactoring to make all of these classes more semantic...
[packetcable.git] / packetcable-driver / src / main / java / org / umu / cops / stack / COPSSyncStateMsg.java
1 /*\r
2  * Copyright (c) 2003 University of Murcia.  All rights reserved.\r
3  * --------------------------------------------------------------\r
4  * For more information, please see <http://www.umu.euro6ix.org/>.\r
5  */\r
6 \r
7 package org.umu.cops.stack;\r
8 \r
9 import java.io.IOException;\r
10 import java.io.OutputStream;\r
11 import java.net.Socket;\r
12 \r
13 /**\r
14  * COPS Sync State Message (RFC 2748 pag. 26 and pag. 29\r
15  *\r
16  *   The format of the Synchronize State Query message is as follows:\r
17  *\r
18  *              <Synchronize State> ::= <Common Header>\r
19  *                                      [<Client Handle>]\r
20  *                                      [<Integrity>]\r
21  *\r
22  *   This message indicates that the remote PDP wishes the client (which\r
23  *   appears in the common header) to re-send its state. If the optional\r
24  *   Client Handle is present, only the state associated with this handle\r
25  *   is synchronized. If the PEP does not recognize the requested handle,\r
26  *   it MUST immediately send a DRQ message to the PDP for the handle that\r
27  *   was specified in the SSQ message. If no handle is specified in the\r
28  *    SSQ message, all the active client state MUST be synchronized with\r
29  *   the PDP.\r
30  *\r
31  *   The client performs state synchronization by re-issuing request\r
32  *   queries of the specified client-type for the existing state in the\r
33  *   PEP. When synchronization is complete, the PEP MUST issue a\r
34  *   synchronize state complete message to the PDP.\r
35  *\r
36  *         <Synchronize State Complete>  ::= <Common Header>\r
37  *                                           [<Client Handle>]\r
38  *                                           [<Integrity>]\r
39  *\r
40  *   The Client Handle object only needs to be included if the corresponding\r
41  *   Synchronize State Message originally referenced a specific handle.\r
42  *\r
43  * @version COPSSyncStateMsg.java, v 1.00 2003\r
44  *\r
45  */\r
46 public class COPSSyncStateMsg extends COPSMsg {\r
47 \r
48     /* COPSHeader coming from base class */\r
49     private COPSHandle  _clientHandle;\r
50     private COPSIntegrity  _integrity;\r
51 \r
52     public COPSSyncStateMsg() {\r
53         _clientHandle = null;\r
54         _integrity = null;\r
55     }\r
56 \r
57     /**\r
58           Parse data and create COPSSyncStateMsg object\r
59      */\r
60     protected COPSSyncStateMsg(byte[] data) throws COPSException  {\r
61         _clientHandle = null;\r
62         _integrity = null;\r
63         parse(data);\r
64     }\r
65 \r
66     /**\r
67      * Checks the sanity of COPS message and throw an\r
68      * COPSException when data is bad.\r
69      */\r
70     public void checkSanity() throws COPSException {\r
71         if (_hdr == null) {\r
72             throw new COPSException("Bad message format");\r
73         }\r
74     }\r
75 \r
76     /**\r
77      * Add message header\r
78      *\r
79      * @param    hdr                 a  COPSHeader\r
80      *\r
81      * @throws   COPSException\r
82      *\r
83      */\r
84     public void add (COPSHeader hdr) throws COPSException {\r
85         if (hdr == null)\r
86             throw new COPSException ("Null Header");\r
87         if ((hdr.getOpCode() != COPSHeader.COPS_OP_SSC) &&\r
88                 (hdr.getOpCode() != COPSHeader.COPS_OP_SSQ))\r
89             throw new COPSException ("Error Header (no COPS_OP_SSX)");\r
90         _hdr = hdr;\r
91         setMsgLength();\r
92     }\r
93 \r
94     /**\r
95      * Add client handle to the message\r
96      *\r
97      * @param    handle              a  COPSHandle\r
98      *\r
99      * @throws   COPSException\r
100      *\r
101      */\r
102     public void add (COPSHandle handle) throws COPSException {\r
103         if (handle == null)\r
104             throw new COPSException ("Null Handle");\r
105 \r
106         //Message integrity object should be the very last one\r
107         //If it is already added\r
108         if (_integrity != null)\r
109             throw new COPSException ("No null Handle");\r
110 \r
111         _clientHandle = handle;\r
112         setMsgLength();\r
113     }\r
114 \r
115     /**\r
116      * Add integrity object\r
117      *\r
118      * @param    integrity           a  COPSIntegrity\r
119      *\r
120      * @throws   COPSException\r
121      *\r
122      */\r
123     public void add (COPSIntegrity integrity) throws COPSException {\r
124         if (integrity == null)\r
125             throw new COPSException ("Null Integrity");\r
126         if (!integrity.isMessageIntegrity())\r
127             throw new COPSException ("Error Integrity");\r
128         _integrity = integrity;\r
129         setMsgLength();\r
130     }\r
131 \r
132     /**\r
133      * If the optional Client Handle is present, only the state associated\r
134       * with this handle is synchronized. If no handle is specified in the\r
135       * SSQ message, all the active client state MUST be synchronized with\r
136       * the PDP.\r
137      *\r
138      * @return   a boolean\r
139      *\r
140      */\r
141     public boolean hasClientHandle() {\r
142         return (_clientHandle != null);\r
143     }\r
144 \r
145     /**\r
146      * Get client Handle\r
147      *\r
148      * @return   a COPSHandle\r
149      *\r
150      */\r
151     public COPSHandle getClientHandle() {\r
152         return _clientHandle;\r
153     }\r
154 \r
155     /**\r
156      * Returns true if it has integrity object\r
157      *\r
158      * @return   a boolean\r
159      *\r
160      */\r
161     public boolean hasIntegrity() {\r
162         return (_integrity != null);\r
163     }\r
164 \r
165     /**\r
166      * Get Integrity. Should check hasIntegrity() before calling\r
167      *\r
168      * @return   a COPSIntegrity\r
169      *\r
170      */\r
171     public COPSIntegrity getIntegrity() {\r
172         return (_integrity);\r
173     }\r
174 \r
175     /**\r
176      * Writes data to given socket\r
177      *\r
178      * @param    id                  a  Socket\r
179      *\r
180      * @throws   IOException\r
181      *\r
182      */\r
183     public void writeData(Socket id) throws IOException {\r
184         // checkSanity();\r
185         if (_hdr != null) _hdr.writeData(id);\r
186         if (_clientHandle != null) _clientHandle.writeData(id);\r
187         if (_integrity != null) _integrity.writeData(id);\r
188 \r
189     }\r
190 \r
191     /**\r
192      * Parse data\r
193      *\r
194      * @param    data                a  byte[]\r
195      *\r
196      * @throws   COPSException\r
197      *\r
198      */\r
199     protected void parse(byte[] data) throws COPSException {\r
200         super.parseHeader(data);\r
201 \r
202         while (_dataStart < _dataLength) {\r
203             byte[] buf = new byte[data.length - _dataStart];\r
204             System.arraycopy(data,_dataStart,buf,0,data.length - _dataStart);\r
205 \r
206             COPSObjHeader objHdr = COPSObjHeader.parse(buf);\r
207             switch (objHdr.getCNum()) {\r
208                 case HANDLE:\r
209                     _clientHandle = new COPSHandle(buf);\r
210                     _dataStart += _clientHandle.getDataLength();\r
211                     break;\r
212                 case MSG_INTEGRITY:\r
213                     _integrity = new COPSIntegrity(buf);\r
214                     _dataStart += _integrity.getDataLength();\r
215                     break;\r
216                 default:\r
217                     throw new COPSException("Bad Message format, unknown object type");\r
218             }\r
219         }\r
220         checkSanity();\r
221     }\r
222 \r
223     /**\r
224      * Parse data\r
225      *\r
226      * @param    hdr                 a  COPSHeader\r
227      * @param    data                a  byte[]\r
228      *\r
229      * @throws   COPSException\r
230      *\r
231      */\r
232     protected void parse(COPSHeader hdr, byte[] data) throws COPSException {\r
233 \r
234         if ((hdr.getOpCode() != COPSHeader.COPS_OP_SSC) &&\r
235                 (hdr.getOpCode() != COPSHeader.COPS_OP_SSQ))\r
236             throw new COPSException ("Error Header (no COPS_OP_SSX)");\r
237 \r
238         _hdr = hdr;\r
239         parse(data);\r
240         setMsgLength();\r
241     }\r
242 \r
243     /**\r
244      * Set the message length, base on the set of objects it contains\r
245      *\r
246      * @throws   COPSException\r
247      *\r
248      */\r
249     protected void setMsgLength() throws COPSException {\r
250         short len = 0;\r
251         if (_clientHandle != null) len += _clientHandle.getDataLength();\r
252         if (_integrity != null) len += _integrity.getDataLength();\r
253         _hdr.setMsgLength(len);\r
254     }\r
255 \r
256     /**\r
257      * Write an object textual description in the output stream\r
258      *\r
259      * @param    os                  an OutputStream\r
260      *\r
261      * @throws   IOException\r
262      *\r
263      */\r
264     public void dump(OutputStream os) throws IOException {\r
265         _hdr.dump(os);\r
266 \r
267         if (_clientHandle != null)\r
268             _clientHandle.dump(os);\r
269 \r
270         if (_integrity != null) {\r
271             _integrity.dump(os);\r
272         }\r
273     }\r
274 }\r
275 \r
276 \r
277 \r