/* * (C) Copyright 2015 by fr3ts0n <erwin.scheuch-heilig@gmx.at> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ package com.fr3ts0n.prot; import org.apache.log4j.Logger; import java.io.IOException; /** * Extension to native serial selectedPort to allow odd baud rates and 5-Baud operations * especially for automotive usage * * @author erwin */ public class SerialExt { static Logger log = Logger.getLogger("com.fr3ts0n.prot.ext"); /** * Open serial device * * @param fileName file name of serial device (i.e.: \\.\COMx, /dev/ttySx ...) * @return file descriptor of file device, or -1 if not available */ private static native int openSerial(String fileName); /** * Close serial device * * @param fd file descriptor of selectedPort * @return error status of system function (0=success) */ private static native int closeSerial(int fd); /** * native interface to * set status of BREAK signal * This is used to create a 5-baud signal for ECU kick-off * * @param fd file descriptor of selectedPort * @param brkStatus desired status of BREAK signal * @return error status of system function (0=success) */ private static native int setBreak(int fd, int brkStatus); /** * native interface to * set custom baud rate * Custom baud rates are set by dividing the selectedPort baud base frequency with a * divisor value. Purpose of this function is to allow odd ball ECU baud rates * like 10400 baud etc., which are not supported by regular system calls * * @param fd file descriptor of selectedPort * @param baudRate cusom baud rate to be set * @return error status of system function (0=success) */ private static native int setCustomBaudrate(int fd, int baudrate); /** * native interface to * return custom baud rate setting * Custom baud rates are set by dividing the selectedPort baud base frequency with a * divisor value. Purpose of this function is to allow odd ball ECU baud rates * like 10400 baud etc., which are not supported by regular system calls * * @param fd file descriptor of selectedPort * @return custom baud rate setting, or 0 if no custom baud rate was set */ private static native int getCustomBaudrate(int fd); /** * receive a character from COM selectedPort * * @param fd file descriptor of selectedPort * @return received character or -1 on receive error */ private static native int receiveChar(int fd); /** * send a character from COM selectedPort * * @param fd file descriptor of selectedPort * @param txChar character to be sent * @return error status of system function (0=success) */ private static native int sendChar(int fd, char txChar); /** file descriptor of serial selectedPort */ public static int serialPortDescriptor = -1; static { System.loadLibrary("SerialExt"); } /** * Open serial device * * @param fileName file name of serial device (i.e.: \\.\COMx, /dev/ttySx ...) * @return file descriptor of file device, or -1 if not available * @throws IOException */ public static int open(String fileName) throws IOException { int result = openSerial(fileName); if (result < 0) { throw new IOException("open"); } serialPortDescriptor = result; return result; } /** * Close serial device * * @return error status of serial operation (0=SUCCESS) * @throws IOException */ public static int close() throws IOException { int result = closeSerial(serialPortDescriptor); serialPortDescriptor = -1; if (result != 0) { throw new IOException("close"); } return result; } /** * Set line BREAK status to desired state * * @param newStatus desired BREAK status * @return error status of selectedPort/line setting (0=SUCCESS) * @throws IOException */ public static int setBreak(int newStatus) throws IOException { log.debug(String.format("BREAK %s", newStatus != 0 ? "ON" : "OFF")); int result = setBreak(serialPortDescriptor, newStatus); if (result != 0) { throw new IOException("setBreak"); } return result; } /** * Set custom baud rate on specified SerialPort * * @param baudrate new baud rate in bps * @return error status of selectedPort/line setting (0=SUCCESS) * @throws IOException */ public static int setCustomBaudrate(int baudrate) throws IOException { log.debug(String.format("Setting custom baudrate %d", baudrate)); int result = setCustomBaudrate(serialPortDescriptor, baudrate); if (result != 0) { throw new IOException("setCustomBaudrate"); } return result; } /** * Set custom baud rate on specified SerialPort * * @return error status of selectedPort/line setting (0=SUCCESS) * @throws IOException */ public static int getCustomBaudrate() throws IOException { int result = getCustomBaudrate(serialPortDescriptor); log.debug(String.format("getting custom baudrate %d", result)); if (result <= 0) { throw new IOException("getCustomBaudrate"); } return result; } /** * receive a character from COM selectedPort * * @return received character or -1 on receive error */ public static int receiveChar() throws IOException { log.trace(String.format("waiting for RX char")); int result = receiveChar(serialPortDescriptor); if (result < 0) { throw new IOException(String.format("receiveChar:%02X", result)); } return result; } /** * send a character to COM selectedPort * * @param txChar character to be sent * @return received character or -1 on send error */ public static int sendChar(byte txChar) throws IOException { log.trace(String.format("sending char:%02X", (byte) txChar)); int result = sendChar(serialPortDescriptor, (char) txChar); if (result < 0) { throw new IOException(String.format("sendChar:%d", result)); } return result; } /** * send characters to COM selectedPort * * @param txBytes characters to be sent * @return received character or -1 on send error */ public static int write(byte[] txBytes) throws IOException { int result = 0; for (int i = 0; i < txBytes.length; i++) result |= sendChar(txBytes[i]); return result; } }