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.future.ConnectFuture;
    34  import org.apache.mina.core.future.DefaultConnectFuture;
    35  import org.apache.mina.core.service.AbstractIoConnector;
    36  import org.apache.mina.core.service.IoConnector;
    37  import org.apache.mina.core.service.TransportMetadata;
    38  import org.apache.mina.core.session.IdleStatusChecker;
    39  import org.apache.mina.core.session.IoSessionInitializer;
    40  import org.slf4j.Logger;
    41  import org.slf4j.LoggerFactory;
    42
    43  /**
    44   * {@link IoConnector} for serial communication transport.
    45   *
    46   * @author <a href="http://mina.apache.org">Apache MINA Project</a>
    47   */
    48  public final class SerialConnector extends AbstractIoConnector {
    49      private final Logger log;
    50
    51      private IdleStatusChecker idleChecker;
    52
    53      public SerialConnector() {
    54          this(null);
    55      }
    56
    57      public SerialConnector(Executor executor) {
    58          super(new DefaultSerialSessionConfig(), executor);
    59          log = LoggerFactory.getLogger(SerialConnector.class);
    60
    61          idleChecker = new IdleStatusChecker();
    62          // we schedule the idle status checking task in this service exceutor
    63          // it will be woke up every seconds
    64          executeWorker(idleChecker.getNotifyingTask(), "idleStatusChecker");
    65
    66      }
    67
    68      @Override
    69      protected synchronized ConnectFuture connect0(SocketAddress remoteAddress, SocketAddress localAddress,
    70              IoSessionInitializer<? extends ConnectFuture> sessionInitializer) {
    71
    72          CommPortIdentifier portId;
    73          Enumeration<?> portList = CommPortIdentifier.getPortIdentifiers();
    74
    75          SerialAddress portAddress = (SerialAddress) remoteAddress;
    76
    77          // looping around found ports
    78          while (portList.hasMoreElements()) {
    79              portId = (CommPortIdentifier) portList.nextElement();
    80              if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
    81                  if (log.isDebugEnabled()) {
    82                      log.debug("Serial port discovered : " + portId.getName());
    83                  }
    84                  if (portId.getName().equals(portAddress.getName())) {
    85                      try {
    86                          if (log.isDebugEnabled()) {
    87                              log.debug("Serial port found : " + portId.getName());
    88                          }
    89
    90                          SerialPort serialPort = initializePort("Apache MINA", portId, portAddress);
    91
    92                          ConnectFuture future = new DefaultConnectFuture();
    93                          SerialSessionImpl session = new SerialSessionImpl(this, getListeners(), portAddress, serialPort);
    94                          initSession(session, future, sessionInitializer);
    95                          session.start();
    96                          return future;
    97                      } catch (PortInUseException e) {
    98                          if (log.isDebugEnabled()) {
    99                              log.debug("Port In Use Exception : ", e);
    100                         }
    101                         return DefaultConnectFuture.newFailedFuture(e);
    102                     } catch (UnsupportedCommOperationException e) {
    103                         if (log.isDebugEnabled()) {
    104                             log.debug("Comm Exception : ", e);
    105                         }
    106                         return DefaultConnectFuture.newFailedFuture(e);
    107                     } catch (IOException e) {
    108                         if (log.isDebugEnabled()) {
    109                             log.debug("IOException : ", e);
    110                         }
    111                         return DefaultConnectFuture.newFailedFuture(e);
    112                     } catch (TooManyListenersException e) {
    113                         if (log.isDebugEnabled()) {
    114                             log.debug("TooManyListenersException : ", e);
    115                         }
    116                         return DefaultConnectFuture.newFailedFuture(e);
    117                     }
    118                 }
    119             }
    120         }
    121
    122         return DefaultConnectFuture.newFailedFuture(new SerialPortUnavailableException("Serial port not found"));
    123     }
    124
    125     @Override
    126     protected void dispose0() throws Exception {
    127         // stop the idle checking task
    128         idleChecker.getNotifyingTask().cancel();
    129     }
    130
    131     public TransportMetadata getTransportMetadata() {
    132         return SerialSessionImpl.METADATA;
    133     }
    134
    135     private SerialPort initializePort(String user, CommPortIdentifier portId, SerialAddress portAddress)
    136             throws UnsupportedCommOperationException, PortInUseException {
    137
    138         SerialSessionConfig config = (SerialSessionConfig) getSessionConfig();
    139
    140         long connectTimeout = getConnectTimeoutMillis();
    141         if (connectTimeout > Integer.MAX_VALUE) {
    142             connectTimeout = Integer.MAX_VALUE;
    143         }
    144
    145         SerialPort serialPort = (SerialPort) portId.open(user, (int) connectTimeout);
    146
    147         serialPort.setSerialPortParams(portAddress.getBauds(), portAddress.getDataBitsForRXTX(),
    148                 portAddress.getStopBitsForRXTX(), portAddress.getParityForRXTX());
    149
    150         serialPort.setFlowControlMode(portAddress.getFLowControlForRXTX());
    151
    152         serialPort.notifyOnDataAvailable(true);
    153
    154         if (config.isLowLatency()) {
    155             serialPort.setLowLatency();
    156         }
    157
    158         serialPort.setInputBufferSize(config.getInputBufferSize());
    159         serialPort.setOutputBufferSize(config.getOutputBufferSize());
    160
    161         if (config.getReceiveThreshold() >= 0) {
    162             serialPort.enableReceiveThreshold(config.getReceiveThreshold());
    163         } else {
    164             serialPort.disableReceiveThreshold();
    165         }
    166
    167         return serialPort;
    168     }
    169
    170     IdleStatusChecker getIdleStatusChecker0() {
    171         return idleChecker;
    172     }
    173 }