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);).
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).
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.