7 import org.pcmm.objects.MMVersionInfo;
8 import org.slf4j.Logger;
9 import org.slf4j.LoggerFactory;
10 import org.umu.cops.prpdp.COPSPdpAgent;
11 import org.umu.cops.prpdp.COPSPdpException;
12 import org.umu.cops.stack.*;
13 import org.umu.cops.stack.COPSError.ErrorTypes;
14 import org.umu.cops.stack.COPSHeader.OPCode;
16 import java.io.IOException;
17 import java.net.InetAddress;
18 import java.net.Socket;
21 * Core PDP agent for provisioning
23 public class PCMMPdpAgent extends COPSPdpAgent {
25 private static final Logger logger = LoggerFactory.getLogger(PCMMPdpAgent.class);
27 /** Well-known port for PCMM */
28 public static final int WELL_KNOWN_PDP_PORT = 3918;
33 private final String psHost;
38 private final int psPort;
41 * Policy data processing object
43 private final PCMMPdpDataProcess _process;
45 // Next two attributes are initialized when connected
47 * The Socket connection to the PEP
49 private transient Socket socket;
50 private transient COPSHandle _handle;
55 * @param clientType - COPS Client-type
56 * @param psHost - Host to connect to
57 * @param psPort - Port to connect to
58 * @param process - Object to perform policy data processing
60 public PCMMPdpAgent(final short clientType, final String psHost, final int psPort,
61 final PCMMPdpDataProcess process) {
62 super(psPort, clientType, null);
63 this._process = process;
69 * XXX -tek- This is the retooled connect. Not sure if the while forever
70 * loop is needed. Socket accept --> handleClientOpenMsg --> pdpConn.run()
72 * Below is new Thread(pdpConn).start(); Does that do it?
78 * @return <tt>true</tt> if PDP accepts the connection; <tt>false</tt>
80 * @throws java.net.UnknownHostException
81 * @throws java.io.IOException
82 * @throws COPSException
84 public boolean connect() throws IOException, COPSException {
85 // Create Socket and send OPN
86 final InetAddress addr = InetAddress.getByName(psHost);
87 socket = new Socket(addr, psPort);
88 logger.debug("{} {}", getClass().getName(), "PDP Socket Opened");
90 // We're waiting for an message
92 logger.debug("Waiting to receiveMsg");
93 final COPSMsg msg = COPSTransceiver.receiveMsg(socket);
94 logger.debug("Message received of type - " + msg.getHeader().getOpCode());
95 if (msg.getHeader().getOpCode().equals(OPCode.OPN)) {
96 handleClientOpenMsg(socket, msg);
100 } catch (Exception ex) {
101 logger.error("Unexpected error closing socket", ex);
104 } catch (Exception e) {
105 logger.error("Unexpected error handing client open message", e);
108 } catch (Exception ex) {
109 logger.error("Unexpected error closing socket", ex);
117 // TODO - remove and let super handle after DataProcess & PdpConnection classes are properly refactored
119 public void disconnect (final String pepID, final COPSError error) throws COPSException, IOException {
120 final PCMMPdpConnection pdpConn = (PCMMPdpConnection) _connectionMap.get(pepID);
121 if (pdpConn != null) {
122 final COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(getClientType(), error, null, null);
123 closeMsg.writeData(pdpConn.getSocket());
127 final Thread thread = threadMap.remove(pepID);
128 if (thread != null) thread.interrupt();
131 // TODO - this method should be broken apart into smaller pieces.
133 protected void handleClientOpenMsg(final Socket conn, final COPSMsg msg) throws COPSException, IOException {
134 logger.info("Processing client open message");
135 final COPSClientOpenMsg cMsg = (COPSClientOpenMsg) msg;
136 _pepId = cMsg.getPepId();
138 // Validate Client Type
139 if (msg.getHeader().getClientType() != getClientType()) {
140 // Unsupported client type
141 final COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(getClientType(),
142 new COPSError(ErrorTypes.UNSUPPORTED_CLIENT_TYPE, ErrorTypes.NA), null, null);
144 closeMsg.writeData(conn);
145 } catch (IOException unae) {
146 logger.error("Unexpected error writing data", unae);
149 throw new COPSException("Unsupported client type");
152 // PEPId is mandatory
153 if (_pepId == null) {
154 // Mandatory COPS object missing
155 final COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(getClientType(),
156 new COPSError(ErrorTypes.MANDATORY_OBJECT_MISSING, ErrorTypes.NA), null, null);
158 closeMsg.writeData(conn);
159 } catch (IOException unae) {
160 logger.error("Unexpected error closing socket", unae);
163 throw new COPSException("Mandatory COPS object missing (PEPId)");
167 if ((cMsg.getClientSI() != null) ) {
168 final MMVersionInfo _mminfo = new MMVersionInfo(cMsg.getClientSI().getData().getData());
169 logger.debug("CMTS sent MMVersion info : major:" + _mminfo.getMajorVersionNB() + " minor:" +
170 _mminfo.getMinorVersionNB());
173 // Unsupported objects
174 final COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(getClientType(),
175 new COPSError(ErrorTypes.UNKNOWN_OBJECT, ErrorTypes.NA), null, null);
177 closeMsg.writeData(conn);
178 } catch (IOException unae) {
179 logger.error("Unexpected error writing data", unae);
182 throw new COPSException("Unsupported objects (PdpAddress, Integrity)");
187 // Connection accepted
188 final COPSClientAcceptMsg acceptMsg;
189 if (getAcctTimer() != 0)
190 acceptMsg = new COPSClientAcceptMsg(getClientType(), new COPSKATimer(getKaTimer()),
191 new COPSAcctTimer(getAcctTimer()), null);
193 acceptMsg = new COPSClientAcceptMsg(getClientType(), new COPSKATimer(getKaTimer()), null, null);
194 acceptMsg.writeData(conn);
195 // XXX - handleRequestMsg
197 logger.debug("handleClientOpenMsg() - Waiting to receive message");
198 final COPSMsg rmsg = COPSTransceiver.receiveMsg(socket);
199 logger.debug("Received message of type - " + rmsg.getHeader().getOpCode());
201 if (rmsg.getHeader().getOpCode().equals(OPCode.CC)) {
202 System.out.println(((COPSClientCloseMsg) rmsg)
203 .getError().getDescription());
205 final COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(getClientType(),
206 new COPSError(ErrorTypes.UNKNOWN_OBJECT, ErrorTypes.NA), null, null);
208 closeMsg.writeData(conn);
209 } catch (IOException unae) {
210 logger.error("Unexpected error writing data", unae);
212 throw new COPSException("CMTS requetsed Client-Close");
215 if (rmsg.getHeader().getOpCode().equals(OPCode.REQ)) {
216 COPSReqMsg rMsg = (COPSReqMsg) rmsg;
217 _handle = rMsg.getClientHandle();
219 throw new COPSException("Can't understand request");
221 } catch (Exception e) { // COPSException, IOException
222 throw new COPSException("Error COPSTransceiver.receiveMsg", e);
225 logger.debug("PDPCOPSConnection");
226 final PCMMPdpConnection pdpConn = new PCMMPdpConnection(_pepId, conn, _process, getKaTimer(), getAcctTimer());
228 // XXX - handleRequestMsg
229 // XXX - check handle is valid
230 final PCMMPdpReqStateMan man = new PCMMPdpReqStateMan(getClientType(), _handle, _process);
231 pdpConn.addStateMan(_handle, man);
233 man.initRequestState(conn);
234 } catch (COPSPdpException unae) {
235 logger.error("Unexpected error initializing state", unae);
237 // XXX - End handleRequestMsg
239 logger.info("Starting PDP connection thread to - " + psHost);
241 // TODO - store the thread reference so it is possible to manage.
242 final Thread thread = new Thread(pdpConn, "Agent for - " + psHost);
244 threadMap.put(_pepId.getData().str(), thread);
245 _connectionMap.put(_pepId.getData().str(), pdpConn);
248 public Socket getSocket() {
252 public COPSHandle getClientHandle() {
256 public String getPepIdString() {
257 return _pepId.getData().str();