Add missing license headers to packetcable-driver messages
[packetcable.git] / packetcable-driver / src / main / java / org / pcmm / messages / impl / MessageFactory.java
1 /*
2  * Copyright (c) 2014, 2015 Cable Television Laboratories, Inc. and others.  All rights reserved.
3  *
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
7  */
8
9 package org.pcmm.messages.impl;
10
11 import org.pcmm.messages.IMessage.MessageProperties;
12 import org.pcmm.messages.IMessageFactory;
13 import org.pcmm.objects.MMVersionInfo;
14 import org.pcmm.rcd.ICMTS;
15 import org.pcmm.rcd.IPCMMClient;
16 import org.slf4j.Logger;
17 import org.slf4j.LoggerFactory;
18 import org.umu.cops.stack.*;
19 import org.umu.cops.stack.COPSClientSI.CSIType;
20 import org.umu.cops.stack.COPSContext.RType;
21 import org.umu.cops.stack.COPSDecision.Command;
22 import org.umu.cops.stack.COPSDecision.DecisionFlag;
23 import org.umu.cops.stack.COPSError.ErrorTypes;
24 import org.umu.cops.stack.COPSHeader.OPCode;
25 import org.umu.cops.stack.COPSObjHeader.CType;
26
27 import java.net.InetAddress;
28 import java.util.*;
29
30 /**
31  *
32  *
33  */
34 public class MessageFactory implements IMessageFactory {
35
36     /** Default keep-alive timer value (secs) */
37     public static final short KA_TIMER_VALUE = 30;
38     /** Default accounting timer value (secs) */
39     public static final short ACCT_TIMER_VALUE = 0;
40
41     private static final Logger logger = LoggerFactory.getLogger(MessageFactory.class);
42
43     private static final MessageFactory instance = new MessageFactory();
44
45     private MessageFactory() {
46     }
47
48     public static MessageFactory getInstance() {
49         return instance;
50     }
51
52     /*
53      * (non-Javadoc)
54      *
55      * @see pcmm.messages.IMessageFactory#create(pcmm.messages.MessageType)
56      */
57     public COPSMsg create(final OPCode messageType) {
58         return create(messageType, new Properties());
59     }
60
61     /*
62      * (non-Javadoc)
63      *
64      * @see org.pcmm.messages.IMessageFactory#create(org.pcmm.messages.IMessage.
65      * MessageType, java.util.Properties)
66      */
67     public COPSMsg create(final OPCode messageType, final Properties properties) {
68         logger.info("Creating message of type - " + messageType);
69         // return new PCMMMessage(messageType, content);
70         switch (messageType) {
71             case OPN:
72                 return createOPNMessage(properties);
73             case REQ:
74                 return createREQMessage(properties);
75             case CAT:
76                 return createCATMessage(properties);
77             case CC:
78                 return createCCMessage(properties);
79             case DEC:
80                 return createDECMessage(properties);
81             case DRQ:
82                 break;
83             case KA:
84                 return createKAMessage(properties);
85             case RPT:
86                 break;
87             case SSC:
88                 break;
89             case SSQ:
90                 break;
91         }
92         return null;
93     }
94
95     /**
96      *
97      * @param prop - the properties
98      * @return - the message
99      */
100     protected COPSMsg createDECMessage(final Properties prop) {
101
102         // ===common part between all gate control messages
103         //        final COPSHeader hdr = new COPSHeader(OPCode.DEC, IPCMMClient.CLIENT_TYPE);
104         // handle
105         // context
106         // decision
107         // TODO - the old command and flag codes are not congruent with the ones described in COPSDecision
108         // TODO - what is the correct client type to be using here???
109 /*
110         if (prop.get(MessageProperties.DECISION_CMD_CODE) != null)
111             decision.setCmdCode((byte) prop.get(MessageProperties.DECISION_CMD_CODE));
112         if (prop.get(MessageProperties.DECISION_FLAG) != null)
113             decision.setFlags((short) prop.get(MessageProperties.DECISION_FLAG));
114 */
115
116         final COPSData data;
117         if (prop.get(MessageProperties.GATE_CONTROL) != null)
118             data = (COPSData) prop.get(MessageProperties.GATE_CONTROL);
119         else
120             data = null;
121
122         // TODO - Need to determine is SIGNALED is the correct default CSIType
123         // Decided that CSI object is not what should be encapsulated by the COPSDecisionMsg, therefore placing
124         // data into the COPSDecision object located in the decisionMap
125         //        final COPSClientSI si = new COPSClientSI(CSIType.SIGNALED, data);
126
127         final COPSHandle handle;
128         if (prop.get(MessageProperties.CLIENT_HANDLE) != null) {
129             handle = new COPSHandle(new COPSData((String) prop.get(MessageProperties.CLIENT_HANDLE)));
130         }
131         else {
132             // TODO - This smells wrong to have a null handle ID
133             handle = new COPSHandle(null);
134         }
135         final Set<COPSDecision> decisionSet = new HashSet<>();
136         decisionSet.add(new COPSDecision(CType.DEF, Command.NULL, DecisionFlag.NA, data));
137         final Map<COPSContext, Set<COPSDecision>> decisionMap = new HashMap<>();
138         decisionMap.put(new COPSContext(RType.CONFIG, (short)0), decisionSet);
139
140         final COPSDecisionMsg msg = new COPSDecisionMsg(IPCMMClient.CLIENT_TYPE, handle, decisionMap, null, null);
141
142         // TODO - determine why this block has been commented out
143         // try {
144         // msg.dump(System.out);
145         // } catch (IOException unae) {
146         // }
147
148         return msg;
149     }
150
151     /**
152      * creates a Client-Open message.
153      *
154      * @param prop
155      *            properties
156      * @return COPS message
157      */
158     protected COPSMsg createOPNMessage(final Properties prop) {
159         // version infor object
160         short majorVersion = MMVersionInfo.DEFAULT_MAJOR_VERSION_INFO;
161         short minorVersion = MMVersionInfo.DEFAULT_MINOR_VERSION_INFO;
162         if (prop.get(MessageProperties.MM_MAJOR_VERSION_INFO) != null)
163             majorVersion = (Short) prop.get(MessageProperties.MM_MAJOR_VERSION_INFO);
164         if (prop.get(MessageProperties.MM_MINOR_VERSION_INFO) != null)
165             minorVersion = (Short) prop.get(MessageProperties.MM_MINOR_VERSION_INFO);
166         // Mandatory MM version.
167         byte[] versionInfo = new MMVersionInfo(majorVersion, minorVersion).getAsBinaryArray();
168         final COPSClientSI clientSI = new COPSClientSI(CSIType.SIGNALED, new COPSData(versionInfo, 0, versionInfo.length));
169         try {
170             final COPSData d;
171             if (prop.get(MessageProperties.PEP_ID) != null)
172                 d = new COPSData((String) prop.get(MessageProperties.PEP_ID));
173             else
174                 d = new COPSData(InetAddress.getLocalHost().getHostName());
175             final COPSPepId pepId = new COPSPepId(d);
176             return new COPSClientOpenMsg(IPCMMClient.CLIENT_TYPE, pepId, clientSI, null, null);
177         } catch (Exception e) {
178             logger.error("Error creating OPN message", e);
179         }
180
181         // TODO - this probably should not return null and throw an exception instead
182         return null;
183     }
184
185     /**
186      * creates a Client-Accept message.
187      * @param prop - properties
188      * @return COPS message
189      */
190     protected COPSMsg createCATMessage(final Properties prop) {
191         // TODO - determine what the first constructor parameter really should be???
192         final COPSKATimer katimer;
193         if (prop.get(MessageProperties.KA_TIMER) != null)
194             katimer = new COPSKATimer((short)prop.get(MessageProperties.KA_TIMER));
195         else
196             katimer = new COPSKATimer(KA_TIMER_VALUE);
197
198         // TODO - determine what the first constructor parameter really should be???
199         final COPSAcctTimer acctTimer;
200         if (prop.get(MessageProperties.ACCEPT_TIMER) != null)
201             acctTimer = new COPSAcctTimer((short) prop.get(MessageProperties.ACCEPT_TIMER));
202         else
203             acctTimer = new COPSAcctTimer(ACCT_TIMER_VALUE);
204
205         if (acctTimer.getTimerVal() != 0)
206             return new COPSClientAcceptMsg(IPCMMClient.CLIENT_TYPE, katimer, acctTimer, null);
207         else return new COPSClientAcceptMsg(IPCMMClient.CLIENT_TYPE, katimer, null, null);
208     }
209
210     /**
211      * creates a Client-Close message.
212      *
213      * @param prop
214      *            properties
215      * @return COPS message
216      */
217     protected COPSMsg createCCMessage(final Properties prop) {
218         final COPSError err;
219         if (prop.get(MessageProperties.ERR_MESSAGE) != null) {
220             ErrorTypes code = ErrorTypes.NA;
221             final ErrorTypes error = (ErrorTypes) prop.get(MessageProperties.ERR_MESSAGE);
222             if (prop.get(MessageProperties.ERR_MESSAGE_SUB_CODE) != null)
223                 code = (ErrorTypes) prop.get(MessageProperties.ERR_MESSAGE_SUB_CODE);
224             err = new COPSError(COPSError.ERROR_CODE_TO_TYPE.get(error.ordinal()),
225                     COPSError.ERROR_CODE_TO_TYPE.get(code.ordinal()));
226         } else
227             err = new COPSError(ErrorTypes.UNKNOWN, ErrorTypes.NA);
228
229         return new COPSClientCloseMsg(IPCMMClient.CLIENT_TYPE, err, null, null);
230     }
231
232     /**
233      * creates a Request message
234      *
235      * @param prop
236      *            properties
237      * @return Request message
238      */
239     protected COPSMsg createREQMessage(final Properties prop) {
240         final short rType;
241         if (prop.get(MessageProperties.R_TYPE) != null)
242             rType = (Short) prop.get(MessageProperties.R_TYPE);
243         else rType = ICMTS.DEFAULT_R_TYPE;
244
245         final short mType;
246         if (prop.get(MessageProperties.M_TYPE) != null)
247             mType = (Short) prop.get(MessageProperties.M_TYPE);
248         else mType = ICMTS.DEFAULT_M_TYPE;
249
250         final COPSContext copsContext = new COPSContext(COPSContext.VAL_TO_RTYPE.get((int)rType), mType);
251         final COPSHandle copsHandle;
252         if (prop.get(MessageProperties.CLIENT_HANDLE) != null)
253             copsHandle = new COPSHandle(new COPSData((String) prop.get(MessageProperties.CLIENT_HANDLE)));
254         else
255             // just a random handle
256             copsHandle = new COPSHandle(new COPSData("" + Math.random() * 82730));
257
258         return new COPSReqMsg(IPCMMClient.CLIENT_TYPE, copsHandle, copsContext, null, null, null, null, null);
259     }
260
261     /**
262      * creates a Keep-Alive message.
263      *
264      * @param prop
265      *            properties
266      * @return COPS message
267      * TODO - Why is there a timer being instantiated but never used?
268      */
269     protected COPSMsg createKAMessage(final Properties prop) {
270         // TODO - determine why this isn't really doing anything
271         return new COPSKAMsg(null);
272 /*
273         final COPSKATimer timer;
274         if (prop.get(MessageProperties.KA_TIMER) != null)
275             timer = new COPSKATimer((short)0, (Short) prop.get(MessageProperties.KA_TIMER));
276         else
277             timer = new COPSKATimer();
278 */
279     }
280 }