Advertisement
Guest User

jSSC 2.8 SerialNativeInterface.java

a guest
Jul 24th, 2014
527
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 15.63 KB | None | 0 0
  1. /* jSSC (Java Simple Serial Connector) - serial port communication library.
  2.  * © Alexey Sokolov (scream3r), 2010-2014.
  3.  *
  4.  * This file is part of jSSC.
  5.  *
  6.  * jSSC is free software: you can redistribute it and/or modify
  7.  * it under the terms of the GNU Lesser General Public License as published by
  8.  * the Free Software Foundation, either version 3 of the License, or
  9.  * (at your option) any later version.
  10.  *
  11.  * jSSC is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU Lesser General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU Lesser General Public License
  17.  * along with jSSC.  If not, see <http://www.gnu.org/licenses/>.
  18.  *
  19.  * If you use jSSC in public project you can inform me about this by e-mail,
  20.  * of course if you want it.
  21.  *
  22.  * e-mail: scream3r.org@gmail.com
  23.  * web-site: http://scream3r.org | http://code.google.com/p/java-simple-serial-connector/
  24.  */
  25. package jssc;
  26.  
  27. import java.io.BufferedReader;
  28. import java.io.File;
  29. import java.io.FileOutputStream;
  30. import java.io.InputStream;
  31. import java.io.InputStreamReader;
  32.  
  33. /**
  34.  *
  35.  * @author scream3r
  36.  */
  37. public class SerialNativeInterface {
  38.  
  39.     private static final String libVersion = "2.8"; //jSSC-2.8.0 Release from 24.01.2014
  40.     private static final String libMinorSuffix = "0"; //since 0.9.0
  41.  
  42.     public static final int OS_LINUX = 0;
  43.     public static final int OS_WINDOWS = 1;
  44.     public static final int OS_SOLARIS = 2;//since 0.9.0
  45.     public static final int OS_MAC_OS_X = 3;//since 0.9.0
  46.  
  47.     private static int osType = -1;
  48.  
  49.     /**
  50.      * @since 2.3.0
  51.      */
  52.     public static final long ERR_PORT_BUSY = -1;
  53.     /**
  54.      * @since 2.3.0
  55.      */
  56.     public static final long ERR_PORT_NOT_FOUND = -2;
  57.     /**
  58.      * @since 2.3.0
  59.      */
  60.     public static final long ERR_PERMISSION_DENIED = -3;
  61.     /**
  62.      * @since 2.3.0
  63.      */
  64.     public static final long ERR_INCORRECT_SERIAL_PORT = -4;
  65.  
  66.     /**
  67.      * @since 2.6.0
  68.      */
  69.     public static final String PROPERTY_JSSC_NO_TIOCEXCL = "JSSC_NO_TIOCEXCL";
  70.     /**
  71.      * @since 2.6.0
  72.      */
  73.     public static final String PROPERTY_JSSC_IGNPAR = "JSSC_IGNPAR";
  74.     /**
  75.      * @since 2.6.0
  76.      */
  77.     public static final String PROPERTY_JSSC_PARMRK = "JSSC_PARMRK";
  78.  
  79.     static {
  80.         StringBuilder libFolderPath;
  81.         String libFolderPathStr;
  82.         String libName;
  83.  
  84.         String osName = System.getProperty("os.name");
  85.         String architecture = System.getProperty("os.arch");
  86.         String userHome = System.getProperty("user.home");
  87.         String fileSeparator = System.getProperty("file.separator");
  88.         String tmpFolder = System.getProperty("java.io.tmpdir");
  89.  
  90.         //since 2.3.0 ->
  91.         String libRootFolder = new File(userHome).canWrite() ? userHome : tmpFolder;
  92.         //<- since 2.3.0
  93.  
  94.         String javaLibPath = System.getProperty("java.library.path");//since 2.1.0
  95.  
  96.         if(osName.equals("Linux")){
  97.             osName = "linux";
  98.             osType = OS_LINUX;
  99.         }
  100.         else if(osName.startsWith("Win")){
  101.             osName = "windows";
  102.             osType = OS_WINDOWS;
  103.         }//since 0.9.0 ->
  104.         else if(osName.equals("SunOS")){
  105.             osName = "solaris";
  106.             osType = OS_SOLARIS;
  107.         }
  108.         else if(osName.equals("Mac OS X") || osName.equals("Darwin")){//os.name "Darwin" since 2.6.0
  109.             osName = "mac_os_x";
  110.             osType = OS_MAC_OS_X;
  111.         }//<- since 0.9.0
  112.  
  113.         if(architecture.equals("i386") || architecture.equals("i686")){
  114.             architecture = "x86";
  115.         }
  116.         else if(architecture.equals("amd64") || architecture.equals("universal")){//os.arch "universal" since 2.6.0
  117.             architecture = "x86_64";
  118.         }
  119.         else if(architecture.equals("arm")) {//since 2.1.0
  120.             String floatStr = "sf";
  121.             if(javaLibPath.toLowerCase().contains("gnueabihf") || javaLibPath.toLowerCase().contains("armhf")){
  122.                 floatStr = "hf";
  123.             }
  124.             else {
  125.                 try {
  126.                     Process readelfProcess =  Runtime.getRuntime().exec("readelf -A /proc/self/exe");
  127.                     BufferedReader reader = new BufferedReader(new InputStreamReader(readelfProcess.getInputStream()));
  128.                     String buffer = "";
  129.                     while((buffer = reader.readLine()) != null && !buffer.isEmpty()){
  130.                         if(buffer.toLowerCase().contains("Tag_ABI_VFP_args".toLowerCase())){
  131.                             floatStr = "hf";
  132.                             break;
  133.                         }
  134.                     }
  135.                     reader.close();
  136.                 }
  137.                 catch (Exception ex) {
  138.                     //Do nothing
  139.                 }
  140.             }
  141.             architecture = "arm" + floatStr;
  142.         }
  143.        
  144.         String context = Thread.currentThread().getStackTrace()[3].getClassName();
  145.  
  146.         libFolderPath = new StringBuilder();
  147.         libFolderPath.append(libRootFolder)
  148.                 .append(fileSeparator)
  149.                 .append(".jssc")
  150.                 .append(fileSeparator)
  151.                 .append(osName)
  152.                 .append(fileSeparator)
  153.                 .append(context);
  154.         libFolderPathStr = libFolderPath.toString();
  155.         libName = "jSSC-" + libVersion + "_" + architecture;
  156.         libName = System.mapLibraryName(libName);
  157.  
  158.         if(libName.endsWith(".dylib")){//Since 2.1.0 MacOSX 10.8 fix
  159.             libName = libName.replace(".dylib", ".jnilib");
  160.         }
  161.  
  162.         boolean loadLib = false;
  163.  
  164.         if (isLibFolderExist(libFolderPathStr)) {
  165.             if (isLibFileExist(libFolderPathStr + fileSeparator + libName)) {
  166.                 loadLib = true;
  167.             }
  168.             else {
  169.                 if (extractLib((libFolderPathStr + fileSeparator + libName), osName, libName)) {
  170.                     loadLib = true;
  171.                 }
  172.             }
  173.         }
  174.         else {
  175.             if (new File(libFolderPathStr).mkdirs()) {
  176.                 if (extractLib((libFolderPathStr + fileSeparator + libName), osName, libName)) {
  177.                     loadLib = true;
  178.                 }
  179.             }
  180.         }
  181.  
  182.         if (loadLib) {
  183.             System.load(libFolderPathStr + fileSeparator + libName);
  184.             String versionBase = getLibraryBaseVersion();
  185.             String versionNative = getNativeLibraryVersion();
  186.             if (!versionBase.equals(versionNative)) {
  187.                 System.err.println("Warning! jSSC Java and Native versions mismatch (Java: " + versionBase + ", Native: " + versionNative + ")");
  188.             }
  189.         }
  190.     }
  191.  
  192.     /**
  193.      * Is library folder exists
  194.      *
  195.      * @param libFolderPath
  196.      *
  197.      * @since 0.8
  198.      */
  199.     private static boolean isLibFolderExist(String libFolderPath) {
  200.         boolean returnValue = false;
  201.         File folder = new File(libFolderPath);
  202.         if(folder.exists() && folder.isDirectory()){
  203.             returnValue = true;
  204.         }
  205.         return returnValue;
  206.     }
  207.  
  208.     /**
  209.      * Is library file exists
  210.      *
  211.      * @param libFilePath
  212.      *
  213.      * @since 0.8
  214.      */
  215.     private static boolean isLibFileExist(String libFilePath) {
  216.         boolean returnValue = false;
  217.         File folder = new File(libFilePath);
  218.         if(folder.exists() && folder.isFile()){
  219.             returnValue = true;
  220.         }
  221.         return returnValue;
  222.     }
  223.  
  224.     /**
  225.      * Extract lib to lib folder
  226.      *
  227.      * @param libFilePath
  228.      * @param osName
  229.      * @param libName
  230.      *
  231.      * @since 0.8
  232.      */
  233.     private static boolean extractLib(String libFilePath, String osName, String libName) {
  234.         boolean returnValue = false;
  235.         File libFile = new File(libFilePath);
  236.         InputStream input = null;
  237.         FileOutputStream output = null;
  238.         input = SerialNativeInterface.class.getResourceAsStream("/libs/" + osName + "/" + libName);
  239.         if(input != null){
  240.             int read;
  241.             byte[] buffer = new byte[4096];
  242.             try {
  243.                 output = new FileOutputStream(libFilePath);
  244.                 while((read = input.read(buffer)) != -1){
  245.                     output.write(buffer, 0, read);
  246.                 }
  247.                 output.close();
  248.                 input.close();
  249.                 returnValue = true;
  250.             }
  251.             catch (Exception ex) {
  252.                 try {
  253.                     output.close();
  254.                     if(libFile.exists()){
  255.                         libFile.delete();
  256.                     }
  257.                 }
  258.                 catch (Exception ex_out) {
  259.                     //Do nothing
  260.                 }
  261.                 try {
  262.                     input.close();
  263.                 }
  264.                 catch (Exception ex_in) {
  265.                     //Do nothing
  266.                 }
  267.             }
  268.         }
  269.         return returnValue;
  270.     }
  271.  
  272.     /**
  273.      * Get OS type (OS_LINUX || OS_WINDOWS || OS_SOLARIS)
  274.      *
  275.      * @since 0.8
  276.      */
  277.     public static int getOsType() {
  278.         return osType;
  279.     }
  280.  
  281.     /**
  282.      * Get jSSC version. The version of library is <b>Base Version</b> + <b>Minor Suffix</b>
  283.      *
  284.      * @since 0.8
  285.      */
  286.     public static String getLibraryVersion() {
  287.         return libVersion + "." + libMinorSuffix;
  288.     }
  289.  
  290.     /**
  291.      * Get jSSC Base Version
  292.      *
  293.      * @since 0.9.0
  294.      */
  295.     public static String getLibraryBaseVersion() {
  296.         return libVersion;
  297.     }
  298.  
  299.     /**
  300.      * Get jSSC minor suffix. For example in version 0.8.1 - <b>1</b> is a minor suffix
  301.      *
  302.      * @since 0.9.0
  303.      */
  304.     public static String getLibraryMinorSuffix() {
  305.         return libMinorSuffix;
  306.     }
  307.  
  308.     /**
  309.      * Get jSSC native library version
  310.      *
  311.      * @return native lib version (for jSSC-2.8.0 should be 2.8 for example)
  312.      *
  313.      * @since 2.8.0
  314.      */
  315.     public static native String getNativeLibraryVersion();
  316.  
  317.     /**
  318.      * Open port
  319.      *
  320.      * @param portName name of port for opening
  321.      * @param useTIOCEXCL enable/disable using of <b>TIOCEXCL</b>. Take effect only on *nix based systems
  322.      *
  323.      * @return handle of opened port or -1 if opening of the port was unsuccessful
  324.      */
  325.     public native long openPort(String portName, boolean useTIOCEXCL);
  326.  
  327.     /**
  328.      * Setting the parameters of opened port
  329.      *
  330.      * @param handle handle of opened port
  331.      * @param baudRate data transfer rate
  332.      * @param dataBits number of data bits
  333.      * @param stopBits number of stop bits
  334.      * @param parity parity
  335.      * @param setRTS initial state of RTS line (ON/OFF)
  336.      * @param setDTR initial state of DTR line (ON/OFF)
  337.      * @param flags additional Native settings. Take effect only on *nix based systems
  338.      *
  339.      * @return If the operation is successfully completed, the method returns true, otherwise false
  340.      */
  341.     public native boolean setParams(long handle, int baudRate, int dataBits, int stopBits, int parity, boolean setRTS, boolean setDTR, int flags);
  342.  
  343.     /**
  344.      * Purge of input and output buffer
  345.      *
  346.      * @param handle handle of opened port
  347.      * @param flags flags specifying required actions for purgePort method
  348.      *
  349.      * @return If the operation is successfully completed, the method returns true, otherwise false
  350.      */
  351.     public native boolean purgePort(long handle, int flags);
  352.  
  353.     /**
  354.      * Close port
  355.      *
  356.      * @param handle handle of opened port
  357.      *
  358.      * @return If the operation is successfully completed, the method returns true, otherwise false
  359.      */
  360.     public native boolean closePort(long handle);
  361.  
  362.     /**
  363.      * Set events mask
  364.      *
  365.      * @param handle handle of opened port
  366.      * @param mask events mask
  367.      *
  368.      * @return If the operation is successfully completed, the method returns true, otherwise false
  369.      */
  370.     public native boolean setEventsMask(long handle, int mask);
  371.  
  372.     /**
  373.      * Get events mask
  374.      *
  375.      * @param handle handle of opened port
  376.      *
  377.      * @return Method returns event mask as a variable of <b>int</b> type
  378.      */
  379.     public native int getEventsMask(long handle);
  380.  
  381.     /**
  382.      * Wait events
  383.      *
  384.      * @param handle handle of opened port
  385.      *
  386.      * @return Method returns two-dimensional array containing event types and their values
  387.      * (<b>events[i][0] - event type</b>, <b>events[i][1] - event value</b>).
  388.      */
  389.     public native int[][] waitEvents(long handle);
  390.  
  391.     /**
  392.      * Change RTS line state
  393.      *
  394.      * @param handle handle of opened port
  395.      * @param value <b>true - ON</b>, <b>false - OFF</b>
  396.      *
  397.      * @return If the operation is successfully completed, the method returns true, otherwise false
  398.      */
  399.     public native boolean setRTS(long handle, boolean value);
  400.  
  401.     /**
  402.      * Change DTR line state
  403.      *
  404.      * @param handle handle of opened port
  405.      * @param value <b>true - ON</b>, <b>false - OFF</b>
  406.      *
  407.      * @return If the operation is successfully completed, the method returns true, otherwise false
  408.      */
  409.     public native boolean setDTR(long handle, boolean value);
  410.  
  411.     /**
  412.      * Read data from port
  413.      *
  414.      * @param handle handle of opened port
  415.      * @param byteCount count of bytes required to read
  416.      *
  417.      * @return Method returns the array of read bytes
  418.      */
  419.     public native byte[] readBytes(long handle, int byteCount);
  420.  
  421.     /**
  422.      * Write data to port
  423.      *
  424.      * @param handle handle of opened port
  425.      * @param buffer array of bytes to write
  426.      *
  427.      * @return If the operation is successfully completed, the method returns true, otherwise false
  428.      */
  429.     public native boolean writeBytes(long handle, byte[] buffer);
  430.  
  431.     /**
  432.      * Get bytes count in buffers of port
  433.      *
  434.      * @param handle handle of opened port
  435.      *
  436.      * @return Method returns the array that contains info about bytes count in buffers:
  437.      * <br><b>element 0</b> - input buffer</br>
  438.      * <br><b>element 1</b> - output buffer</br>
  439.      *
  440.      * @since 0.8
  441.      */
  442.     public native int[] getBuffersBytesCount(long handle);
  443.  
  444.     /**
  445.      * Set flow control mode
  446.      *
  447.      * @param handle handle of opened port
  448.      * @param mask mask of flow control mode
  449.      *
  450.      * @return If the operation is successfully completed, the method returns true, otherwise false
  451.      *
  452.      * @since 0.8
  453.      */
  454.     public native boolean setFlowControlMode(long handle, int mask);
  455.  
  456.     /**
  457.      * Get flow control mode
  458.      *
  459.      * @param handle handle of opened port
  460.      *
  461.      * @return Mask of setted flow control mode
  462.      *
  463.      * @since 0.8
  464.      */
  465.     public native int getFlowControlMode(long handle);
  466.  
  467.     /**
  468.      * Get serial port names like an array of String
  469.      *
  470.      * @return unsorted array of String with port names
  471.      */
  472.     public native String[] getSerialPortNames();
  473.  
  474.     /**
  475.      * Getting lines states
  476.      *
  477.      * @param handle handle of opened port
  478.      *
  479.      * @return Method returns the array containing information about lines in following order:
  480.      * <br><b>element 0</b> - <b>CTS</b> line state</br>
  481.      * <br><b>element 1</b> - <b>DSR</b> line state</br>
  482.      * <br><b>element 2</b> - <b>RING</b> line state</br>
  483.      * <br><b>element 3</b> - <b>RLSD</b> line state</br>
  484.      */
  485.     public native int[] getLinesStatus(long handle);
  486.  
  487.     /**
  488.      * Send Break singnal for setted duration
  489.      *
  490.      * @param handle handle of opened port
  491.      * @param duration duration of Break signal
  492.      * @return If the operation is successfully completed, the method returns true, otherwise false
  493.      *
  494.      * @since 0.8
  495.      */
  496.     public native boolean sendBreak(long handle, int duration);
  497. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement