0

I'm trying to create a TCP/IP connection with a device that is running embedded linux, I'm using from android the USB tethering to have a ethernet connection between the Android device and the Embedded Linux device, I modified the embedded linux device to support RNDIS device driver.

The Android and the embedded linux device are working correctly, a ethernet conection was established succesfully, I can ping from embedded linux to android device and viceversa.

On my android application I created a simple service to establish a TCP/IP connection with the embedded linux device, the problem happens when I try to connect i got the following error:

02-17 13:53:13.300: E/TCP Client(2576): C: Connecting...
02-17 13:53:13.310: E/TCP Client(2576): C: Error
02-17 13:53:13.310: E/TCP Client(2576): java.net.SocketException: socket failed: EACCES (Permission denied)
02-17 13:53:13.310: E/TCP Client(2576):     at libcore.io.IoBridge.socket(IoBridge.java:583)
02-17 13:53:13.310: E/TCP Client(2576):     at java.net.PlainSocketImpl.create(PlainSocketImpl.java:201)
02-17 13:53:13.310: E/TCP Client(2576):     at java.net.Socket.startupSocket(Socket.java:559)
02-17 13:53:13.310: E/TCP Client(2576):     at java.net.Socket.<init>(Socket.java:225)
02-17 13:53:13.310: E/TCP Client(2576):     at com.example.service.TCPClientThread.run(TCPClientThread.java:75)
02-17 13:53:13.310: E/TCP Client(2576): Caused by: libcore.io.ErrnoException: socket failed: EACCES (Permission denied)
02-17 13:53:13.310: E/TCP Client(2576):     at libcore.io.Posix.socket(Native Method)
02-17 13:53:13.310: E/TCP Client(2576):     at libcore.io.BlockGuardOs.socket(BlockGuardOs.java:181)
02-17 13:53:13.310: E/TCP Client(2576):     at libcore.io.IoBridge.socket(IoBridge.java:568)
02-17 13:53:13.310: E/TCP Client(2576):     ... 4 more

I have configured my manifest as follows:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.dea600"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="18" />

    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.INTERNET" /> 
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/example"
        android:label="@string/appName" >
        <activity
            android:name="com.example.gui.mainActivity"
            android:configChanges="orientation|screenSize"
            android:screenOrientation="landscape"
            android:theme="@android:style/Theme.Holo.Light.DarkActionBar" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
                <category android:name="android.intent.category.HOME" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>

        <service
            android:name="com.example.service.TCPClientService"
            android:isolatedProcess="true"
            android:label="TCP Client Service"
            android:process=":TCPClientService" >
        </service>

        <receiver
            android:name="com.example.service.TCPStartClientService"
            android:enabled="true"
            android:exported="true" 
            android:process=":StartTCPService">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>

     </application>

</manifest>

The most extrange thing is if I use a Android VM (Genymotion) I'm able to connect and everithing works correctly, but when I try to use it on a real device I get the error.

Thank you in advance for any comment.

EDIT:

This is the code I'm using to create the binding, I'm using the port 6540, and the IP is 192.168.42.130

public void run() {           
    try {             
        //here you must put your computer's IP address.             
        InetAddress serverAddr = InetAddress.getByName(SERVERIP);               
        Log.e("TCP Client", "C: Connecting...");
        //create a socket to make the connection with the server             
        Connection = new Socket(serverAddr, SERVERPORT);
        Log.e("TCP Client", "C: Connected...");
        // Output Stream
        OutStream = new DataOutputStream((OutputStream)Connection.getOutputStream());
        // Input stream
        InStream = new DataInputStream((InputStream)Connection.getInputStream());

        while (ThreadStatus) {
            try {

                String message = myReadStream(InStream);
                if (message.length() > 0) {
                    Log.e("TCP Client", "Received message ... " + message);
                    if (mMessageListener != null){
                        mMessageListener.messageReceived(message);
                    }
                }
            } catch (Exception e) {      
                ThreadStatus = false;
                Log.e("TCP Client", "S: Error", e);               
            }
        }

    } catch (Exception e) {               
        Log.e("TCP Client", "C: Error", e);           
    }  finally {                 
        try {
            Connection.close();
            OutStream.close();
            InStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    if (mConnectionEndListener != null){
        mConnectionEndListener.notifyConnectionEnd();
    }

}       

I believe that when I try to create the socket the error occurs (Connection = new Socket(serverAddr, SERVERPORT);).

Maraku
  • 21
  • 1
  • 1
  • 5
  • Show us the socket creation and binding code and indicate the specific line of your code ultimately referenced in the abbreviated stack trace (look through it until it references your code). What port number and address are you trying to use? – Chris Stratton Feb 17 '14 at 20:37
  • Again, you need to read the full stack trace and identify the line *of your code* appearing therein. Also, don't just log the fact that there's been an error in your catch block, do an e.printStackTrace() – Chris Stratton Feb 17 '14 at 20:53
  • The most likely case here is that your network simply isn't routing between your devices, your connection is failing, and your code is not reporting that fact very clearly. – Chris Stratton Feb 17 '14 at 20:56
  • Hi Chris, I added the stack trace and basically it displays the same information, the line where the error is the one I commented in (com.example.service.TCPClientThread.run(TCPClientThread.java:75), when I try to create the connection **Connection = new Socket(serverAddr, SERVERPORT);**. Maybe I'm not getting exactly what else do you need. – Maraku Feb 17 '14 at 21:10
  • Thank you for your comments, I'll try to do some other testings, to be sure that the ethernet connection is working as expected, any idea will be helpful. – Maraku Feb 17 '14 at 21:13
  • You might use ADB (or install connectbot) and try to do shell level network tests from that end, or from the embedded device end. – Chris Stratton Feb 17 '14 at 21:15
  • I used ConnectBot and I was able to connect using telnet to the embedded linux device, so I believe that this confirms that the TCP connection is working properly – Maraku Feb 17 '14 at 21:23
  • See if you can connect to the actual port you are trying to use. – Chris Stratton Feb 17 '14 at 21:25
  • Yes, I was able to connect on that port too, I'll try using a different port but I don't think it will work anyway. – Maraku Feb 17 '14 at 21:42
  • You might try some other trivial android TCP example. Also beware of stateful bugs, for example near-term port reuse on the server side without the necessary flags, especially if you've killed or crashed the process in the last few minutes, you might not be able to restart the server and might not have noticed that, but then had it all work 10 minutes later. Something like tcpdump (one one of the involved machines, not a 3rd party) could help you see if the connection is attempted and failing, or never even attempted. – Chris Stratton Feb 17 '14 at 21:48

3 Answers3

2

android:isolatedProcess

If set to true, this service will run under a special process that is isolated from the rest of the system and has no permissions of its own. The only communication with it is through the Service API (binding and starting).

Ekaterina
  • 21
  • 2
1
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
0

I found a walkaround for this issue, I changed the TCP client from a service to an async task inside the main application, I don't understand really why it worked on the Genymotion emulator but it didn't worked at all on the real device when using services.

Maraku
  • 21
  • 1
  • 1
  • 5
  • its because GenyMotion did not support google services. Now there is a workaround to install the services on GenyMotion. – Tirolel Mar 31 '16 at 12:17