Add packetcable-driver as a bundle and fix karafe depends. Merge hop-along model...
[packetcable.git] / packetcable-driver / src / main / java / org / pcmm / PCMMPepAgent.java
1 /**
2  @header@
3  */
4
5 package org.pcmm;
6
7 import java.io.IOException;
8 import java.net.ServerSocket;
9 import java.net.Socket;
10 import java.net.UnknownHostException;
11
12 import org.umu.cops.common.COPSDebug;
13 import org.umu.cops.prpep.COPSPepAgent;
14 import org.umu.cops.prpep.COPSPepConnection;
15 import org.umu.cops.prpep.COPSPepException;
16 import org.umu.cops.stack.COPSAcctTimer;
17 import org.umu.cops.stack.COPSClientAcceptMsg;
18 import org.umu.cops.stack.COPSClientCloseMsg;
19 import org.umu.cops.stack.COPSClientOpenMsg;
20 import org.umu.cops.stack.COPSData;
21 import org.umu.cops.stack.COPSError;
22 import org.umu.cops.stack.COPSException;
23 import org.umu.cops.stack.COPSHeader;
24 import org.umu.cops.stack.COPSKATimer;
25 import org.umu.cops.stack.COPSMsg;
26 import org.umu.cops.stack.COPSPepId;
27 import org.umu.cops.stack.COPSTransceiver;
28
29 /**
30  * This is a provisioning COPS PEP. Responsible for making connection to the PDP
31  * and maintaining it
32  */
33 public class PCMMPepAgent extends COPSPepAgent implements Runnable {
34
35     /** Well-known port for COPS */
36     public static final int WELL_KNOWN_CMTS_PORT = 3918;
37
38     /**
39      * PDP host IP
40      */
41     private ServerSocket serverSocket;
42
43     /**
44      * PDP host port
45      */
46     private int serverPort;
47
48     /**
49      * COPS error returned by PDP
50      */
51     private COPSError error;
52
53     /**
54      * Creates a PEP agent
55      *
56      * @param pepID
57      *            PEP-ID
58      * @param clientType
59      *            Client-type
60      */
61     public PCMMPepAgent(String pepID, short clientType) {
62         super(pepID, clientType);
63         serverPort = WELL_KNOWN_CMTS_PORT;
64     }
65
66     /**
67      * Creates a PEP agent with a PEP-ID equal to "noname"
68      *
69      * @param clientType
70      *            Client-type
71      */
72     public PCMMPepAgent(short clientType) {
73         super(clientType);
74         serverPort = WELL_KNOWN_CMTS_PORT;
75     }
76
77     /**
78      * Runs the PEP process XXX - not sure of the exception throwing
79      */
80     public void run() {
81         try {
82
83             COPSDebug.err(getClass().getName(), "Create Server Socket on Port "
84                           + serverPort);
85
86             serverSocket = new ServerSocket(serverPort);
87             // Loop through for Incoming messages
88
89             // server infinite loop
90             while (true) {
91
92                 // Wait for an incoming connection from a PEP
93                 Socket socket = serverSocket.accept();
94
95                 COPSDebug.err(getClass().getName(), "New connection accepted "
96                               + socket.getInetAddress() + ":" + socket.getPort());
97
98                 processConnection(socket);
99                 /**
100                  * XXX - processConnection handles the open request from PEP And
101                  * a thread is created for conn = new
102                  * COPSPepConnection(_clientType, socket); the main processing
103                  * loop for PEP
104                  */
105
106             }
107         } catch (IOException e) {
108             COPSDebug.err(getClass().getName(), COPSDebug.ERROR_SOCKET, e);
109         } catch (COPSException e) {
110             COPSDebug.err(getClass().getName(), COPSDebug.ERROR_SOCKET, e);
111         } catch (COPSPepException e) {
112             COPSDebug.err(getClass().getName(), COPSDebug.ERROR_SOCKET, e);
113         }
114     }
115
116     /**
117      * Establish connection to PDP's IP address
118      *
119      * <Client-Open> ::= <Common Header> <PEPID> [<ClientSI>] [<LastPDPAddr>]
120      * [<Integrity>]
121      *
122      * Not support [<ClientSI>], [<LastPDPAddr>], [<Integrity>]
123      *
124      * <Client-Accept> ::= <Common Header> <KA Timer> [<ACCT Timer>]
125      * [<Integrity>]
126      *
127      * Not send [<Integrity>]
128      *
129      * <Client-Close> ::= <Common Header> <Error> [<PDPRedirAddr>] [<Integrity>]
130      *
131      * Not send [<PDPRedirAddr>], [<Integrity>]
132      *
133      * @throws UnknownHostException
134      * @throws IOException
135      * @throws COPSException
136      * @throws COPSPepException
137      *
138      */
139     private COPSPepConnection processConnection(Socket socket)
140     throws UnknownHostException, IOException, COPSException,
141                 COPSPepException {
142         // Build OPN
143         COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_OPN, getClientType());
144
145         COPSPepId pepId = new COPSPepId();
146         COPSData d = new COPSData(getPepID());
147         pepId.setData(d);
148
149         COPSClientOpenMsg msg = new COPSClientOpenMsg();
150         msg.add(hdr);
151         msg.add(pepId);
152
153         // Create Socket and send OPN
154         /*
155          * InetAddress addr = InetAddress.getByName(psHost); Socket socket = new
156          * Socket(addr,psPort);
157          */
158         COPSDebug.err(getClass().getName(), "Send COPSClientOpenMsg to PDP");
159         msg.writeData(socket);
160
161         // Receive the response
162         COPSDebug.err(getClass().getName(), "Receive the resposne from PDP");
163         COPSMsg recvmsg = COPSTransceiver.receiveMsg(socket);
164
165         if (recvmsg.getHeader().isAClientAccept()) {
166             COPSDebug.err(getClass().getName(), "isAClientAccept from PDP");
167             COPSClientAcceptMsg cMsg = (COPSClientAcceptMsg) recvmsg;
168
169             // Support
170             if (cMsg.getIntegrity() != null) {
171                 throw new COPSPepException("Unsupported object (Integrity)");
172             }
173
174             // Mandatory KATimer
175             COPSKATimer kt = cMsg.getKATimer();
176             if (kt == null)
177                 throw new COPSPepException(
178                     "Mandatory COPS object missing (KA Timer)");
179             short _kaTimeVal = kt.getTimerVal();
180
181             // ACTimer
182             COPSAcctTimer at = cMsg.getAcctTimer();
183             short _acctTimer = 0;
184             if (at != null)
185                 _acctTimer = at.getTimerVal();
186
187             // Create the connection manager
188             COPSPepConnection conn = new COPSPepConnection(getClientType(),
189                     socket);
190             conn.setKaTimer(_kaTimeVal);
191             conn.setAcctTimer(_acctTimer);
192             COPSDebug.err(getClass().getName(), "Thread(conn).start");
193             new Thread(conn).start();
194
195             return conn;
196         } else if (recvmsg.getHeader().isAClientClose()) {
197             COPSDebug.err(getClass().getName(), "isAClientClose from PDP");
198             COPSClientCloseMsg cMsg = (COPSClientCloseMsg) recvmsg;
199             error = cMsg.getError();
200             socket.close();
201             return null;
202         } else { // messages of other types are not expected
203             throw new COPSPepException(
204                 "Message not expected. Closing connection for "
205                 + socket.toString());
206         }
207     }
208
209     /**
210      * Gets the COPS error returned by the PDP
211      *
212      * @return <tt>COPSError</tt> returned by PDP
213      */
214     public COPSError getConnectionError() {
215         return error;
216     }
217
218     public void setConnectionError(COPSError _error) {
219         this.error = _error;
220     }
221
222     /**
223      * @return the serverSocket
224      */
225     public ServerSocket getServerSocket() {
226         return serverSocket;
227     }
228
229     /**
230      * @param serverSocket
231      *            the serverSocket to set
232      */
233     public void setServerSocket(ServerSocket serverSocket) {
234         this.serverSocket = serverSocket;
235     }
236
237     /**
238      * @return the serverPort
239      */
240     public int getServerPort() {
241         return serverPort;
242     }
243
244     /**
245      * @param serverPort
246      *            the serverPort to set
247      */
248     public void setServerPort(int serverPort) {
249         this.serverPort = serverPort;
250     }
251
252 }