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
7 package org.umu.cops.stack;
\r
9 import java.io.IOException;
\r
10 import java.io.OutputStream;
\r
11 import java.net.Socket;
\r
14 * COPS Header (RFC 2748 pag. 6)
\r
16 * Each COPS message consists of the COPS header followed by a number of
\r
20 * +--------------+--------------+--------------+--------------+
\r
21 * |Version| Flags| Op Code | Client-type |
\r
22 * +--------------+--------------+--------------+--------------+
\r
23 * | Message Length |
\r
24 * +--------------+--------------+--------------+--------------+
\r
26 * Global note: //// implies field is reserved, set to 0.
\r
28 * The fields in the header are:
\r
30 * COPS version number. Current version is 1.
\r
33 * Defined flag values (all other flags MUST be set to 0):
\r
34 * 0x1 Solicited Message Flag Bit
\r
35 * This flag is set when the message is solicited by
\r
36 * another COPS message. This flag is NOT to be set
\r
37 * (value=0) unless otherwise specified.
\r
40 * The COPS operations:
\r
42 * 2 = Decision (DEC)
\r
43 * 3 = Report State (RPT)
\r
44 * 4 = Delete Request State (DRQ)
\r
45 * 5 = Synchronize State Req (SSQ)
\r
46 * 6 = Client-Open (OPN)
\r
47 * 7 = Client-Accept (CAT)
\r
48 * 8 = Client-Close (CC)
\r
49 * 9 = Keep-Alive (KA)
\r
50 * 10= Synchronize Complete (SSC)
\r
52 * Client-type: 16 bits
\r
55 * @version COPSHeader.java, v 1.00 2003
\r
58 public class COPSHeader {
\r
60 public final static byte COPS_OP_REQ = 1;
\r
61 public final static byte COPS_OP_DEC = 2;
\r
62 public final static byte COPS_OP_RPT = 3;
\r
63 public final static byte COPS_OP_DRQ = 4;
\r
64 public final static byte COPS_OP_SSQ = 5;
\r
65 public final static byte COPS_OP_OPN = 6;
\r
66 public final static byte COPS_OP_CAT = 7;
\r
67 public final static byte COPS_OP_CC = 8;
\r
68 public final static byte COPS_OP_KA = 9;
\r
69 public final static byte COPS_OP_SSC = 10;
\r
71 public final static byte COPS_FLAG_NULL = 0;
\r
72 public final static byte COPS_FLAG_SOLICITED = 1;
\r
74 private byte _versionNflg;
\r
75 private byte _opCode;
\r
76 private short _cType;
\r
77 private int _msgLength;
\r
79 public COPSHeader() {
\r
80 _versionNflg = 0x10;
\r
86 public COPSHeader(byte opCode, short clientType) {
\r
87 _versionNflg = 0x10;
\r
89 _cType = clientType;
\r
91 if (isAKeepAlive()) _cType = 0;
\r
94 public COPSHeader(byte opCode) {
\r
95 _versionNflg = 0x10;
\r
99 if (isAKeepAlive()) _cType = 0;
\r
103 Parse data and create COPSHeader object
\r
105 public COPSHeader(byte[] buf) {
\r
106 _versionNflg = (byte) buf[0];
\r
107 _opCode = (byte) buf[1];
\r
108 _cType |= ((short) buf[2]) << 8;
\r
109 _cType |= ((short) buf[3]) & 0xFF;
\r
110 _msgLength |= ((short) buf[4]) << 24;
\r
111 _msgLength |= ((short) buf[5]) << 16;
\r
112 _msgLength |= ((short) buf[6]) << 8;
\r
113 _msgLength |= ((short) buf[7]) & 0xFF;
\r
117 * If the operation code corresponds with a message Request, return true
\r
119 * @return a boolean
\r
122 public boolean isARequest() {
\r
123 return (_opCode == COPS_OP_REQ);
\r
127 * If the operation code corresponds with a message Decision, return true
\r
129 * @return a boolean
\r
132 public boolean isADecision() {
\r
133 return (_opCode == COPS_OP_DEC);
\r
137 * If the operation code corresponds with a message Report, return true
\r
139 * @return a boolean
\r
142 public boolean isAReport() {
\r
143 return (_opCode == COPS_OP_RPT);
\r
147 * If the operation code corresponds with a message DeleteRequest, return true
\r
149 * @return a boolean
\r
152 public boolean isADeleteReq() {
\r
153 return (_opCode == COPS_OP_DRQ);
\r
157 * If the operation code corresponds with a message SyncStateReq, return true
\r
159 * @return a boolean
\r
162 public boolean isASyncStateReq() {
\r
163 return (_opCode == COPS_OP_SSQ);
\r
167 * If the operation code corresponds with a message ClientOpen, return true
\r
169 * @return a boolean
\r
172 public boolean isAClientOpen() {
\r
173 return (_opCode == COPS_OP_OPN);
\r
177 * If the operation code corresponds with a message ClientAccept, return true
\r
179 * @return a boolean
\r
182 public boolean isAClientAccept() {
\r
183 return (_opCode == COPS_OP_CAT);
\r
187 * If operation code corresponds with a message ClientClose, return true
\r
189 * @return a boolean
\r
192 public boolean isAClientClose() {
\r
193 return (_opCode == COPS_OP_CC);
\r
197 * If the operation code corresponds with a message KeepAlive, return true
\r
199 * @return a boolean
\r
202 public boolean isAKeepAlive() {
\r
203 return (_opCode == COPS_OP_KA);
\r
207 * If the operation code corresponds with a message SSC, return true
\r
209 * @return a boolean
\r
212 public boolean isASyncComplete() {
\r
213 return (_opCode == COPS_OP_SSC);
\r
217 * Get message length
\r
222 public int getMsgLength() {
\r
227 * Get header length
\r
232 public int getHdrLength() {
\r
233 // return (sizeof(u_int32_t) * 2);
\r
238 * Get Operation Code
\r
243 public byte getOpCode() {
\r
248 * Set the solicitation flag
\r
250 * @param flg a byte
\r
253 public void setFlag(byte flg) {
\r
254 _versionNflg &= 0x10;
\r
255 _versionNflg |= flg;
\r
259 * Returns the flags field
\r
260 * @return aByte Flags field in header
\r
262 public byte getFlags() { //OJO
\r
263 return (byte) (_versionNflg & 0x0f);
\r
267 * Set the client-type
\r
269 * @param cType a short
\r
272 public void setClientType(short cType) {
\r
277 * Set the message length
\r
279 * @param len an int
\r
281 * @throws COPSException
\r
284 public void setMsgLength(int len) throws COPSException {
\r
285 if ((len % 4) != 0)
\r
286 throw new COPSException ("Message is not aligned on 32 bit intervals");
\r
287 _msgLength = len + 8;
\r
296 public short getClientType() {
\r
301 * Always return true
\r
303 * @return a boolean
\r
306 public boolean isCOPSHeader() {
\r
311 * Writes object to given network socket in network byte order
\r
313 * @param id a Socket
\r
315 * @throws IOException
\r
318 public void writeData(Socket id) throws IOException {
\r
319 byte buf[] = new byte[8];
\r
321 buf[0] = (byte) _versionNflg;
\r
322 buf[1] = (byte) _opCode;
\r
323 buf[2] = (byte) (_cType >> 8);
\r
324 buf[3] = (byte) _cType;
\r
325 buf[4] = (byte) (_msgLength >> 24);
\r
326 buf[5] = (byte) (_msgLength >> 16);
\r
327 buf[6] = (byte) (_msgLength >> 8);
\r
328 buf[7] = (byte) _msgLength;
\r
330 COPSUtil.writeData(id, buf, 8);
\r
334 * Get an object textual description
\r
339 public String toString() {
\r
340 String str = new String();
\r
342 str += "**MSG HEADER** \n";
\r
343 str += "Version: " + (_versionNflg >> 4) + "\n";
\r
344 str += "Flags: " + (_versionNflg & 0x01) + "\n";
\r
345 str += "OpCode: " + _opCode + "\n";
\r
346 str += "Client-type: " + _cType + "\n";
\r
347 str += "Message-length(bytes): " + _msgLength + "\n";
\r
352 * Write an object textual description in the output stream
\r
354 * @param os an OutputStream
\r
356 * @throws IOException
\r
359 public void dump(OutputStream os) throws IOException {
\r
360 os.write(new String("**MSG HEADER**" + "\n").getBytes());
\r
361 os.write(new String("Version: " + (_versionNflg >> 4) + "\n").getBytes());
\r
362 os.write(new String("Flags: " + (_versionNflg & 0x01) + "\n").getBytes());
\r
363 os.write(new String("OpCode: " + _opCode + "\n").getBytes());
\r
364 os.write(new String("Client-type: " + _cType + "\n").getBytes());
\r
365 os.write(new String("Message-length(bytes): " + _msgLength + "\n").getBytes());
\r