868e2086511b5cd7926ccb08275cbda6bb270c9d
[controller.git] / opendaylight / protocol_plugins / openflow / src / main / java / org / opendaylight / controller / protocol_plugin / openflow / core / internal / ControllerIO.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.controller.protocol_plugin.openflow.core.internal;
10
11 import java.io.IOException;
12 import java.nio.channels.SelectionKey;
13 import java.nio.channels.Selector;
14 import java.nio.channels.ServerSocketChannel;
15 import java.nio.channels.spi.SelectorProvider;
16 import java.util.Iterator;
17
18 import org.opendaylight.controller.protocol_plugin.openflow.core.IController;
19 import org.slf4j.Logger;
20 import org.slf4j.LoggerFactory;
21
22 public class ControllerIO {
23     private static final Logger logger = LoggerFactory
24             .getLogger(ControllerIO.class);
25     private static Short defaultOpenFlowPort = 6633;
26     private Short openFlowPort;
27     private SelectionKey serverSelectionKey;
28     private IController listener;
29     private ServerSocketChannel serverSocket;
30     private Selector selector;
31     private boolean running;
32     private Thread controllerIOThread;
33
34     public ControllerIO(IController l) {
35         this.listener = l;
36         this.openFlowPort = defaultOpenFlowPort;
37         String portString = System.getProperty("of.listenPort");
38         if (portString != null) {
39             try {
40                 openFlowPort = Short.decode(portString).shortValue();
41             } catch (NumberFormatException e) {
42                 logger.warn("Invalid port:{}, use default({})", portString,
43                         openFlowPort);
44             }
45         }
46     }
47
48     public void start() throws IOException {
49         this.running = true;
50         // obtain a selector
51         this.selector = SelectorProvider.provider().openSelector();
52         // create the listening socket
53         this.serverSocket = ServerSocketChannel.open();
54         this.serverSocket.configureBlocking(false);
55         this.serverSocket.socket().bind(
56                 new java.net.InetSocketAddress(openFlowPort));
57         this.serverSocket.socket().setReuseAddress(true);
58         // register this socket for accepting incoming connections
59         this.serverSelectionKey = this.serverSocket.register(selector,
60                 SelectionKey.OP_ACCEPT);
61         controllerIOThread = new Thread(new Runnable() {
62             @Override
63             public void run() {
64                 while (running) {
65                     try {
66                         // wait for an incoming connection
67                         selector.select(0);
68                         Iterator<SelectionKey> selectedKeys = selector
69                                 .selectedKeys().iterator();
70                         while (selectedKeys.hasNext()) {
71                             SelectionKey skey = selectedKeys.next();
72                             selectedKeys.remove();
73                             if (skey.isValid() && skey.isAcceptable()) {
74                                 ((Controller) listener).handleNewConnection(
75                                         selector, serverSelectionKey);
76                             }
77                         }
78                     } catch (Exception e) {
79                         continue;
80                     }
81                 }
82             }
83         }, "ControllerI/O Thread");
84         controllerIOThread.start();
85         logger.info("Controller is now listening on port {}", openFlowPort);
86     }
87
88     public void shutDown() throws IOException {
89         this.running = false;
90         this.selector.wakeup();
91         this.serverSocket.close();
92     }
93 }