Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to reuse a SSH (Jsch) session created in an AsyncTask in another class

I'm a Android & Java newbie and here is my situation:

I'm trying to create an app which connects to a Beaglebone Black using a ssh connection and then controls some peripherals connected to the BBB by issuing commands coming from an Android device. I'm opening (successfully) an ssh session in an AsyncTask while the user sees an splash screen, if the connection was successful the user will get a confirmation and then will be able to send predefined commands by clicking some available buttons.

What I want to do next is left the session opened and then create a new channel (exec or shell ) each time I wish to issue a command and wait for the response from the BBB, but I don´t know how to reuse such ssh session outside the AsynkTask.

is that even possible?

I'm using Android Studio 0.8.2 and Jsch 0.1.51, my code is as follows:

public class SplashScreen extends ActionBarActivity {

public static final int segundos =10;
public static final int milisegundos =segundos*1000;
public static  final int delay=2;
private ProgressBar pbprogreso;
@Override

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_splash_screen);
    pbprogreso= (ProgressBar)findViewById(R.id.pbprogreso);
    pbprogreso.setMax(maximo_progreso());
    empezaranimacion();
}

public void empezaranimacion()
{
    sshConnect task = new sshConnect();
    task.execute(new String[] {"http:"});

    new CountDownTimer(milisegundos,1000)

    {
        @Override
    public void onTick(long milisUntilFinished){
            pbprogreso.setProgress(establecer_progreso(milisUntilFinished));
        }
       @Override
    public void onFinish(){
           finish();
       }
    }.start();

}
public  int establecer_progreso (long miliseconds)
{
    return (int)((milisegundos-miliseconds)/1000);
}

public int maximo_progreso () {
    return segundos-delay;
}

public class sshConnect extends AsyncTask <String, Void, String>{
    ByteArrayOutputStream Baos=new ByteArrayOutputStream();
    ByteArrayInputStream Bais = new ByteArrayInputStream(new byte[1000]);
    @Override
    protected String doInBackground(String... data) {

        String host = "xxxxxxx";
        String user = "root";
        String pwd = "";
        int port = 22;
        JSch jsch = new JSch();
        try {
            Session session = jsch.getSession(user, host, port);
            session.setPassword(pwd);
            session.setConfig("StrictHostKeyChecking", "no");
            session.connect();

            ChannelExec channel = (ChannelExec)session.openChannel("exec");
            channel.setOutputStream(Baos);
            channel.setInputStream(Bais);
            //Run Command
            channel.setCommand("python ~/BBB_test/testconnect.py");
            channel.connect();
            try{Thread.sleep(3500);}catch (Exception ee){}
            channel.disconnect();
            //session.disconnect();
        }catch (Exception e){
            System.out.println(e.getMessage());
        }
        return Baos.toString();
    }
    @Override
    protected void onPostExecute(String result) {
        if (result.equals("Connected to BBB Baby!!\n")) {
            Intent nuevofrom = new Intent(SplashScreen.this, Principal.class);
            startActivity(nuevofrom);
            finish();
        } else {
            Intent newfrom = new Intent(SplashScreen.this, ConnecError.class);
            startActivity(newfrom);
            finish();

        }
    }
}

//Here is where I want to reuse the opened session and create a new channel

public class sendCommand extends AsyncTask <String, Void, String >{
    ByteArrayOutputStream Baosc=new ByteArrayOutputStream();
    ByteArrayInputStream Baisc = new ByteArrayInputStream(new byte[1000])

    protected String doInBackground (String... command){
        try {
            ChannelExec channel2 = (ChannelExec)session.openChannel("exec");
            channel2.setOutputStream(Baosc);
            channel2.setInputStream(Baisc);
            //Run Command
            channel2.setCommand("python ~/BBB_test/testgpio.py");
            channel2.connect();
            try{Thread.sleep(3500);}catch (Exception ee){}
            channel2.disconnect();


        }catch (Exception e) {
            System.out.println(e.getMessage());
        }
        return  Baosc.toString();
    }
    protected void onPostExecute(Long result) {
        TextView txt = (TextView) findViewById(R.id.infotext);
        txt.setText(result);

    }

}

If something else is needed let me know! (it is the first time I ask something in a forum)

Thanks a lot for your time and support!

like image 454
Laus23 Avatar asked Nov 01 '22 16:11

Laus23


1 Answers

I managed to get what I wanted by using the recommendation from DamienKnight of creating the session outside the Asynktask class. I create a public classwith three methods to create, return and disconnect the session:

public static class cSession {
        String host = "xxx.xxx.xxx.xxx";
        String user = "root";
        String pwd = "";
        int port = 22;
        JSch jsch = new JSch();
        public Session Met1 (){
            try {
                session = jsch.getSession(user, host, port);
                session.setPassword(pwd);
                session.setConfig("StrictHostKeyChecking", "no");
            } catch (Exception e2){
                System.out.println(e2.getMessage());
            }return session;
        }
        public Session damesession (){
            return session;
        }
        public void close_ses(){
            session.disconnect();
        }
    }

By doing this so, the creation of channels is flexible and I can use the methods from Jsch too.

public class sshConnect extends AsyncTask <String, Void, String>{
        ByteArrayOutputStream Baos=new ByteArrayOutputStream();
        ByteArrayInputStream Bais = new ByteArrayInputStream(new byte[1000]);


        @Override
        protected String doInBackground(String... data) {
            cSession jschses = new cSession();
            Session ses =null;
            ses = jschses.Met1();
            try {
                ses.connect();
                ChannelExec channel = (ChannelExec)ses.openChannel("exec");
                channel.setOutputStream(Baos);
                channel.setInputStream(Bais);
                //Run Command
                channel.setCommand("python ~/BBB_test/testconnect.py");
                channel.connect();
                try{Thread.sleep(3500);}catch (Exception ee){}
                channel.disconnect();
                //session.disconnect();
            }catch (Exception e){
                System.out.println(e.getMessage());
            }
            return Baos.toString();

        }

Thanks @Damienknight!

Regards

like image 115
Laus23 Avatar answered Nov 09 '22 12:11

Laus23