View Javadoc

1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License.
18   *
19   */
20  package org.apache.mina.transport.serial;
21  
22  import gnu.io.CommPortIdentifier;
23  import gnu.io.PortInUseException;
24  import gnu.io.SerialPort;
25  import gnu.io.UnsupportedCommOperationException;
26  
27  import java.io.IOException;
28  import java.net.SocketAddress;
29  import java.util.Enumeration;
30  import java.util.TooManyListenersException;
31  import java.util.concurrent.Executor;
32  
33  import org.apache.mina.core.service.AbstractIoConnector;
34  import org.apache.mina.core.future.ConnectFuture;
35  import org.apache.mina.core.future.DefaultConnectFuture;
36  import org.apache.mina.core.session.IdleStatusChecker;
37  import org.apache.mina.core.service.IoConnector;
38  import org.apache.mina.core.future.IoFuture;
39  import org.apache.mina.core.session.IoSessionInitializer;
40  import org.apache.mina.core.service.TransportMetadata;
41  import org.slf4j.Logger;
42  import org.slf4j.LoggerFactory;
43  
44  /**
45   * {@link IoConnector} for serial communication transport.
46   *
47   * @author The Apache MINA Project (dev@mina.apache.org)
48   * @version $Rev: 529576 $, $Date: 2007-04-17 14:25:07 +0200 (mar., 17 avr. 2007) $
49   */
50  public final class SerialConnector extends AbstractIoConnector {
51      private final Logger log;
52      
53      private IdleStatusChecker idleChecker;
54  
55      public SerialConnector() {
56          this(null);
57      }
58  
59      public SerialConnector(Executor executor) {
60          super(new DefaultSerialSessionConfig(), executor);
61          log = LoggerFactory.getLogger(SerialConnector.class);
62          
63          idleChecker = new IdleStatusChecker();
64          // we schedule the idle status checking task in this service exceutor
65          // it will be woke up every seconds
66          executeWorker(idleChecker.getNotifyingTask(), "idleStatusChecker");
67          
68      }
69  
70      @Override
71      protected ConnectFuture connect0(
72              SocketAddress remoteAddress, SocketAddress localAddress,
73              IoSessionInitializer<? extends ConnectFuture> sessionInitializer) {
74  
75          CommPortIdentifier portId;
76          Enumeration<?> portList = CommPortIdentifier.getPortIdentifiers();
77  
78          SerialAddress portAddress = (SerialAddress) remoteAddress;
79  
80          // looping around found ports
81          while (portList.hasMoreElements()) {
82              portId = (CommPortIdentifier) portList.nextElement();
83              if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
84                  if (log.isDebugEnabled()) {
85                      log.debug("Serial port discovered : " + portId.getName());
86                  }
87                  if (portId.getName().equals(portAddress.getName())) {
88                      try {
89                          if (log.isDebugEnabled()) {
90                              log
91                                      .debug("Serial port found : "
92                                              + portId.getName());
93                          }
94  
95                          SerialPort serialPort = initializePort("Apache MINA",
96                                  portId, portAddress);
97  
98                          ConnectFuture future = new DefaultConnectFuture();
99                          SerialSessionImpl session = new SerialSessionImpl(
100                                 this, getListeners(), portAddress, serialPort);
101                         finishSessionInitialization(session, future, sessionInitializer);
102                         session.start();
103                         return future;
104                     } catch (PortInUseException e) {
105                         if (log.isDebugEnabled()) {
106                             log.debug("Port In Use Exception : ", e);
107                         }
108                         return DefaultConnectFuture.newFailedFuture(e);
109                     } catch (UnsupportedCommOperationException e) {
110                         if (log.isDebugEnabled()) {
111                             log.debug("Comm Exception : ", e);
112                         }
113                         return DefaultConnectFuture.newFailedFuture(e);
114                     } catch (IOException e) {
115                         if (log.isDebugEnabled()) {
116                             log.debug("IOException : ", e);
117                         }
118                         return DefaultConnectFuture.newFailedFuture(e);
119                     } catch (TooManyListenersException e) {
120                         if (log.isDebugEnabled()) {
121                             log.debug("TooManyListenersException : ", e);
122                         }
123                         return DefaultConnectFuture.newFailedFuture(e);
124                     }
125                 }
126             }
127         }
128 
129         return DefaultConnectFuture
130                 .newFailedFuture(new SerialPortUnavailableException(
131                         "Serial port not found"));
132     }
133 
134     @Override
135     protected IoFuture dispose0() throws Exception {
136     	// stop the idle checking task
137     	idleChecker.getNotifyingTask().cancel();
138         return null;
139     }
140 
141     public TransportMetadata getTransportMetadata() {
142         return SerialSessionImpl.METADATA;
143     }
144 
145     private SerialPort initializePort(String user, CommPortIdentifier portId,
146             SerialAddress portAddress)
147             throws UnsupportedCommOperationException, PortInUseException {
148 
149         SerialSessionConfig config = (SerialSessionConfig) getSessionConfig();
150 
151         long connectTimeout = getConnectTimeoutMillis();
152         if (connectTimeout > Integer.MAX_VALUE) {
153             connectTimeout = Integer.MAX_VALUE;
154         }
155 
156         SerialPort serialPort = (SerialPort) portId.open(
157                 user, (int) connectTimeout);
158 
159         serialPort.setSerialPortParams(portAddress.getBauds(), portAddress
160                 .getDataBitsForRXTX(), portAddress.getStopBitsForRXTX(),
161                 portAddress.getParityForRXTX());
162 
163         serialPort.setFlowControlMode(portAddress.getFLowControlForRXTX());
164 
165         serialPort.notifyOnDataAvailable(true);
166 
167         if (config.isLowLatency()) {
168             serialPort.setLowLatency();
169         }
170 
171         serialPort.setInputBufferSize(config.getInputBufferSize());
172         serialPort.setOutputBufferSize(config.getOutputBufferSize());
173 
174         if (config.getReceiveThreshold() >= 0) {
175             serialPort.enableReceiveThreshold(config.getReceiveThreshold());
176         } else {
177             serialPort.disableReceiveThreshold();
178         }
179 
180         return serialPort;
181     }
182 
183     IdleStatusChecker getIdleStatusChecker0() {
184         return idleChecker;
185     }
186 }