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