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