I have installed a python server on my robot and also create a socket to robot successfully. Everything is looking fine but when I want to create a channel I have an error that says:
sending naocom/start.sh
W/System.err: bash: naocom/start.sh: Permission denied
here is where I tried to start connection and start python server with
public Map<String, Integer> sendSSHCommands(String[] aCommands, String... aInput){
// Connect to ssh server
Session vSession = connectSSH();
Map<String, Integer> vExitStatus = new HashMap<String, Integer>();
if( vSession != null){
// execute commands
for( int i=0; i < aCommands.length; i++ ){
String cmd = aCommands[i];
try{
// open channel
Channel vChannel = vSession.openChannel("naocom/start.sh");
ChannelExec vChannelExec = (ChannelExec) vChannel;
OutputStream vOutStream = vChannel.getOutputStream();
vChannelExec.setCommand(cmd);
vChannelExec.setOutputStream(System.out);
vChannelExec.setErrStream(System.err);
// connect
Log.i(TAG, "sending " + cmd);
vChannel.connect();
// get user information
SharedPreferences vPreferences = MainActivity.getPreferences();
// wait for command to complete
while( !vChannel.isClosed() ){
try {
Thread.sleep(100);
} catch (InterruptedException e) {}
};
// add exit status
vExitStatus.put( cmd, vChannel.getExitStatus() );
vOutStream.close();
vChannel.disconnect();
} catch(JSchException e){
Log.e(TAG, e.getMessage());
} catch (IOException e) {
Log.e(TAG, e.getMessage());
e.printStackTrace();
}
}
// close ssh connection
closeSSH(vSession);
}
return vExitStatus;
}
when I debuged my code I found it happend when start(); in Channel.java called
public void connect() throws JSchException{
connect(0);
}
public void connect(int connectTimeout) throws JSchException{
this.connectTimeout=connectTimeout;
try{
sendChannelOpen();
start(); //here i have an error
}
catch(Exception e){
connected=false;
disconnect();
if(e instanceof JSchException)
throw (JSchException)e;
throw new JSchException(e.toString(), e);
}
}
Related
I've been facing this issue while connecting OBDII devices. This issue's occurrence is very random varied across cheap Chinese OBD devices to expensive branded ones.
For Bluetooth communication in flutter, I'm using the Flutter Bluetooth Serial package https://pub.dev/packages/flutter_bluetooth_serial
What I'm doing is initially creating a socket via createRfcommSocketToServiceRecord method. When IOException occurs, then the socket is created via createRfcommSocket reflection method. If still, the IOException occurs, then the Input and Output streams and socket are closed manually and then the connection is tried again. I try connection a total of 3 times.
Here is the connect function which I changed in the package.
public void connect() throws IOException {
if (isConnected()) {
throw new IOException("already connected");
}
BluetoothSocket fallbackSocket = null;
boolean isConnectionEstablished = false;
BluetoothDevice device = bluetoothAdapter.getRemoteDevice(mRemoteAddress);
if (device == null) {
throw new IOException("device not found");
}
mBluetoothSocket = device.createRfcommSocketToServiceRecord(DEFAULT_UUID); // #TODO . introduce ConnectionMethod
if (mBluetoothSocket == null) {
throw new IOException("socket connection not established");
}
// Cancel discovery, even though we didn't start it
bluetoothAdapter.cancelDiscovery();
if (mFirstConnection == 0)
mFirstConnection = 1;
try {
mBluetoothSocket.connect();
isConnectionEstablished = true;
} catch (IOException ioException) {
Log.e(TAG, "IO exception: " + ioException.getMessage());
try {
Class<?> clazz = mBluetoothSocket.getRemoteDevice().getClass();
Class<?>[] paramTypes = new Class<?>[] {Integer.TYPE};
Method m = clazz.getMethod("createRfcommSocket", paramTypes);
Object[] params = new Object[] {Integer.valueOf(1)};
mFallBackSocket = (BluetoothSocket)m.invoke(mBluetoothSocket.getRemoteDevice(), params);
mBluetoothSocket = mFallBackSocket;
if (mBluetoothSocket != null) {
mBluetoothSocket.connect();
isConnectionEstablished = true;
}else{
Log.d(TAG, "fallback_socket received null....: " + mBluetoothSocket);
}
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException | IOException e) {
Log.e(TAG, "exception_in_code....: " + e);
e.printStackTrace();
}
}
if (isConnectionEstablished) {
connectionThread = new ConnectionThread(mBluetoothSocket);
connectionThread.start();
} else {
if (mFirstConnection == 1) {
mFirstConnection = 2;
resetFallBackSocket();
reconnectSocket();
} else if (mFirstConnection == 2) {
mFirstConnection = 3;
resetFallBackSocket();
reconnectSocket();
} else {
mFirstConnection = 0;
resetFallBackSocket();
throw new IOException("socket connection not established...");
}
}
}
public void resetFallBackSocket() {
mFallBackSocket = null;
}
reconnectSocket is the function in which the Input and Output streams and Socket is closed manually and connection is tried again.
public void reconnectSocket() throws IOException {
Log.e(TAG, "debug13. Reconnection Bluetooth socket..");
dataLogsFinal = dataLogsFinal + "debug13. Reconnection Bluetooth socket..$";
Log.d(TAG, "Reconnection Bluetooth socket...");
if (mBluetoothSocket == null)
throw new IOException("Bluetooth Socket is NULL!" + dataLogsFinal);
StringBuilder errorBuilder = new StringBuilder();
try {
mBluetoothSocket.getInputStream().close();
} catch (IOException | NullPointerException e) {
e.printStackTrace();
Log.e(TAG, "Error closing input stream: " + e.getMessage());
errorBuilder.append("Error closing input stream: ").append(e.getMessage()).append(" | ");
}
try {
mBluetoothSocket.getOutputStream().close();
} catch (IOException | NullPointerException e) {
e.printStackTrace();
Log.e(TAG, "Error closing output stream: " + e.getMessage());
errorBuilder.append("Error closing output stream: ").append(e.getMessage()).append(" | ");
}
try {
mBluetoothSocket.close();
Thread.sleep(1000);
} catch (IOException | InterruptedException | NullPointerException e) {
e.printStackTrace();
Log.e(TAG, "Error closing bluetooth socket: " + e.getMessage());
errorBuilder.append("Error closing bluetooth socket: ").append(e.getMessage()).append(" | ");
}
try {
connect();
} catch (IOException e) {
e.printStackTrace();
Log.e(TAG, "Error starting service: " + e.getMessage());
errorBuilder.append("Error starting service: ").append(e.getMessage());
throw new IOException(errorBuilder.toString());
}
}
I've tried changing the channel value for the port ranging from 1-5 for the reflection method.
Port-1:- Most of the time the connection gets created.
Port-2:- As soon as the device gets connected, it gets disconnected.
Port-3:- Device gets connected but unexpected responses are received.
Port-4:- java.io.IOException: bt socket closed, read return: -1
Port-5:- java.io.IOException: bt socket closed, read return: -1
How do we figure out that port number has to be used for creating the connection via the reflection method?
Previously we had faced a similar kind of issue with the native android app and the issue was resolved with the help of the exact same methods which I've mentioned above.
With all the possible tries, now ran out of ideas. Any help will be very much appreciated.
Thanks
I am new to using the Xirsys API for Android. I have followed the tutorial ("Learning WebRTC Getting Started"), but one thing I am noticing is that the 'users' message I get from SYS keeps growing, with duplicates of the same name I am using for my tests (presumably because I am connecting multiple times as I am trying out the APIs). Here is an example message:
{"m":{"f":"StayingInTouch/__sys__","o":"peers","t":null},"p":{"users":["tad#gmail.com","tad#gmail.com","tad#gmail.com","tad#gmail.com","tad#gmail.com","tad#gmail.com","tad#gmail.com","tad#gmail.com","tad#gmail.com","tad"]},"t":"u"}
Is there something I am supposed to do other than close the various resources in order to have Xirsys remove that user from its internal list?
I start by issuing a PUT via Volley to get the token, then follow that up with a GET via Volley to get the signalling host Url, then open the socket:
okhttp3.Request request = new okhttp3.Request.Builder().url(hostValue + "/v2/" + mToken).build();
ws = client.newWebSocket(request, socketListener);
All that works just fine, and I am able to signal back and forth.
Here is my onDestroy():
protected void onDestroy() {
shutDownResources();
try {
client.dispatcher().executorService().shutdown();
} catch (Exception e) {
myLog("Error shutting down socket client: " + e.getMessage());
}
mQueue.cancelAll(null);
mQueue.stop();
super.onDestroy();
}
And here is the shutDownResources() method:
private void shutDownResources() {
if ( localDataChannel != null ) {
try {
localDataChannel.unregisterObserver();
localObserver = null;
localDataChannel.close();
localDataChannel.dispose();
localDataChannel = null;
} catch (Exception e) {
myLog( "Error closing local data channel:" + e.getMessage());
}
}
if ( localPeer != null ) {
try {
localPeer.close();
localPeer.dispose();
localPeer = null;
} catch (Exception e) {
myLog( "Error closing peer:" + e.getMessage());
}
}
if ( ws != null ) {
try {
ws.cancel();
ws = null;
} catch (Exception e) {
myLog( "Error shutting down socket client: " + e.getMessage());
}
}
iceServers = null;
iceServerMap.clear();
}
There is a python server in my pepper robot and it works fine on the machine. I use putty to start the server and ncat to send my command and there is no problem at all.
In my Connection fragment I need to create a channel to send an ssh command to robot to start the server and then I need to create socket to the server. Then when I send a package to connect server to the application with this command: {'command': '< SYS_CONNECT>'}
In response server should send some information about robot like name, battery level and etc. BUT i just got null from server.
There is application used to run in anroid 5.1 and some years before. Now I deceided to create new application and import some class and components from old application.
private boolean connect(){
state = ConnectionState.CONNECTION_INIT;
for( String h : hostAdresses ){
try{
host = h;
// create socket
socket = new Socket( InetAddress.getByName(host).getHostAddress(), port );
socket.setSoTimeout(defaultReadTimeout);
in = new BufferedReader( new InputStreamReader( new BufferedInputStream(socket.getInputStream()) ) );
out = socket.getOutputStream();
// try to connect
int tries = connectionMaxTries;
while(!stop && socket != null && state == ConnectionState.CONNECTION_INIT && tries > 0) {
// send connection request
DataRequestPackage p = new DataRequestPackage(
PepperCommands.SYS_CONNECT,
new String[0]);
String data = gson.toJson(p);
// wait for data
//data = in.readLine();
try {
out.write(data.getBytes());
Log.w(TAG, "Sending data =" + data);
StringBuilder sb = new StringBuilder();
while ((data = in.readLine()) != null) {
sb.append(data);
Log.d(TAG, "loop data");
}
data = sb.toString();
} catch (Exception e) {
Log.d(TAG, "error on reading data");
}
Log.w(TAG, "Receiving data = " + data);
Log.w(TAG, "in.readLine(), data = " + in.readLine());
DataResponsePackage response = gson.fromJson(data, DataResponsePackage.class);
if( response.request.command == PepperCommands.SYS_CONNECT
&& response.requestSuccessfull){
state = ConnectionState.CONNECTION_ESTABLISHED;
notifyDataRecievedListeners(response);
return true;
}
tries--;
}
}catch(UnknownHostException e){
state = ConnectionState.CONNECTION_UNKNOWN_HOST;
Log.w(TAG, "Host unknown " + host);
MainActivity.getInstance().runOnUiThread( new Runnable() {
#Override
public void run() {
Toast.makeText(MainActivity.getInstance().getApplicationContext(),
R.string.net_unknown_host, Toast.LENGTH_SHORT).show();
}
});
} catch (IOException e) {
state = ConnectionState.CONNECTION_ESTABLISHED_FAILED;
Log.w(TAG, "IO Exception on connnection with " + host + ":" + port);
}
}
return false;
}
Tries to start remote server using ssh.
/**
* Tries to start remote server using ssh.
* #return {#code true} if server started, {#code false} otherwise.
*/
private boolean sshServerStart(){
// show message
MainActivity.getInstance().runOnUiThread( new Runnable() {
#Override
public void run() {
Toast.makeText(MainActivity.getInstance().getApplicationContext(),
R.string.net_try_server_start, Toast.LENGTH_SHORT).show();
}
});
// send command
String[] vCommands = new String[]{ SSH_COMMAND_SERVER_START };
if( sendSSHCommands( vCommands ).size() > 0 ){
// wait a few seconds for server to start
try {
Thread.sleep(5000);
} catch (InterruptedException e) {}
return true;
}
return false;
}
Connecting to ssh server
/**
* Connecting to ssh server
* #return {#code true} if successful connected, {#code false} otherwise.
*/
private Session connectSSH(){
for( String host : hostAdresses ){
try {
// get user information
SharedPreferences vPreferences = MainActivity.getPreferences();
String vUser = vPreferences.getString(PREFERENCES_SSH_USER, "nao");
String vPassword = vPreferences.getString(PREFERENCES_SSH_PASSWORD, "nao");
if( mUseCustomLoginData ){
vUser = mSSHUser;
vPassword = mSSHPassword;
}
// create session
Session vSession = mSSH.getSession(vUser,
InetAddress.getByName(host).getHostAddress().toString(),
22 );
vSession.setPassword( vPassword );
// avoid asking for key auth
Properties vProperties = new Properties();
vProperties.put("StrictHostKeyChecking", "no");
vSession.setConfig(vProperties);
try{
// connect to ssh server
vSession.connect();
} catch( JSchException err ){
if( err.getMessage().contains("Auth fail") ){
// ask for custom login data
if( askForCustomLoginData() ){
vSession = connectSSH();
} else {
return null;
}
} else {
System.out.println("EXCEPTION: " + err.getMessage());
err.printStackTrace();
}
}
return vSession;
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (JSchException e) {
e.printStackTrace();
}
}
return null;
}
I expect on this code response.request.command return SYS_CONNECT and response.requestSuccessfull return true on this line but I got unexpected null response
if( response.request.command == PepperCommands.SYS_CONNECT && response.requestSuccessfull){
Good day.Im trying to connect to server with socket.Here is my code on how i do it.
private class SocketConnection extends AsyncTask<String, String, String> {
PrintWriter out;
BufferedReader in;
#Override
protected String doInBackground(String... params) {
connect();
try {
out = new PrintWriter(clientSocket.getOutputStream());
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
} catch (IOException ex) {
System.out.append("error").append("socketcoonection").println();
}
String msg = null;
try {
msg = in.readLine();
} catch (IOException e) {
e.printStackTrace();
}
while (run) {
System.out.append(msg).append("socketcoonection").println();
out.println();
out.flush();
/*try {
msg = in.readLine();
} catch (IOException ex) {
Logger.getLogger(MainActivity.class.getName()).log(Level.SEVERE, null, ex);
}*/
}
return null;
}
}
and here is the connect() method
public void connect() {
try {
clientSocket = new Socket("vaenterprises.org/test.php", 8080);
} catch (UnknownHostException ex) {
} catch (IOException ex) {
}
if (clientSocket != null) {
run = true;
}
}
and this is the server side php code of test.php
echo json_encode("socket working");
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
and the address link is vaenterprises.org/test/php so im trying to connect to it and read the input or output stream or the echo.Whatever i do,i get nullPointerException at System.out.append(msg).append("socketcoonection").println(); and during debug i figured out that its socket which is null...Please tell me what am i doing wrong?
I am a complete noob at Android, only at the level of basic (1 or 2 line) Activities activated by buttons, but I would like to create a really simple app that, when I tap the app icon, it fires and forgets a message to a listening server on my Windows 8 PC. The phone is connected as a simple media device, without Kies, via a USB cable.
I can get as far as a message box lying and saying the message was sent. I need to know what kind of comms channel to use, e.g. a COM port or what, and how to send data over that from Android. On the Windows side, once I've established how to communicate, I can help myself.
starting with the desktop side of this application:
You can use the ADB (Android debug bridge) to establish a tcp/ip socket connection via port between the device and desktop. The command is :
adb forward tcp:<port-number> tcp:<port-number>
to run this command in your java program, you will have to create a process builder wherein this command ets executed on a child shell.
For windows you may need to use:
process=Runtime.getRuntime().exec("D:\\Android\\adt-bundle-windows-x86_64-20130729\\sdk\\platform-tools\\adb.exe forward tcp:38300 tcp:38300");
sc = new Scanner(process.getErrorStream());
if (sc.hasNext())
{
while (sc.hasNext())
System.out.print(sc.next()+" ");
System.out.println("\nCannot start the Android debug bridge");
}
sc.close();
}
The function required to execute adb commands :
String[] commands = new String[]{"/bin/sh","-c", command};
try {
Process proc = new ProcessBuilder(commands).start();
BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
String s = null;
while ((s = stdInput.readLine()) != null)
{
sb.append(s);
sb.append("\n");
}
while ((s = stdError.readLine()) != null)
{
sb.append(s);
sb.append("\n");
}
} catch (IOException e) {
e.printStackTrace();
}
Above method will take the above command as a string and execute it on a child shell
//Extracting Device Id through ADB
device_list=CommandExecutor.execute("adb devices").split("\\r?\\n");
System.out.println(device_list);
if(device_list.length>1)
{
if(device_list[1].matches(".*\\d.*"))
{
device_id=device_list[1].split("\\s+");
device_name=""+CommandExecutor.execute("adb -s "+device_id[0]+" shell getprop ro.product.manufacturer")+CommandExecutor.execute("adb -s "+device_id[0]+" shell getprop ro.product.model");
device_name=device_name.replaceAll("\\s+"," ");
System.out.println("\n"+device_name+" : "+device_id[0]);
device=device_id[0];
System.out.println("\n"+device);
}
else
{
System.out.println("Please attach a device");
}
}
else
{
System.out.println("Please attach a device");
}
CommandExecutor is a class which has the execute method in it. The code of the execute method is the same as posted above.
This will check if any device is connected and if it connected, it will return it unique id number.
It is preferable to use id number while executing adb commands like :
adb -s "+device_id[0]+" shell getprop ro.product.manufacturer
OR
adb -s <put-id-here> shell getprop ro.product.manufacturer
Note that '-s' is necesarry after adb.
Then using adb forward commnd you need to establish a tcp/ip socket. Here the desktop will be the client and mobile/device will be the server.
//Create socket connection
try{
socket = new Socket("localhost", 38300);
System.out.println("Socket Created");
out = new PrintWriter(socket.getOutputStream(), true);
out.println("Hey Server!\n");
new Thread(readFromServer).start();
Thread closeSocketOnShutdown = new Thread() {
public void run() {
try {
socket.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
};
Runtime.getRuntime().addShutdownHook(closeSocketOnShutdown);
}
catch (UnknownHostException e) {
System.out.println("Socket connection problem (Unknown host)"+e.getStackTrace());
} catch (IOException e) {
System.out.println("Could not initialize I/O on socket "+e.getStackTrace());
}
Then you need read from the server i.e. the device :
private Runnable readFromServer = new Runnable() {
#Override
public void run() {
try {
System.out.println("Reading From Server");
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while ((buffer=in.readLine())!=null) {
System.out.println(buffer);
}catch (IOException e) {
try {
in.close();
} catch (IOException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}
}
The 'buffer' will contain what device will send from its end of the app.
Now in your mobile application,you will need to open the same connection and siple write data to it out buffer
public class TcpConnection implements Runnable {
public static final int TIMEOUT=10;
private String connectionStatus=null;
private Handler mHandler;
private ServerSocket server=null;
private Context context;
private Socket client=null;
private String line="";
BufferedReader socketIn;
PrintWriter socketOut;
public TcpConnection(Context c) {
// TODO Auto-generated constructor stub
context=c;
mHandler=new Handler();
}
#Override
public void run() {
// TODO Auto-generated method stub
// initialize server socket
try {
server = new ServerSocket(38300);
server.setSoTimeout(TIMEOUT*1000);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
//attempt to accept a connection
try{
client = server.accept();
socketOut = new PrintWriter(client.getOutputStream(), true);
socketOut.println("Hey Client!\n");
socketOut.flush();
syncContacts();
Thread readThread = new Thread(readFromClient);
readThread.setPriority(Thread.MAX_PRIORITY);
readThread.start();
Log.e(TAG, "Sent");
}
catch (SocketTimeoutException e) {
// print out TIMEOUT
connectionStatus="Connection has timed out! Please try again";
mHandler.post(showConnectionStatus);
try {
server.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
catch (IOException e) {
Log.e(TAG, ""+e);
}
if (client!=null) {
try{
// print out success
connectionStatus="Connection succesful!";
Log.e(TAG, connectionStatus);
mHandler.post(showConnectionStatus);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
private Runnable readFromClient = new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
try {
Log.e(TAG, "Reading from server");
socketIn=new BufferedReader(new InputStreamReader(client.getInputStream()));
while ((line = socketIn.readLine()) != null) {
Log.d("ServerActivity", line);
//Do something with line
}
socketIn.close();
closeAll();
Log.e(TAG, "OUT OF WHILE");
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
public void closeAll() {
// TODO Auto-generated method stub
try {
Log.e(TAG, "Closing All");
socketOut.close();
client.close();
server.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private Runnable showConnectionStatus = new Runnable() {
public void run() {
try
{
Toast.makeText(context, connectionStatus, Toast.LENGTH_SHORT).show();
}
catch(Exception e)
{
e.printStackTrace();
}
}
};
}
}
Using Managed.adb in c#
AndroidDebugBridge bridge = AndroidDebugBridge.
CreateBridge(#"C:\Users\bla\AppData\Local\Android\Sdk\platform-tools\adb.exe", true);
List<Device> devices = AdbHelper.Instance.
GetDevices(AndroidDebugBridge.SocketAddress);
devices[0].CreateForward(38300, 38300);
Then create a server socket on android to that port.
server = new ServerSocket(38300);
server.setSoTimeout(TIMEOUT * 1000);
socket = server.accept();
and client socket on C#
TcpClient clientSocket = new System.Net.Sockets.TcpClient();
clientSocket.Connect("127.0.0.1", 38300);