09ae644047cf0700e7439d4ad25d0fba468998d7
[packetcable.git] / packetcable-driver / src / main / java / org / pcmm / rcd / impl / CMTS.java
1 /**
2  @header@
3  */
4 package org.pcmm.rcd.impl;
5
6 import org.pcmm.gates.IPCMMGate;
7 import org.pcmm.gates.ITransactionID;
8 import org.pcmm.gates.impl.PCMMGateReq;
9 import org.pcmm.messages.impl.MessageFactory;
10 import org.pcmm.rcd.ICMTS;
11 import org.umu.cops.COPSStateMan;
12 import org.umu.cops.prpep.COPSPepConnection;
13 import org.umu.cops.prpep.COPSPepDataProcess;
14 import org.umu.cops.prpep.COPSPepException;
15 import org.umu.cops.prpep.COPSPepReqStateMan;
16 import org.umu.cops.stack.*;
17 import org.umu.cops.stack.COPSHeader.OPCode;
18
19 import java.net.Socket;
20 import java.util.*;
21 import java.util.concurrent.Callable;
22
23 /**
24  * This class starts a mock CMTS that can be used for testing.
25  */
26 public class CMTS extends AbstractPCMMServer implements ICMTS {
27
28         /**
29          * Constructor for having the server port automatically assigned
30          * Call getPort() after startServer() is called to determine the port number of the server
31          */
32         public CMTS() {
33                 this(0);
34         }
35
36         /**
37          * Constructor for starting the server to a pre-defined port number
38          * @param port - the port number on which to start the server.
39          */
40         public CMTS(final int port) {
41                 super(port);
42         }
43
44         @Override
45         protected IPCMMClientHandler getPCMMClientHandler(final Socket socket) {
46
47                 return new AbstractPCMMClientHandler(socket) {
48
49                         private COPSHandle handle;
50
51                         public void run() {
52                                 try {
53                                         // send OPN message
54                                         // set the major version info and minor version info to
55                                         // default (5,0)
56                                         logger.info("Send OPN message to the PS");
57                                         sendRequest(MessageFactory.getInstance().create(OPCode.OPN, new Properties()));
58                                         // wait for CAT
59                                         COPSMsg recvMsg = readMessage();
60
61                                         if (recvMsg.getHeader().getOpCode().equals(OPCode.CC)) {
62                                                 COPSClientCloseMsg cMsg = (COPSClientCloseMsg) recvMsg;
63                                                 logger.info("PS requested Client-Close" + cMsg.getError().getDescription());
64                                                 // send a CC message and close the socket
65                                                 disconnect();
66                                                 return;
67                                         }
68                                         if (recvMsg.getHeader().getOpCode().equals(OPCode.CAT)) {
69                                                 logger.info("received Client-Accept from PS");
70                                                 COPSClientAcceptMsg cMsg = (COPSClientAcceptMsg) recvMsg;
71                                                 // Support
72                                                 if (cMsg.getIntegrity() != null) {
73                                                         throw new COPSPepException("Unsupported object (Integrity)");
74                                                 }
75
76                                                 // Mandatory KATimer
77                                                 COPSKATimer kt = cMsg.getKATimer();
78                                                 if (kt == null)
79                                                         throw new COPSPepException("Mandatory COPS object missing (KA Timer)");
80                                                 short kaTimeVal = kt.getTimerVal();
81
82                                                 // ACTimer
83                                                 COPSAcctTimer at = cMsg.getAcctTimer();
84                                                 short acctTimer = 0;
85                                                 if (at != null)
86                                                         acctTimer = at.getTimerVal();
87
88                                                 logger.info("Send a REQ message to the PS");
89                                                 {
90                                                         Properties prop = new Properties();
91                                                         COPSMsg reqMsg = MessageFactory.getInstance().create(OPCode.REQ, prop);
92                                                         handle = ((COPSReqMsg) reqMsg).getClientHandle();
93                                                         sendRequest(reqMsg);
94                                                 }
95                                                 // Create the connection manager
96                                                 final PCMMCmtsConnection conn = new PCMMCmtsConnection(CLIENT_TYPE, socket);
97                                                 // pcmm specific handler
98                                                 // conn.addReqStateMgr(handle, new
99                                                 // PCMMPSReqStateMan(CLIENT_TYPE, handle));
100                                                 conn.addRequestState(handle, new CmtsDataProcessor());
101                                                 conn.setKaTimer(kaTimeVal);
102                                                 conn.setAcctTimer(acctTimer);
103                                                 logger.info(getClass().getName() + " Thread(conn).start");
104                                                 new Thread(conn).start();
105                                         } else {
106                                                 // messages of other types are not expected
107                                                 throw new COPSPepException("Message not expected. Closing connection for " + socket.toString());
108                                         }
109                                 } catch (Exception e) {
110                                         logger.error(e.getMessage());
111                                 }
112                         }
113
114                         @Override
115                         public void task(Callable<?> c) {
116                                 // TODO Auto-generated method stub
117
118                         }
119
120                         @Override
121                         public void shouldWait(int t) {
122                                 // TODO Auto-generated method stub
123
124                         }
125
126                         @Override
127                         public void done() {
128                                 // TODO Auto-generated method stub
129
130                         }
131
132                 };
133         }
134
135         class PCMMCmtsConnection extends COPSPepConnection {
136
137                 public PCMMCmtsConnection(final short clientType, final Socket sock) {
138                         super(clientType, sock);
139                 }
140
141                 public COPSPepReqStateMan addRequestState(final COPSHandle clientHandle, final COPSPepDataProcess process)
142                                 throws COPSException {
143                         return super.addRequestState(clientHandle, process);
144                 }
145         }
146
147         class PCMMPSReqStateMan extends COPSPepReqStateMan {
148
149                 public PCMMPSReqStateMan(final short clientType, final COPSHandle clientHandle) {
150                         super(clientType, clientHandle, new CmtsDataProcessor());
151                 }
152
153                 @Override
154                 protected void processDecision(final COPSDecisionMsg dMsg, final Socket socket) throws COPSPepException {
155             final Map<String, String> removeDecs = new HashMap<>();
156                         final Map<String, String> installDecs = new HashMap<>();
157                         final Map<String, String> errorDecs = new HashMap<>();
158
159                         for (final Set<COPSDecision> copsDecisions : dMsg.getDecisions().values()) {
160                                 final COPSDecision cmddecision = copsDecisions.iterator().next();
161
162                                 // cmddecision --> we must check whether it is an error!
163                 String prid = "";
164                 switch (cmddecision.getCommand()) {
165                     case INSTALL:
166                         for (final COPSDecision decision : copsDecisions) {
167                                                         final COPSPrObjBase obj = new COPSPrObjBase(decision.getData().getData());
168                             switch (obj.getSNum()) {
169                                 // TODO when there is install request only the PR_PRID
170                                 // is git but the ClientSI object containing the PR_EPD
171                                 // is null??? this is why the tests fail and so I set
172                                 // the assertion to NOT true....
173                                 case COPSPrObjBase.PR_PRID:
174                                     prid = obj.getData().str();
175                                     break;
176                                 case COPSPrObjBase.PR_EPD:
177                                     installDecs.put(prid, obj.getData().str());
178                                     break;
179                                 default:
180                                     break;
181                             }
182                         }
183                     case REMOVE:
184                         for (final COPSDecision decision : copsDecisions) {
185                                                         final COPSPrObjBase obj = new COPSPrObjBase(decision.getData().getData());
186                             switch (obj.getSNum()) {
187                                 // TODO when there is install request only the PR_PRID
188                                 // is git but the ClientSI object containing the PR_EPD
189                                 // is null??? this is why the tests fail and so I set
190                                 // the assertion to NOT true....
191                                 case COPSPrObjBase.PR_PRID:
192                                     prid = obj.getData().str();
193                                     break;
194                                 case COPSPrObjBase.PR_EPD:
195                                     removeDecs.put(prid, obj.getData().str());
196                                     break;
197                                 default:
198                                     break;
199                             }
200                         }
201                 }
202             }
203
204                         if (_process != null) {
205                                 // ** Apply decisions to the configuration
206                                 _process.setDecisions(this, removeDecs, installDecs, errorDecs);
207                                 _status = Status.ST_DECS;
208                                 if (_process.isFailReport(this)) {
209                                         // COPSDebug.out(getClass().getName(),"Sending FAIL Report\n");
210                                         _sender.sendFailReport(_process.getReportData(this));
211                                 } else {
212                                         // COPSDebug.out(getClass().getName(),"Sending SUCCESS Report\n");
213                                         _sender.sendSuccessReport(_process.getReportData(this));
214                                 }
215                                 _status = Status.ST_REPORT;
216                         }
217                 }
218         }
219
220         class CmtsDataProcessor implements COPSPepDataProcess {
221
222                 private Map<String, String> removeDecs;
223                 private Map<String, String> installDecs;
224                 private Map<String, String> errorDecs;
225                 private COPSPepReqStateMan stateManager;
226
227                 public CmtsDataProcessor() {
228                         setRemoveDecs(new HashMap<String, String>());
229                         setInstallDecs(new HashMap<String, String>());
230                         setErrorDecs(new HashMap<String, String>());
231                 }
232
233                 @Override
234                 public void setDecisions(final COPSPepReqStateMan man, final Map<String, String> removeDecs,
235                                  final Map<String, String> installDecs, final Map<String, String> errorDecs) {
236                         setRemoveDecs(removeDecs);
237                         setInstallDecs(installDecs);
238                         setErrorDecs(errorDecs);
239                         setStateManager(man);
240                 }
241
242                 @Override
243                 public boolean isFailReport(final COPSPepReqStateMan man) {
244                         return (errorDecs != null && errorDecs.size() > 0);
245                 }
246
247                 @Override
248                 public Map<String, String> getReportData(final COPSPepReqStateMan man) {
249                         if (isFailReport(man)) {
250                                 return errorDecs;
251                         } else {
252                                 final Map<String, String> siDataHashTable = new HashMap<>();
253                                 if (installDecs.size() > 0) {
254                                         String data = "";
255                                         for (String k : installDecs.keySet()) {
256                                                 data = installDecs.get(k);
257                                                 break;
258                                         }
259                                         final ITransactionID transactionID = new PCMMGateReq(new COPSData(data).getData()).getTransactionID();
260                                         final IPCMMGate responseGate = new PCMMGateReq();
261                                         responseGate.setTransactionID(transactionID);
262
263                     // TODO FIXME - Why is the key always null??? What value should be used here???
264                     final String key = null;
265                                         siDataHashTable.put(key, new String(responseGate.getData()));
266                                 }
267                                 return siDataHashTable;
268                         }
269                 }
270
271                 @Override
272                 public Map<String, String> getClientData(COPSPepReqStateMan man) {
273                         // TODO Auto-generated method stub
274                         return new HashMap<>();
275                 }
276
277                 @Override
278                 public Map<String, String> getAcctData(COPSPepReqStateMan man) {
279                         // TODO Auto-generated method stub
280                         return new HashMap<>();
281                 }
282
283                 @Override
284                 public void notifyClosedConnection(final COPSStateMan man, final COPSError error) {
285                         // TODO Auto-generated method stub
286                 }
287
288                 @Override
289                 public void notifyNoKAliveReceived(final COPSStateMan man) {
290                         // TODO Auto-generated method stub
291                 }
292
293                 @Override
294                 public void closeRequestState(final COPSStateMan man) {
295                         // TODO Auto-generated method stub
296                 }
297
298                 @Override
299                 public void newRequestState(final COPSPepReqStateMan man) {
300                         // TODO Auto-generated method stub
301                 }
302
303                 public Map<String, String> getRemoveDecs() {
304                         return new HashMap<>(removeDecs);
305                 }
306
307                 public void setRemoveDecs(final Map<String, String> removeDecs) {
308                         this.removeDecs = new HashMap<>(removeDecs);
309                 }
310
311                 public Map<String, String> getInstallDecs() {
312                         return new HashMap<>(installDecs);
313                 }
314
315                 public void setInstallDecs(final Map<String, String> installDecs) {
316                         this.installDecs = new HashMap<>(installDecs);
317                 }
318
319                 public Map<String, String> getErrorDecs() {
320                         return errorDecs;
321                 }
322
323                 public void setErrorDecs(final Map<String, String> errorDecs) {
324                         this.errorDecs = new HashMap<>(errorDecs);
325                 }
326
327                 public COPSPepReqStateMan getStateManager() {
328                         return stateManager;
329                 }
330
331                 public void setStateManager(COPSPepReqStateMan stateManager) {
332                         this.stateManager = stateManager;
333                 }
334
335         }
336 }