I have solved the issue myself. Android should be rooted in order to be able to invoke such system commands requiring root access. I've mistaken such a simple point. If anyone needs it, I'm explaining what I've done;
1. Android should be rooted by using some 3rd party application. Google for how to do it.
2. After rooting Android, it is possible to execute "su" process in normal-user level. In application code, create and execute a "su" process in which our commands will be executed with root permissions:
...
Process suProcess = Runtime.getRuntime().exec("su");
3. Input your commands to that process by using DataOutputStream class;
...
DataOutputStream os = new DataOutputStream(suProcess.getOutputStream());
os.writeBytes("command-string-to-be-executed");
os.flush();
4. End the process;
...
os.writeBytes("exit\n");
os.flush();
This is what happens in summary; our application will start a seperate process with root permissions, it executes the commands in that process, finally it ends the process.
I think this is the easiest way of controlling, i.e, configuring/starting/stopping, FlexCAN interface in application code. Then you can develop your own user space methods to send and receive CAN messages using classical Socket-API. Or, you can use an existing one such as Rick suggested. Here is my implementation with proper error handling included;
A generic class that can be used to execute system commands with root permissions;
public class ExecuteAsRoot
{
public ArrayList<String> commands;
public ExecuteAsRoot(ArrayList<String> arr) {
commands = new ArrayList<String>();
for (int i=0; i<arr.size(); i++)
commands.add(arr.get(i));
}
public boolean execute() {
boolean retVal = false;
try {
if (null != commands && commands.size() > 0) {
Process suProcess = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(suProcess.getOutputStream());
for (String currCommand : commands) {
os.writeBytes(currCommand + "\n");
os.flush();
}
os.writeBytes("exit\n");
os.flush();
BufferedReader stderr = new BufferedReader(new InputStreamReader(suProcess.getErrorStream()));
String line = "";
String errString = "";
while ((line = stderr.readLine()) != null) errString += line + "\n";
suProcess.waitFor();
if (suProcess.exitValue() != 0)
throw new Exception(errString);
retVal = true;
}
} catch (Exception e) {
retVal = false;
Log.d("ERR", e.getMessage());
e.printStackTrace();
}
return retVal;
}
}
A part of application code to control FlexCAN interface;
// ....
public boolean createVirtualCANInterface(String interfaceName) {
ArrayList<String> commands = new ArrayList<String>();
commands.add("ip link add dev " + interfaceName + " type vcan");
ExecuteAsRoot p = new ExecuteAsRoot(commands);
return p.execute();
}
public boolean setBitRate(String interfaceName, long bitrate) {
ArrayList<String> commands = new ArrayList<String>();
commands.add("ip link set " + interfaceName + " type can bitrate " + bitrate);
ExecuteAsRoot p = new ExecuteAsRoot(commands);
return p.execute();
}
public boolean startDevice(String interfaceName) {
ArrayList<String> commands = new ArrayList<String>();
commands.add("ip link set " + interfaceName + " up");
ExecuteAsRoot p = new ExecuteAsRoot(commands);
return p.execute();
}
public boolean stopDevice(String interfaceName) {
ArrayList<String> commands = new ArrayList<String>();
commands.add("ip link set " + interfaceName + " down");
ExecuteAsRoot p = new ExecuteAsRoot(commands);
return p.execute();
}
// ...