Skip to content

Commit

Permalink
AIMSICD Shell
Browse files Browse the repository at this point in the history
Shell class added to provide an ongoing root shell which will allow for the correct
execution of AT Commands and receiving the response, the first implementation would
run the native command in a single instance which is suitable as commands which
redirect serial device output would not function as intended.

AT Command fragment also updated to include the start of an automatic detection system
for possible candidates for AT command serial devices, currently the system will
attempt to draw the system property [rild.libargs] for the serial device. Secondly
ATCI* devices will be checked within /dev/radio as these have been confirmed as
working on MTK devices with the MT6282 chip.
  • Loading branch information
xLaMbChOpSx committed Jun 28, 2014
1 parent a1f14d3 commit 4049b1b
Show file tree
Hide file tree
Showing 10 changed files with 709 additions and 156 deletions.
1 change: 0 additions & 1 deletion app/libs/android-support-v13.jar.REMOVED.git-id

This file was deleted.

5 changes: 3 additions & 2 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.SecUpwN.AIMSICD"
android:versionCode="20"
android:versionName="0.1.20">
android:versionCode="21"
android:versionName="0.1.21">

<uses-feature
android:glEsVersion="0x00020000"
android:required="true"/>

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/java/com/SecUpwN/AIMSICD/AIMSICD.java
Original file line number Diff line number Diff line change
Expand Up @@ -398,8 +398,8 @@ public boolean onOptionsItemSelected(MenuItem item) {
new RequestTask(mContext, RequestTask.RESTORE_DATABASE).execute();
return true;
case R.id.update_opencelldata:
Location loc = mAimsicdService.mDevice.getLastLocation();
if (loc != null) {
Location loc = mAimsicdService.lastKnownLocation();
if (loc != null && loc.hasAccuracy()) {
Helpers.sendMsg(mContext, "Contacting OpenCellID.org for data...");
Helpers.getOpenCellData(mContext, loc.getLatitude(), loc.getLongitude(),
RequestTask.OPEN_CELL_ID_REQUEST);
Expand Down
228 changes: 188 additions & 40 deletions app/src/main/java/com/SecUpwN/AIMSICD/fragments/AtCommandFragment.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package com.SecUpwN.AIMSICD.fragments;

import com.SecUpwN.AIMSICD.R;
import com.SecUpwN.AIMSICD.utils.CMDProcessor;
import com.SecUpwN.AIMSICD.utils.CommandResult;
import com.SecUpwN.AIMSICD.utils.Helpers;
import com.SecUpwN.AIMSICD.utils.Shell;

import android.app.Activity;
import android.app.Fragment;
Expand All @@ -14,31 +13,49 @@
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.RelativeLayout;
import android.widget.Spinner;
import android.widget.TextView;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class AtCommandFragment extends Fragment {

//Return value constants
private final int RIL_INIT_OK = 200;
private final int RIL_INIT_ERROR = 201;
private final int SERIAL_INIT_OK = 200;
private final int SERIAL_INIT_ERROR = 201;
private final int ROOT_UNAVAILABLE = 202;
private final int BUSYBOX_UNAVAILABLE = 203;

private final int EXECUTE_AT = 300;
private final int EXECUTE_COMMAND = 301;

//System items
private Context mContext;
private Shell mShell = null;
private String mSerialDevice;
private final List<String> mSerialDevices = new ArrayList<>();

private List<String> mOutput;
private List<String> mError;

//Layout items
private View mView;
private RelativeLayout mAtCommandLayout;
private TextView mAtCommandError;
private TextView mRilDeviceDisplay;
private TextView mSerialDeviceDisplay;
private Button mAtCommandExecute;
private TextView mAtResponse;
private EditText mAtCommand;
private String mRilDevice;
private Spinner mSerialDeviceSpinner;
private TextView mSerialDeviceSpinnerLabel;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Expand All @@ -48,15 +65,34 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container,
mAtCommandLayout = (RelativeLayout) mView.findViewById(R.id.atcommandView);
mAtCommandError = (TextView) mView.findViewById(R.id.at_command_error);
mAtCommandExecute = (Button) mView.findViewById(R.id.execute);
mRilDeviceDisplay = (TextView) mView.findViewById(R.id.ril_device);
mSerialDeviceDisplay = (TextView) mView.findViewById(R.id.serial_device);
mAtResponse = (TextView) mView.findViewById(R.id.response);
mAtCommand = (EditText) mView.findViewById(R.id.at_command);
mAtCommandExecute.setOnClickListener(new btnClick());
mSerialDeviceSpinner = (Spinner) mView.findViewById(R.id.serial_device_spinner);
mSerialDeviceSpinner.setOnItemSelectedListener(new spinnerListener());
mSerialDeviceSpinnerLabel = (TextView) mView.findViewById(R.id.serial_device_spinner_title);
}

return mView;
}

private class spinnerListener implements AdapterView.OnItemSelectedListener {

@Override
public void onItemSelected(AdapterView<?> parentView, View selectedItemView,
int position, long id) {
mSerialDevice = String.valueOf(mSerialDeviceSpinner.getSelectedItem());
mSerialDeviceDisplay.setText(mSerialDevice);
mShell.setSerialDevice(mSerialDevice);
}

@Override
public void onNothingSelected(AdapterView<?> parentView) {

}
}

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Expand All @@ -71,16 +107,20 @@ public void onAttach(Activity activity) {
@Override
public void onDestroy() {
super.onDestroy();
if (mShell != null) {
mShell.close();
mShell = null;
}
}

@Override
public void onResume() {
super.onResume();

int rilInit = initialiseRil();
int serialDevice = initSerialDevice();

switch (rilInit) {
case RIL_INIT_OK:
switch (serialDevice) {
case SERIAL_INIT_OK:
mAtCommandLayout.setVisibility(View.VISIBLE);
break;
case ROOT_UNAVAILABLE:
Expand All @@ -95,9 +135,9 @@ public void onResume() {
+ "Please check your device has Busybox installed and try again";
mAtCommandError.setText(busyboxUnavailable);
break;
case RIL_INIT_ERROR:
case SERIAL_INIT_ERROR:
String error =
"An unknown error has occurred trying to acquire the Ril Serial Device.\n\n"
"An unknown error has occurred trying to acquire the Serial Device.\n\n"
+ "Please check your logcat for any errors and post them to Github "
+ "or XDA, links to both of these locations can be found within the "
+ "About section of the application.";
Expand All @@ -113,18 +153,27 @@ public void onResume() {
break;
}


}

private class btnClick implements View.OnClickListener {

@Override
public void onClick(View v) {
executeAT();
if (mAtCommand.getText() != null) {
String command = mAtCommand.getText().toString();
if (command.indexOf("AT") == 0 || command.indexOf("at") == 0) {
Log.i("AIMSICD", "AT Command Detected");
new MyAsync().execute(EXECUTE_AT);
} else {
Log.i("AIMSICD", "Terminal Command Detected");
new MyAsync().execute(EXECUTE_COMMAND);
}
}
}
}

private int initialiseRil() {
private int initSerialDevice() {

//Check for root access
boolean root = Helpers.checkSu();
if (!root) {
Expand All @@ -137,45 +186,144 @@ private int initialiseRil() {
return BUSYBOX_UNAVAILABLE;
}

if (mShell == null) {
mShell = new Shell();
}

//Draw Ril Serial Device details from the System Property
String rilDevice = Helpers.getSystemProp(mContext, "rild.libargs", "UNKNOWN");
mRilDevice = (rilDevice.equals("UNKNOWN") ? rilDevice : rilDevice.substring(3));
mRilDeviceDisplay.setText(mRilDevice);
mSerialDevice = (rilDevice.equals("UNKNOWN") ? rilDevice : rilDevice.substring(3));

if (!mSerialDevice.equals("UNKNOWN")) {
mSerialDevices.add(mSerialDevice);
}

if (mRilDevice.equals("UNKNOWN"))
return RIL_INIT_ERROR;
boolean result = mShell.sendCommandPreserveOut("ls /dev/radio | grep atci*", 5.0f);
if (result) {
mOutput = new ArrayList<>();
mOutput = mShell.GetStdOut();
mError = new ArrayList<>();
mError = mShell.GetStdErr();
}
if (mOutput != null) {
for (String device : mOutput) {
mSerialDevices.add("/dev/radio/" + device.trim());
}
}
if (mError != null) {
for (String error : mError) {
mAtResponse.append(error + "\n");
}
}

return RIL_INIT_OK;
//Now try xgold modem config
File xgold = new File("/system/etc/ril_xgold_radio.cfg");
if (xgold.exists() && xgold.isFile()) {
result = mShell.sendCommandPreserveOut("cat /system/etc/ril_xgold_radio.cfg | "
+ "grep -E \"atport*|dataport*\"", 5.0f);
if (result) {
mOutput = new ArrayList<>();
mOutput = mShell.GetStdOut();
mError = new ArrayList<>();
mError = mShell.GetStdErr();
}
}

if (mOutput != null) {
for (String device : mOutput) {
if (device.contains("/dev/")) {
int place = device.indexOf("=") + 1;
mSerialDevices.add(device.substring(place, device.length()-1));
}
}
}
if (mError != null) {
for (String error : mError) {
mAtResponse.append(error + "\n");
}
}

if (!mSerialDevices.isEmpty()) {
mSerialDevice = mSerialDevices.get(0);
mShell.setSerialDevice(mSerialDevices.get(0));
String[] entries = new String[mSerialDevices.size()];
entries = mSerialDevices.toArray(entries);
ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<>(mContext,
android.R.layout.simple_spinner_item, entries);
mSerialDeviceSpinner.setAdapter(spinnerAdapter);
mSerialDeviceSpinner.setVisibility(View.VISIBLE);
mSerialDeviceSpinnerLabel.setVisibility(View.VISIBLE);
}

mAtResponse.setVisibility(View.VISIBLE);

return SERIAL_INIT_OK;
}

private void executeAT() {
private boolean executeAT() {
boolean result = false;
if (mAtCommand.getText() != null) {
mAtResponse.setText("");
String cmdSetup = "cat " + mRilDevice + " &";
new ExecuteAtCommand().execute(cmdSetup);
String atCommand = mAtCommand.getText().toString();
new ExecuteAtCommand().execute("echo -e " + atCommand +"\r > " + mRilDevice);
result = mShell.executeAt(mAtCommand.getText().toString());
if (result) {
mOutput = new ArrayList<>();
mOutput = mShell.GetStdOut();
mError = new ArrayList<>();
mError = mShell.GetStdErr();
}
}
return result;
}

private class ExecuteAtCommand extends AsyncTask<String, Integer, CommandResult> {

protected CommandResult doInBackground(String... atCommand) {
return CMDProcessor.runSuCommand(atCommand[0]);
private boolean executeCommand() {
boolean result = false;
if (mAtCommand.getText() != null) {
result = mShell.sendCommandPreserveOut(mAtCommand.getText().toString(), 5.0f);
if (result) {
mOutput = new ArrayList<>();
mOutput = mShell.GetStdOut();
mError = new ArrayList<>();
mError = mShell.GetStdErr();
}
}
return result;
}

protected void onPostExecute(CommandResult result) {
if (result != null) {
Log.i("AIMSICD_ATCommand", "Stdout: " + result.getStdout() +
" StdErr: " + result.getStderr() + " Exit Value: " + result.getExitValue());
if (!result.getStdout().isEmpty())
mAtResponse.append(result.getStdout());
else if (!result.getStderr().isEmpty())
mAtResponse.append(result.getStderr());
else
mAtResponse.append("No response or error detected...");
private void updateDisplay() {
String displayOutput = "";
if (mOutput == null && mError == null) {
displayOutput = "Command Timeout/No Response\n";
} else {
if (mOutput != null) {
for (String output : mOutput) {
displayOutput += output + "\n";
}
} else {
for (String error : mError) {
displayOutput += error + "\n";
}
}
}

mAtResponse.append((displayOutput.isEmpty())
? "Command Timeout/No Response\n" : displayOutput + "\n" );
}

private class MyAsync extends AsyncTask<Integer, Void, Boolean> {
@Override
protected Boolean doInBackground(Integer ... params) {
switch (params[0]) {
case EXECUTE_AT:
return executeAT();
case EXECUTE_COMMAND:
return executeCommand();
}
return null;
}

@Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
updateDisplay();
}
}
}
12 changes: 12 additions & 0 deletions app/src/main/java/com/SecUpwN/AIMSICD/service/AimsicdService.java
Original file line number Diff line number Diff line change
Expand Up @@ -688,7 +688,19 @@ private void cancelNotification() {
}
}

public Location lastKnownLocation() {
Location location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location == null || (location.getLatitude() == 0.0 && location.getLongitude() == 0.0)) {
location = lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
}

if (location != null && location.hasAccuracy()) {
location = (mDevice.isBetterLocation(location, mDevice.getLastLocation()) ? location :
mDevice.getLastLocation());
}

return location;
}

/**
* Neighbouring Cell List
Expand Down
Loading

0 comments on commit 4049b1b

Please sign in to comment.