2 * Copyright (c) 2014, 2015 Cable Television Laboratories, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.pcmm.base.impl;
11 import com.google.common.primitives.Bytes;
12 import org.pcmm.base.IPCMMBaseObject;
13 import org.umu.cops.stack.COPSData;
14 import org.umu.cops.stack.COPSMsgParser;
15 import org.umu.cops.stack.COPSObjectParser;
17 import java.io.IOException;
18 import java.net.Socket;
19 import java.util.ArrayList;
20 import java.util.List;
24 * Abstract implementation of the base class {@link IPCMMBaseObject}
25 * Implementations of this class are used for sending/receiving PCMM data to/from a COPS client
27 public abstract class PCMMBaseObject implements IPCMMBaseObject {
29 protected static final short HEADER_OFFSET = (short) 4;
30 protected static final short PADDING_OFFSET = (short) 4;
32 // The following two attributes denote the type of PCMMBaseObject
33 private final SNum sNum;
34 private final byte sType;
38 * @param sNum - the S-Num
39 * @param sType - the S-Type
41 protected PCMMBaseObject(final SNum sNum, final byte sType) {
42 if (sNum == null) throw new IllegalArgumentException("Invalid or null SNum");
48 public final void writeData(final Socket socket) throws IOException {
49 final byte[] data = getAsBinaryArray();
50 socket.getOutputStream().write(data, 0, data.length);
54 public final byte[] getAsBinaryArray() {
55 final byte[] data = getBytes();
56 final COPSData padding;
57 if ((data.length % PADDING_OFFSET) != 0) {
58 final int padLen = PADDING_OFFSET - (data.length % PADDING_OFFSET);
59 padding = COPSObjectParser.getPadding(padLen);
61 padding = new COPSData();
64 final int payloadSize = data.length + padding.length() + HEADER_OFFSET;
65 final List<Byte> outBytes = new ArrayList<>();
66 outBytes.addAll(Bytes.asList(COPSMsgParser.shortToBytes((short) payloadSize)));
67 outBytes.add(sNum.getValue());
69 outBytes.addAll(Bytes.asList(data));
70 outBytes.addAll(Bytes.asList(padding.getData()));
71 return Bytes.toArray(outBytes);
75 public boolean equals(final Object o) {
79 if (!(o instanceof PCMMBaseObject)) {
83 final PCMMBaseObject that = (PCMMBaseObject) o;
84 return sType == that.sType && sNum == that.sNum;
88 public int hashCode() {
89 int result = sNum.hashCode();
90 result = 31 * result + (int) sType;
95 * Returns the byte array consisting of the data contained within the implementation class
96 * @return - the byte array
98 protected abstract byte[] getBytes();
101 * Enumeration of SNum values that is used by the client to determine which Object type is being sent
104 TRANSACTION_ID((byte) 1),
106 SUBSCRIBER_ID((byte) 3),
109 CLASSIFIERS((byte) 6),
110 TRAFFIC_PROFILE((byte) 7),
111 EVENT_GEN_INFO((byte) 8),
112 VOL_BASED_USAGE_LIMIT((byte) 9),
113 TIME_BASED_USAGE_LIMIT((byte) 10),
114 OPAQUE_DATA((byte) 11),
115 GATE_TIME_INFO((byte) 12),
116 GATE_USAGE_INFO((byte) 13),
117 PCMM_ERROR((byte) 14),
118 GATE_STATE((byte) 15),
119 VERSION_INFO((byte) 16),
121 SYNC_OPTS((byte) 18),
122 MSG_RECEIPT_KEY((byte) 19),
124 SHARED_RES_ID((byte) 21);
126 private final byte value;
132 public byte getValue() {
136 public static SNum valueOf(byte v) {
139 return SNum.TRANSACTION_ID;
143 return SNum.SUBSCRIBER_ID;
147 return SNum.GATE_SPEC;
149 return SNum.CLASSIFIERS;
151 return SNum.TRAFFIC_PROFILE;
153 return SNum.EVENT_GEN_INFO;
155 return SNum.VOL_BASED_USAGE_LIMIT;
157 return SNum.TIME_BASED_USAGE_LIMIT;
159 return SNum.OPAQUE_DATA;
161 return SNum.GATE_TIME_INFO;
163 return SNum.GATE_USAGE_INFO;
165 return SNum.PCMM_ERROR;
167 return SNum.GATE_STATE;
169 return SNum.VERSION_INFO;
173 return SNum.SYNC_OPTS;
175 return SNum.MSG_RECEIPT_KEY;
179 return SNum.SHARED_RES_ID;
181 throw new IllegalArgumentException("not supported value");