'Andriod app crashes while calling Java.IO.FileDescriptor Open(String path, int baudrate, int flags);

I am new to xamarin. Developing app for ProDVX android 8.1.0 to switch LED lights i am following a sample written in java.

package android_serialport_api;

import android.util.Log;

import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class SerialPort {

    private static final String TAG = "SerialPort";

    /*
     * Do not remove or rename the field mFd: it is used by native method close();
     */
    private FileDescriptor mFd;
    private FileInputStream mFileInputStream;
    private FileOutputStream mFileOutputStream;

    public SerialPort(File device, int baudrate, int flags) throws SecurityException, IOException {

        /* Check access permission */
        if (!device.canRead() || !device.canWrite()) {
            try {
                /* Missing read/write permission, trying to chmod the file */
                Process su;
                su = Runtime.getRuntime().exec("/system/bin/su");
                String cmd = "chmod 666 " + device.getAbsolutePath() + "\n"
                        + "exit\n";
                su.getOutputStream().write(cmd.getBytes());
                if ((su.waitFor() != 0) || !device.canRead()
                        || !device.canWrite()) {
                    throw new SecurityException();
                }
            } catch (Exception e) {
                e.printStackTrace();
                throw new SecurityException();
            }
        }

        mFd = open(device.getAbsolutePath(), baudrate, flags);
        if (mFd == null) {
            Log.e(TAG, "native open returns null");
            throw new IOException();
        }
        mFileInputStream = new FileInputStream(mFd);
        mFileOutputStream = new FileOutputStream(mFd);
    }

    // Getters and setters
    public FileInputStream getFileInputStream() {
        return mFileInputStream;
    }

    public FileOutputStream getFileOutputStream() {
        return mFileOutputStream;
    }

    // JNI
    private native static FileDescriptor open(String path, int baudrate, int flags);
    public native void close();
    static {
        System.loadLibrary("serial_port");
    }

}

Now call these functions to switch LED

public void AllGreenOn() {                   //All Green the lights
        try {
            sp = new SerialPort(new File("/dev/ttyS1"), 115200, 0);
        } catch (IOException e) {
            e.printStackTrace();
        }
        new Thread(new Runnable() {
            @Override
            public void run() {
                if (lock == null) {
                    System.out.println("lock = null");
                } else {
                    try {
                        synchronized (lock) {
                            out = sp.getFileOutputStream();
                            AllGOnLamps();
                            out.close();
                            sp.close();
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }).run();
    }
private void AllGOnLamps() throws IOException {                   //All the Green lights
int num1 = 0x55;
int num2 = 0xaa;        
int numL = 0xfb;
        int numR = 0;
        int numB = 0;
        int numG = 0x70;
int num7 = 0x88;
        out.write(intToByteArray(num1));
        out.write(intToByteArray(num2));
        for (int i = 0; i < 52; i++) {
            out.write(intToByteArray(numL));
            out.write(intToByteArray(numB));
            out.write(intToByteArray(numR));
            out.write(intToByteArray(numG));
        }
        out.write(intToByteArray(num7));
    }

I am trying this into c# and my code is

public class SerialPort
    {
        private Java.IO.FileDescriptor mFd;
        private Java.IO.FileInputStream mFileInputStream;
        private Java.IO.FileOutputStream mFileOutputStream;
     
        //[System.Runtime.InteropServices.DllImport("serial_port.so")]
        //private static extern Java.IO.FileDescriptor Open(String path, int baudrate, int flags);
        
        
        public SerialPort(Java.IO.File device, int baudrate, int flags)
        {
            MainActivity.addDebug(" su beging: .....");
            
            if (!device.CanRead() || !device.CanWrite())
            {
                
                MainActivity.addDebug("process su started: .....");
                Java.Lang.Process su;
                su = Java.Lang.Runtime.GetRuntime().Exec("su");

                MainActivity.addDebug("process su made: .....");
                string cmd = "chmod 666 " + device.AbsolutePath + "\n" + "exit\n";
                su.OutputStream.Write(Encoding.ASCII.GetBytes(cmd));

                MainActivity.addDebug("chmod 666 written ..... ");
            }

            mFd = Open(device.AbsolutePath, baudrate, flags);
            
            if (mFd == null)
            {
                MainActivity.addDebug("mfd made");
                throw new Exception();
            }
            mFileInputStream = new Java.IO.FileInputStream(mFd);
            mFileOutputStream = new Java.IO.FileOutputStream(mFd);

        }
        public Java.IO.FileInputStream getFileInputStream()
        {
            return mFileInputStream;
        }
        public Java.IO.FileOutputStream getFileOutputStream()
        {
            return mFileOutputStream;
        }
        
    }

public void AllGreenOn()
        {
            try
            {
                sp = new SerialPort(new Java.IO.File("/dev/ttyS1"), 115200, 0);
                _out = sp.getFileOutputStream();
                AllGOnLamps();
                _out.Close();
                
            }
            catch (IOException e)
            {
                
            }
        }

private SerialPort sp;
private Java.IO.FileOutputStream _out = null;
public void AllGOnLamps()
{

    int num1 = 0x55;
    int num2 = 0xaa;        
    int numL = 0xfb;
    int numR = 0;
    int numB = 0;
    int numG = 0x70;
    int num7 = 0x88;

    _out.Write(intToByteArray(num1));
    _out.Write(intToByteArray(num2));
    MainActivity.addDebug("num1 written ..... ");

    for (int i = 0; i < 52; i++)
    {
        _out.Write(intToByteArray(numL));
        _out.Write(intToByteArray(numB));
        _out.Write(intToByteArray(numR));
        _out.Write(intToByteArray(numG));

    }

    _out.Write(intToByteArray(num7));
    MainActivity.addDebug("num7 written ..... ");


   

}

Now here mFd = Open(device.AbsolutePath, baudrate, flags); cause crash the app

I have no idea where i am doing wrong. Any suggestion or alternate to this will be highly appriciated.



Solution 1:[1]

There are a few things wrong with the C# code, I recommend looking at the source code for the original native library.

For example you should specify an entry point where the method name does not match the native method signature.

[System.Runtime.InteropServices.DllImport("serial_port", EntryPoint = "Java_android_1serialport_1api_SerialPort_open")]

https://github.com/cepr/android-serialport-api/blob/master/android-serialport-api/project/jni/SerialPort.c

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 monkeychew