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;
15 import java.io.IOException;
16 import java.net.InetAddress;
17 import java.net.Socket;
20 * Core PDP agent for provisioning
22 public class PCMMPdpAgent extends COPSPdpAgent {
24 public final static Logger logger = LoggerFactory.getLogger(PCMMPdpAgent.class);
26 /** Well-known port for PCMM */
27 public static final int WELL_KNOWN_PDP_PORT = 3918;
29 private COPSPepId _pepId;
30 private String _pepIdString;
34 private String psHost;
41 private Socket socket;
44 * Policy data processing object
46 private PCMMPdpDataProcess _process;
47 private COPSHandle _handle;
48 // private short _transactionID;
56 * Object to perform policy data processing
58 public PCMMPdpAgent(short clientType, PCMMPdpDataProcess process) {
59 this(clientType, null, WELL_KNOWN_PDP_PORT, process);
72 * Object to perform policy data processing
74 public PCMMPdpAgent(short clientType, String psHost, int psPort, PCMMPdpDataProcess process) {
75 super(psPort, clientType, null);
76 this._process = process;
81 * XXX -tek- This is the retooled connect. Not sure if the while forever
82 * loop is needed. Socket accept --> handleClientOpenMsg --> pdpConn.run()
84 * Below is new Thread(pdpConn).start(); Does that do it?
94 * @return <tt>true</tt> if PDP accepts the connection; <tt>false</tt>
96 * @throws java.net.UnknownHostException
97 * @throws java.io.IOException
98 * @throws COPSException
99 * @throws COPSPdpException
101 public boolean connect(String psHost, int psPort) throws IOException, COPSException, COPSPdpException {
103 this.psHost = psHost;
104 this.psPort = psPort;
105 // Create Socket and send OPN
106 InetAddress addr = InetAddress.getByName(psHost);
108 socket = new Socket(addr, psPort);
109 } catch (IOException e) {
110 logger.error("Error creating socket connection", e);
113 logger.info("PDP Socket Opened");
114 // Loop through for Incoming messages
116 // server infinite loop
120 // We're waiting for an message
122 logger.info("PDP COPSTransceiver.receiveMsg");
123 COPSMsg msg = COPSTransceiver.receiveMsg(socket);
124 if (msg.getHeader().isAClientOpen()) {
125 logger.info("PDP msg.getHeader().isAClientOpen");
126 handleClientOpenMsg(socket, msg);
130 } catch (Exception ex) {
131 logger.error("Unexpected exception closing socket", ex);
134 } catch (Exception e) { // COPSException, IOException
137 } catch (Exception ex) {
138 logger.error("Unexpected exception closing socket", ex);
147 * Handles a COPS client-open message
152 * <tt>COPSMsg</tt> holding the client-open message
153 * @throws COPSException
154 * @throws IOException
156 private void handleClientOpenMsg(Socket conn, COPSMsg msg)
157 throws COPSException, IOException {
158 COPSClientOpenMsg cMsg = (COPSClientOpenMsg) msg;
159 COPSPepId pepId = cMsg.getPepId();
161 // Validate Client Type
162 if (msg.getHeader().getClientType() != getClientType()) {
163 // Unsupported client type
164 COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, msg
165 .getHeader().getClientType());
166 COPSError err = new COPSError(ErrorTypes.UNSUPPORTED_CLIENT_TYPE, ErrorTypes.NA);
167 COPSClientCloseMsg closeMsg = new COPSClientCloseMsg();
171 closeMsg.writeData(conn);
172 } catch (IOException unae) {
173 logger.error("Unexpected error writing COPS data", unae);
176 throw new COPSException("Unsupported client type");
179 // PEPId is mandatory
181 // Mandatory COPS object missing
182 COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, msg
183 .getHeader().getClientType());
184 COPSError err = new COPSError(
185 ErrorTypes.MANDATORY_OBJECT_MISSING, ErrorTypes.NA);
186 COPSClientCloseMsg closeMsg = new COPSClientCloseMsg();
190 closeMsg.writeData(conn);
191 } catch (IOException unae) {
192 logger.error("Unexpected error writing COPS data", unae);
195 throw new COPSException("Mandatory COPS object missing (PEPId)");
199 if ((cMsg.getClientSI() != null) ) {
200 final MMVersionInfo _mminfo = new MMVersionInfo(cMsg.getClientSI().getData().getData());
201 logger.info("CMTS sent MMVersion info : major:" + _mminfo.getMajorVersionNB() + " minor:" +
202 _mminfo.getMinorVersionNB());
205 // Unsupported objects
206 COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, msg
207 .getHeader().getClientType());
208 COPSError err = new COPSError(ErrorTypes.UNKNOWN_OBJECT, ErrorTypes.NA);
209 COPSClientCloseMsg closeMsg = new COPSClientCloseMsg();
213 closeMsg.writeData(conn);
214 } catch (IOException unae) {
215 logger.error("Unexpected error writing COPS data", unae);
218 throw new COPSException("Unsupported objects (PdpAddress, Integrity)");
223 // Connection accepted
224 COPSHeader ahdr = new COPSHeader(COPSHeader.COPS_OP_CAT, msg
225 .getHeader().getClientType());
226 COPSKATimer katimer = new COPSKATimer(getKaTimer());
227 COPSAcctTimer acctTimer = new COPSAcctTimer(getAcctTimer());
228 COPSClientAcceptMsg acceptMsg = new COPSClientAcceptMsg();
230 acceptMsg.add(katimer);
231 if (getAcctTimer() != 0)
232 acceptMsg.add(acctTimer);
233 acceptMsg.writeData(conn);
234 // XXX - handleRequestMsg
236 logger.info("PDP COPSTransceiver.receiveMsg");
237 COPSMsg rmsg = COPSTransceiver.receiveMsg(socket);
239 if (rmsg.getHeader().isAClientClose()) {
240 logger.info("Client close description - " + ((COPSClientCloseMsg) rmsg).getError().getDescription());
242 COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, msg
243 .getHeader().getClientType());
244 COPSError err = new COPSError(ErrorTypes.UNKNOWN_OBJECT, ErrorTypes.NA);
245 COPSClientCloseMsg closeMsg = new COPSClientCloseMsg();
249 closeMsg.writeData(conn);
250 } catch (IOException unae) {
251 logger.error("Unexpected exception writing COPS data", unae);
253 throw new COPSException("CMTS requetsed Client-Close");
256 if (rmsg.getHeader().isARequest()) {
257 COPSReqMsg rMsg = (COPSReqMsg) rmsg;
258 _handle = rMsg.getClientHandle();
260 throw new COPSException("Can't understand request");
263 } catch (Exception e) { // COPSException, IOException
264 throw new COPSException("Error COPSTransceiver.receiveMsg");
267 logger.info("PDPCOPSConnection");
268 PCMMPdpConnection pdpConn = new PCMMPdpConnection(pepId, conn, _process);
269 pdpConn.setKaTimer(getKaTimer());
270 if (getAcctTimer() != 0)
271 pdpConn.setAccTimer(getAcctTimer());
273 // XXX - handleRequestMsg
274 // XXX - check handle is valid
275 PCMMPdpReqStateMan man = new PCMMPdpReqStateMan(getClientType(), _handle.getId().str());
276 pdpConn.getReqStateMans().put(_handle.getId().str(),man);
277 man.setDataProcess(_process);
279 man.initRequestState(conn);
280 } catch (COPSPdpException unae) {
281 logger.error("Error initializing the state manager's request state");
283 // XXX - End handleRequestMsg
285 logger.info("PDP Thread(pdpConn).start");
286 new Thread(pdpConn).start();
287 getConnectionMap().put(pepId.getData().str(), pdpConn);
291 * @return the _psHost
293 public String getPsHost() {
298 * TODO - make the host immutable
303 public void setPsHost(String _psHost) {
304 this.psHost = _psHost;
308 * @return the _psPort
310 public int getPsPort() {
315 * TODO - make the port immutable
320 public void setPsPort(int _psPort) {
321 this.psPort = _psPort;
327 public Socket getSocket() {
332 * TODO - Ensure socket is not overly transient
337 public void setSocket(Socket socket) {
338 this.socket = socket;
342 * @return the _process
344 public PCMMPdpDataProcess getProcess() {
350 * the _process to set
352 public void setProcess(PCMMPdpDataProcess _process) {
353 this._process = _process;
357 * Gets the client handle
358 * @return Client's <tt>COPSHandle</tt>
360 public COPSHandle getClientHandle() {
366 * @return <tt>COPSPepId</tt>
368 public COPSPepId getPepId() {
372 public String getPepIdString() {
378 * TODO - make PEP ID and the associate string immutable or remove altogether
379 * @param pepId - COPSPepId
382 public void setPepId(COPSPepId pepId) {
384 _pepIdString = pepId.getData().str();
389 * @see org.pcmm.rcd.IPCMMClient#isConnected()
391 public boolean isConnected() {
392 return socket != null && socket.isConnected();