--- /dev/null
+/**\r
+ * Created by Tak and Bowon on 17. 7. 21.\r
+ * SSH class can be used to make ssh connections and send command lines\r
+ */\r
+\r
+package com.example.lede2;\r
+\r
+import android.content.Context;\r
+import android.util.Log;\r
+import android.os.AsyncTask;\r
+\r
+import com.jcraft.jsch.JSch;\r
+import com.jcraft.jsch.JSchException;\r
+import com.jcraft.jsch.Session;\r
+import com.jcraft.jsch.ChannelExec;\r
+import com.jcraft.jsch.Channel;\r
+\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+import java.lang.String;\r
+import java.util.ArrayList;\r
+import java.util.Arrays;\r
+import java.util.List;\r
+\r
+//import android.provider.Settings;\r
+//import android.support.v7.app.AppCompatActivity;\r
+//import android.os.Bundle;\r
+//import java.io.ByteArrayOutputStream;\r
+//import java.util.Properties;\r
+//import java.io.PrintStream;\r
+\r
+// AsyncTask input : command line\r
+// AysncTask output : output from a command\r
+public class SSH extends AsyncTask<String, Void, List<String>> {\r
+\r
+ // variables used for connection\r
+ Session session;\r
+ Channel channel;\r
+ ChannelExec ce;\r
+ // in this project, we supposed we use fixed host, username, password\r
+ String host;\r
+ String username;\r
+ String password;\r
+\r
+ // host, username, password initialize\r
+ @Override\r
+ protected void onPreExecute() {\r
+ super.onPreExecute();\r
+\r
+ host = ConfigActivity.ROUTERIP;\r
+ username = ConfigActivity.ROUTERUSER;\r
+ password = ConfigActivity.RPWD;\r
+ }\r
+\r
+ /* \r
+ The functions below are mainly from :\r
+ https://stackoverflow.com/questions/25789245/how-to-get-jsch-shell-command-output-in-string\r
+ */\r
+\r
+\r
+ // open the conenction using username, password, and hostname\r
+ public boolean open() throws JSchException {\r
+\r
+ JSch jSch = new JSch();\r
+\r
+ session = jSch.getSession(username, host, 22);\r
+ java.util.Properties config = new java.util.Properties();\r
+ config.put("StrictHostKeyChecking", "no"); // not recommended\r
+ session.setPassword(password);\r
+ session.setConfig(config);\r
+\r
+\r
+ Log.d("SSH CONNECT OPEN", "Connecting SSH to " + host + " - Please wait for few seconds... ");\r
+ session.connect();\r
+ if (session.isConnected()) {\r
+ Log.d("SSH CONNECT", "router connected!");\r
+ return true;\r
+ } else {\r
+ Log.d("SSH NOT CONNECT", "router NOT connected!");\r
+ return false;\r
+ }\r
+ }\r
+\r
+ // send a command\r
+ public void runCommand(String command) throws JSchException, IOException {\r
+\r
+ if (!session.isConnected())\r
+ throw new RuntimeException("Not connected to an open session. Call open() first!");\r
+\r
+ channel = session.openChannel("exec");\r
+ ce = (ChannelExec) channel;\r
+ ce.setCommand(command);\r
+ ce.connect();\r
+ Log.d("SSH RUN COMMAND", command);\r
+ }\r
+\r
+ // get output from a command\r
+ private List<String> getChannelOutput(Channel channel) throws IOException {\r
+\r
+ byte[] buffer = new byte[1024];\r
+ List<String> output_lines = new ArrayList<String>();\r
+ try {\r
+ InputStream in = channel.getInputStream();\r
+ String line = new String();\r
+ while (true) {\r
+ while (in.available() > 0) {\r
+ int i = in.read(buffer, 0, 1024);\r
+ if (i < 0) {\r
+ break;\r
+ }\r
+ line = new String(buffer, 0, i);\r
+ // add the read line to the return value list.\r
+ output_lines = new ArrayList(Arrays.asList(line.split("\\n")));\r
+ }\r
+\r
+ if(line.contains("logout")) {\r
+ break;\r
+ }\r
+ if (channel.isClosed()) {\r
+ break;\r
+ }\r
+ try {\r
+ Thread.sleep(1000);\r
+ } catch (Exception ee){}\r
+ }\r
+ } catch(Exception e) {\r
+ Log.d("SSH READOUTPUT ERROR", "Error while reading channel output: "+ e);\r
+ }\r
+\r
+ return output_lines;\r
+ }\r
+\r
+\r
+ /*\r
+ usage :\r
+ 0. params == "-ch <password>" : change default password into <password>\r
+ 1. params == "-co <password>" : add device to the database and hostapd file\r
+ 2. params == "-dn <password>" : delete devices by their names\r
+ 3. params == "-ln <password>" : list devices' names\r
+ */\r
+ @Override\r
+ protected List<String> doInBackground(String... params) {\r
+\r
+ List<String> result_lines = new ArrayList<String>();\r
+ String cmd;\r
+\r
+ if(params[0].substring(0,3).equals("-ch")) { // ./change_default_pw.sh -ch <password>\r
+ cmd = MainActivity.DEF_CHANGE_DEFAULT_SCRIPT + " " + params[0];\r
+ } else if(params[0].substring(0,3).equals("-co")) { // ./connect_device.sh -co <password> <device-name>\r
+ cmd = MainActivity.DEF_CONNECT_DEVICE_SCRIPT + " " + params[0];\r
+ } else if(params[0].substring(0,3).equals("-dn")) { // ./register_device.sh -dn <devcie-name>\r
+ cmd = MainActivity.DEF_REGISTER_DEVICE_SCRIPT + " " + params[0];\r
+ } else if(params[0].substring(0,3).equals("-ln")) { // ./register_device.sh -ln <devcie-name>\r
+ // below block is a little different from others cause it needs to get output from the router\r
+ try {\r
+ // try open the connection\r
+ if (!open()) {\r
+ Log.d("SSH CONNECTION CLOSE", "open failed.");\r
+ return null;\r
+ }\r
+ cmd = MainActivity.DEF_REGISTER_DEVICE_SCRIPT + " " + params[0];\r
+ runCommand(cmd);\r
+ ce.setCommand(cmd);\r
+ ce.connect();\r
+ result_lines = getChannelOutput(ce);\r
+ } catch (Exception e) {\r
+ }\r
+ channel.disconnect();\r
+\r
+ // only this block return meaningful value, which should be the names of devices.\r
+ return result_lines;\r
+ } else {\r
+ Log.d("SSH PARAM ERROR", "Wrong parameter used.");\r
+ return null;\r
+ }\r
+\r
+ // now the command is set, so send it.\r
+ try {\r
+ // try open the connection\r
+ if (!open()) {\r
+ Log.d("SSH CONNECTION CLOSE", "open failed.");\r
+ return null;\r
+ }\r
+ runCommand(cmd);\r
+ ce.setCommand(cmd);\r
+ ce.connect();\r
+ } catch (Exception e) {\r
+ } // done\r
+\r
+ channel.disconnect();\r
+ return null;\r
+ }\r
+\r
+ /*\r
+ @Override\r
+ protected onPostExecute(Void param) {\r
+ Log.d("POST", "in post execute");\r
+ }\r
+ */\r
+}\r