From 9567bbb9bcf8b01a98a930ad23a5aa2b32cec728 Mon Sep 17 00:00:00 2001 From: Anashuman Singh Date: Sun, 3 Nov 2024 12:42:05 +0530 Subject: [PATCH 1/3] feat: added support for wireless communication using ESP01 --- .../io/pslab/communication/HttpAsyncTask.java | 27 +++--- .../io/pslab/communication/PacketHandler.java | 37 ++++---- .../io/pslab/communication/ScienceLab.java | 25 +++--- .../io/pslab/communication/SocketClient.java | 88 +++++++++++++++++++ .../java/io/pslab/fragment/ESPFragment.java | 29 +++--- 5 files changed, 150 insertions(+), 56 deletions(-) create mode 100644 app/src/main/java/io/pslab/communication/SocketClient.java diff --git a/app/src/main/java/io/pslab/communication/HttpAsyncTask.java b/app/src/main/java/io/pslab/communication/HttpAsyncTask.java index 4aae41545..6be4bd015 100644 --- a/app/src/main/java/io/pslab/communication/HttpAsyncTask.java +++ b/app/src/main/java/io/pslab/communication/HttpAsyncTask.java @@ -1,6 +1,7 @@ package io.pslab.communication; import android.os.AsyncTask; +import android.util.Log; import org.json.JSONException; import org.json.JSONObject; @@ -11,30 +12,34 @@ public class HttpAsyncTask extends AsyncTask { - private HttpHandler mHttpHandler; - private HttpCallback mHttpCallback; + private SocketClient socketClient; + private HttpCallback mHttpCallback; + private int bytesToRead; - public HttpAsyncTask(String baseIP, HttpCallback httpCallback) { - mHttpHandler = new HttpHandler(baseIP); + public HttpAsyncTask(HttpCallback httpCallback, int bytesToRead) { + socketClient = SocketClient.getInstance(); mHttpCallback = httpCallback; + this.bytesToRead = bytesToRead; } @Override protected Void doInBackground(byte[]... data) { - int res = 0; + int bytesRead = 0; try { - if (data.length != 0) { - res = mHttpHandler.write(data[0]); + if (data[0].length != 0) { + socketClient.write(data[0]); } else { - res = mHttpHandler.read(); + bytesRead = socketClient.read(bytesToRead); } - } catch (IOException | JSONException e) { + } catch (IOException e) { mHttpCallback.error(e); e.printStackTrace(); } - if (res == 1) { - mHttpCallback.success(mHttpHandler.getReceivedData()); + if (data[0].length == 0 && bytesRead == bytesToRead) { + mHttpCallback.success(socketClient.getReceivedData()); + } else if (data[0].length != 0) { + mHttpCallback.success(new byte[]{}); } else { mHttpCallback.error(new Exception()); } diff --git a/app/src/main/java/io/pslab/communication/PacketHandler.java b/app/src/main/java/io/pslab/communication/PacketHandler.java index 709b26659..42b8825e0 100644 --- a/app/src/main/java/io/pslab/communication/PacketHandler.java +++ b/app/src/main/java/io/pslab/communication/PacketHandler.java @@ -41,8 +41,10 @@ public PacketHandler(int timeout, CommunicationHandler communicationHandler) { this.connected = false; this.timeout = timeout; this.mCommandsProto = new CommandsProto(); - this.mCommunicationHandler = communicationHandler; - connected = (mCommunicationHandler.isConnected() || ScienceLabCommon.isWifiConnected()); + if (communicationHandler != null) { + this.mCommunicationHandler = communicationHandler; + } + connected = (ScienceLabCommon.isWifiConnected() || mCommunicationHandler.isConnected()); } public boolean isConnected() { @@ -247,49 +249,44 @@ public byte[] sendBurst() { public int commonRead(int bytesToRead) throws IOException { final int[] bytesRead = {0}; - if (mCommunicationHandler.isConnected()) { + if (mCommunicationHandler != null && mCommunicationHandler.isConnected()) { bytesRead[0] = mCommunicationHandler.read(buffer, bytesToRead, timeout); } else if (ScienceLabCommon.isWifiConnected()) { - httpAsyncTask = new HttpAsyncTask(ScienceLabCommon.getEspIP(), new HttpCallback() { + httpAsyncTask = new HttpAsyncTask(new HttpCallback() { @Override - public void success(JSONObject jsonObject) { - try { - //Server will send byte array - buffer = (byte[]) jsonObject.get("data"); - bytesRead[0] = buffer.length; - } catch (JSONException e) { - e.printStackTrace(); - } + public void success(byte[] t1) { + System.arraycopy(t1, 0, buffer, 0, bytesToRead); + bytesRead[0] = bytesToRead; + Log.d(TAG, "Read: " + t1.length); } @Override public void error(Exception e) { Log.e(TAG, "Error reading data over ESP"); } - }); + }, bytesToRead); httpAsyncTask.execute(new byte[]{}); } return bytesRead[0]; } public void commonWrite(byte[] data) throws IOException { - if (mCommunicationHandler.isConnected()) { + if (mCommunicationHandler != null && mCommunicationHandler.isConnected()) { mCommunicationHandler.write(data, timeout); } else if (ScienceLabCommon.isWifiConnected()) { - httpAsyncTask = new HttpAsyncTask(ScienceLabCommon.getEspIP(), new HttpCallback() { + httpAsyncTask = new HttpAsyncTask(new HttpCallback() { @Override - public void success(JSONObject jsonObject) { - Log.v(TAG, "write response:" + jsonObject.toString()); + public void success(byte[] t1) { + Log.d(TAG, "Data written successfully"); } @Override public void error(Exception e) { Log.e(TAG, "Error writing data over ESP"); } - }); - + }, 0); httpAsyncTask.execute(data); } - } + } diff --git a/app/src/main/java/io/pslab/communication/ScienceLab.java b/app/src/main/java/io/pslab/communication/ScienceLab.java index 07e94466b..4619ffee9 100644 --- a/app/src/main/java/io/pslab/communication/ScienceLab.java +++ b/app/src/main/java/io/pslab/communication/ScienceLab.java @@ -36,6 +36,7 @@ import io.pslab.communication.peripherals.I2C; import io.pslab.fragment.HomeFragment; import io.pslab.others.InitializationVariable; +import io.pslab.others.ScienceLabCommon; /** * Created by viveksb007 on 28/3/17. @@ -79,15 +80,19 @@ public class ScienceLab { public ScienceLab(CommunicationHandler communicationHandler) { mCommandsProto = new CommandsProto(); mAnalogConstants = new AnalogConstants(); - mCommunicationHandler = communicationHandler; - if (isDeviceFound() && MainActivity.hasPermission) { - try { - mCommunicationHandler.open(1000000); - //Thread.sleep(200); - mPacketHandler = new PacketHandler(50, mCommunicationHandler); - } catch (IOException | NullPointerException e) { - e.printStackTrace(); + if (communicationHandler != null) { + mCommunicationHandler = communicationHandler; + if (isDeviceFound() && MainActivity.hasPermission) { + try { + mCommunicationHandler.open(1000000); + //Thread.sleep(200); + mPacketHandler = new PacketHandler(50, mCommunicationHandler); + } catch (IOException | NullPointerException e) { + e.printStackTrace(); + } } + } else { + mPacketHandler = new PacketHandler(50, null); } if (isConnected()) { initializeVariables(); @@ -745,7 +750,7 @@ public boolean isDeviceFound() { * @return true is device is connected; false otherwise */ public boolean isConnected() { - return mCommunicationHandler.isConnected(); + return (ScienceLabCommon.isWifiConnected || mCommunicationHandler.isConnected()); } /* DIGITAL SECTION */ @@ -2133,7 +2138,7 @@ public void resetDevice() { * @throws IOException * @throws InterruptedException */ - public void enterBootloader() throws IOException, InterruptedException { + public void enterBootloader() throws Exception { mCommunicationHandler.close(); mCommunicationHandler.open(460800); mPacketHandler = new PacketHandler(50, mCommunicationHandler); diff --git a/app/src/main/java/io/pslab/communication/SocketClient.java b/app/src/main/java/io/pslab/communication/SocketClient.java new file mode 100644 index 000000000..bcbc4388f --- /dev/null +++ b/app/src/main/java/io/pslab/communication/SocketClient.java @@ -0,0 +1,88 @@ +package io.pslab.communication; + +import android.util.Log; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.Socket; + +public class SocketClient { + + public static final String TAG = "SocketClient"; + private static SocketClient socketClient = null; + private Socket socket; + private OutputStream outputStream; + private InputStream inputStream; + private boolean isConnected = false; + + public static final int DEFAULT_READ_BUFFER_SIZE = 32 * 1024; + + private byte[] buffer = new byte[DEFAULT_READ_BUFFER_SIZE]; + + private byte[] receivedData; + + private SocketClient() { + } + + public void openConnection(String ip, int port) throws IOException { + socket = new Socket(ip, port); + outputStream = socket.getOutputStream(); + inputStream = socket.getInputStream(); + if (!socket.isConnected()) { + isConnected = false; + return; + } + isConnected = true; + } + + public static SocketClient getInstance() { + if (socketClient == null) { + socketClient = new SocketClient(); + } + return socketClient; + } + + public boolean isConnected() { + return isConnected; + } + + public void write(byte[] data) throws IOException { + if (isConnected && socketClient.isConnected && outputStream != null) { + outputStream.write(data); + } + } + + public int read(int bytesToRead) throws IOException { + int bytesRead = 0; + if (isConnected && socketClient.isConnected && inputStream != null) { + bytesRead = inputStream.read(buffer, 0, bytesToRead); + + if (bytesRead > 0) { + receivedData = new byte[bytesRead]; + System.arraycopy(buffer, 0, receivedData, 0, bytesRead); + } else { + Log.e(TAG, "Read Error: " + bytesToRead); + return bytesRead; + } + } + return bytesRead; + } + + public byte[] getReceivedData() { + return receivedData; + } + + public void closeConnection() { + try { + if (isConnected) { + inputStream.close(); + outputStream.close(); + socket.close(); + isConnected = false; + } + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/app/src/main/java/io/pslab/fragment/ESPFragment.java b/app/src/main/java/io/pslab/fragment/ESPFragment.java index 3c13b32ae..f3a669ccd 100644 --- a/app/src/main/java/io/pslab/fragment/ESPFragment.java +++ b/app/src/main/java/io/pslab/fragment/ESPFragment.java @@ -23,6 +23,8 @@ import java.io.IOException; import io.pslab.R; +import io.pslab.communication.CommunicationHandler; +import io.pslab.communication.SocketClient; import io.pslab.others.CustomSnackBar; import io.pslab.others.ScienceLabCommon; import okhttp3.OkHttpClient; @@ -84,7 +86,7 @@ public void onResume() { getDialog().getWindow().setAttributes((android.view.WindowManager.LayoutParams) params); } - private class ESPTask extends AsyncTask { + private class ESPTask extends AsyncTask { @Override protected void onPreExecute() { @@ -93,35 +95,32 @@ protected void onPreExecute() { } @Override - protected String doInBackground(Void... voids) { - String result = ""; + protected Boolean doInBackground(Void... voids) { try { - OkHttpClient client = new OkHttpClient(); - Request request = new Request.Builder() - .url("http://" + espIPAddress) - .build(); - Response response = client.newCall(request).execute(); - if (response.code() == 200) { + SocketClient socketClient = SocketClient.getInstance(); + socketClient.openConnection(espIPAddress, 80); + if (socketClient.isConnected()) { ScienceLabCommon.setIsWifiConnected(true); ScienceLabCommon.setEspBaseIP(espIPAddress); + return true; } - result = response.body().string(); - } catch (IOException e) { + } catch (Exception e) { e.printStackTrace(); } - return result; + return false; } @Override - protected void onPostExecute(String result) { + protected void onPostExecute(Boolean result) { espConnectProgressBar.setVisibility(View.GONE); espConnectBtn.setVisibility(View.VISIBLE); Activity activity; - if (result.isEmpty() && ((activity = getActivity()) != null)) { + if (!result && ((activity = getActivity()) != null)) { CustomSnackBar.showSnackBar(activity.findViewById(android.R.id.content), getString(R.string.incorrect_IP_address_message), null, null, Snackbar.LENGTH_SHORT); } else { - Log.v("Response", result); + Log.v("ESPFragment", "ESP Connection Successful"); + ScienceLabCommon.getInstance().openDevice(null); } } } From daee97ebdf05270fa79d56b71d0358f441cb4eb0 Mon Sep 17 00:00:00 2001 From: Anashuman Singh Date: Fri, 27 Dec 2024 22:36:36 +0530 Subject: [PATCH 2/3] feat: added more functionality --- .../java/io/pslab/activity/MainActivity.java | 16 +++- .../communication/CommunicationHandler.java | 7 +- .../io/pslab/communication/HttpAsyncTask.java | 48 ---------- .../io/pslab/communication/HttpHandler.java | 87 ------------------ .../io/pslab/communication/PacketHandler.java | 70 ++++++++------ .../io/pslab/communication/ScienceLab.java | 12 +-- .../io/pslab/communication/SocketClient.java | 31 ++++--- .../java/io/pslab/fragment/ESPFragment.java | 8 +- .../java/io/pslab/fragment/HomeFragment.java | 22 ++++- .../io/pslab/interfaces/HttpCallback.java | 6 -- .../receivers/WifiDisconnectReceiver.java | 65 +++++++++++++ .../main/res/drawable/ic_wifi_connected.xml | 9 ++ .../drawable/icons8_wifi_connected_100.png | Bin 0 -> 3133 bytes app/src/main/res/layout/home_fragment.xml | 3 +- .../main/res/menu/pslab_connectivity_menu.xml | 5 + app/src/main/res/values/dimens.xml | 1 + 16 files changed, 189 insertions(+), 201 deletions(-) delete mode 100644 app/src/main/java/io/pslab/communication/HttpAsyncTask.java delete mode 100644 app/src/main/java/io/pslab/communication/HttpHandler.java delete mode 100644 app/src/main/java/io/pslab/interfaces/HttpCallback.java create mode 100644 app/src/main/java/io/pslab/receivers/WifiDisconnectReceiver.java create mode 100644 app/src/main/res/drawable/ic_wifi_connected.xml create mode 100644 app/src/main/res/drawable/icons8_wifi_connected_100.png diff --git a/app/src/main/java/io/pslab/activity/MainActivity.java b/app/src/main/java/io/pslab/activity/MainActivity.java index a7a8017ae..bfae90792 100644 --- a/app/src/main/java/io/pslab/activity/MainActivity.java +++ b/app/src/main/java/io/pslab/activity/MainActivity.java @@ -1,5 +1,6 @@ package io.pslab.activity; +import static io.pslab.others.ScienceLabCommon.isWifiConnected; import static io.pslab.others.ScienceLabCommon.scienceLab; import android.app.PendingIntent; @@ -10,6 +11,7 @@ import android.content.IntentFilter; import android.hardware.usb.UsbDevice; import android.hardware.usb.UsbManager; +import android.net.wifi.WifiManager; import android.os.Bundle; import android.os.Handler; import android.util.Log; @@ -55,6 +57,7 @@ import io.pslab.others.InitializationVariable; import io.pslab.others.ScienceLabCommon; import io.pslab.receivers.USBDetachReceiver; +import io.pslab.receivers.WifiDisconnectReceiver; public class MainActivity extends AppCompatActivity { @@ -101,6 +104,7 @@ public class MainActivity extends AppCompatActivity { private PendingIntent mPermissionIntent; private CommunicationHandler communicationHandler; private USBDetachReceiver usbDetachReceiver; + private WifiDisconnectReceiver wifiDisconnectReceiver; private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION"; private static final int TIME_INTERVAL = 2000; private long mBackPressed; @@ -136,6 +140,11 @@ protected void onCreate(Bundle savedInstanceState) { usbDetachReceiver = new USBDetachReceiver(this); registerReceiver(usbDetachReceiver, usbDetachFilter); + IntentFilter wifiDisconnectFilter = new IntentFilter(); + wifiDisconnectFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); + wifiDisconnectReceiver = new WifiDisconnectReceiver(this); + registerReceiver(wifiDisconnectReceiver, wifiDisconnectFilter); + setSupportActionBar(toolbar); mHandler = new Handler(); @@ -414,7 +423,7 @@ public boolean onCreateOptionsMenu(Menu menu) { @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { - case R.id.menu_pslab_connected: + case R.id.menu_wifi_connected, R.id.menu_pslab_connected: CustomSnackBar.showSnackBar(findViewById(android.R.id.content), getString(R.string.device_connected_successfully), null, null, Snackbar.LENGTH_SHORT); break; @@ -496,8 +505,9 @@ private void attemptToGetUSBPermission() { @Override public boolean onPrepareOptionsMenu(Menu menu) { - menu.getItem(0).setVisible(PSLabisConnected); - menu.getItem(1).setVisible(!PSLabisConnected); + menu.getItem(0).setVisible(isWifiConnected); + menu.getItem(1).setVisible(PSLabisConnected); + menu.getItem(2).setVisible(!PSLabisConnected && !isWifiConnected); setPSLabVersionIDs(); return true; } diff --git a/app/src/main/java/io/pslab/communication/CommunicationHandler.java b/app/src/main/java/io/pslab/communication/CommunicationHandler.java index 14a1ad618..8b7f36c14 100644 --- a/app/src/main/java/io/pslab/communication/CommunicationHandler.java +++ b/app/src/main/java/io/pslab/communication/CommunicationHandler.java @@ -69,8 +69,7 @@ public void open(int baudRate) throws IOException { } if (mUsbDevice.getProductId() == PSLAB_PRODUCT_ID_V6 && mUsbDevice.getVendorId() == PSLAB_VENDOR_ID_V6) { PSLAB_VERSION = 6; - } - else { + } else { PSLAB_VERSION = 5; } connected = true; @@ -102,7 +101,7 @@ public int read(byte[] dest, int bytesToBeRead, int timeoutMillis) throws IOExce } int numBytesRead = 0; int readNow; - Log.v(TAG, "TO read : " + bytesToBeRead); + Log.v(TAG, "To read : " + bytesToBeRead); int bytesToBeReadTemp = bytesToBeRead; while (numBytesRead < bytesToBeRead) { readNow = port.read(mReadBuffer, bytesToBeReadTemp, timeoutMillis); @@ -123,7 +122,7 @@ public int read(byte[] dest, int bytesToBeRead, int timeoutMillis) throws IOExce public int readCdcAcm(byte[] dest, int bytesToBeRead, int timeoutMillis) throws IOException { int numBytesRead = 0; int readNow; - Log.v(TAG, "TO read : " + bytesToBeRead); + Log.v(TAG, "To read : " + bytesToBeRead); int bytesToBeReadTemp = bytesToBeRead; while (numBytesRead < bytesToBeRead) { readNow = mConnection.bulkTransfer(mUsbDevice.getInterface(1).getEndpoint(1), mReadBuffer, bytesToBeReadTemp, timeoutMillis); diff --git a/app/src/main/java/io/pslab/communication/HttpAsyncTask.java b/app/src/main/java/io/pslab/communication/HttpAsyncTask.java deleted file mode 100644 index 6be4bd015..000000000 --- a/app/src/main/java/io/pslab/communication/HttpAsyncTask.java +++ /dev/null @@ -1,48 +0,0 @@ -package io.pslab.communication; - -import android.os.AsyncTask; -import android.util.Log; - -import org.json.JSONException; -import org.json.JSONObject; - -import java.io.IOException; - -import io.pslab.interfaces.HttpCallback; - -public class HttpAsyncTask extends AsyncTask { - - private SocketClient socketClient; - private HttpCallback mHttpCallback; - private int bytesToRead; - - public HttpAsyncTask(HttpCallback httpCallback, int bytesToRead) { - socketClient = SocketClient.getInstance(); - mHttpCallback = httpCallback; - this.bytesToRead = bytesToRead; - } - - @Override - protected Void doInBackground(byte[]... data) { - int bytesRead = 0; - try { - if (data[0].length != 0) { - socketClient.write(data[0]); - - } else { - bytesRead = socketClient.read(bytesToRead); - } - } catch (IOException e) { - mHttpCallback.error(e); - e.printStackTrace(); - } - if (data[0].length == 0 && bytesRead == bytesToRead) { - mHttpCallback.success(socketClient.getReceivedData()); - } else if (data[0].length != 0) { - mHttpCallback.success(new byte[]{}); - } else { - mHttpCallback.error(new Exception()); - } - return null; - } -} diff --git a/app/src/main/java/io/pslab/communication/HttpHandler.java b/app/src/main/java/io/pslab/communication/HttpHandler.java deleted file mode 100644 index a2f7bed38..000000000 --- a/app/src/main/java/io/pslab/communication/HttpHandler.java +++ /dev/null @@ -1,87 +0,0 @@ -package io.pslab.communication; - -import android.util.Log; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.io.IOException; -import java.net.URL; - -import okhttp3.MediaType; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.RequestBody; -import okhttp3.Response; - -public class HttpHandler { - - private final String TAG = this.getClass().getSimpleName(); - private String baseIP; - private String sendDataEndPoint = "send"; - private String getDataEndPoint = "get"; - private String dataKeyString = "data"; - private OkHttpClient client; - private JSONObject receivedData; - - public HttpHandler(String baseIP) { - this.baseIP = baseIP; - this.client = new OkHttpClient(); - } - - /** - * Method to send data to ESP - * - * @param data data to be sent in byte array - * @return 1 if response code is "200" 0 otherwise; - */ - public int write(byte[] data) throws IOException, JSONException { - int result = 1; - URL baseURL = new URL("http://" + baseIP + "/" + sendDataEndPoint); - int written = 0; - JSONArray responseArray = new JSONArray(); - while (written < data.length) { - JSONObject jsonObject = new JSONObject(); - jsonObject.put(dataKeyString, data[written]); - RequestBody body = RequestBody.create(jsonObject.toString(), MediaType.get("application/json; charset=utf-8")); - Request request = new Request.Builder() - .url(baseURL) - .post(body) - .build(); - Response response = client.newCall(request).execute(); - responseArray.put(new JSONObject(response.body().string())); - if (response.code() != 200) { - Log.e(TAG, "Error writing byte:" + written); - return 0; - } - written++; - } - receivedData = new JSONObject(responseArray.toString()); - return result; - } - - /** - * Method to get data from ESP - * @return 1 if data was received 0 otherwise - */ - public int read() throws IOException, JSONException { - int result = 1; - URL baseURL = new URL("http://" + baseIP + "/" + getDataEndPoint); - Request request = new Request.Builder() - .url(baseURL) - .build(); - Response response = client.newCall(request).execute(); - if (response.code() != 200) { - Log.e(TAG, "Error reading data"); - return 0; - } else { - receivedData = new JSONObject(response.body().string()); - } - return result; - } - - public JSONObject getReceivedData() { - return receivedData; - } -} diff --git a/app/src/main/java/io/pslab/communication/PacketHandler.java b/app/src/main/java/io/pslab/communication/PacketHandler.java index 42b8825e0..28d8b096d 100644 --- a/app/src/main/java/io/pslab/communication/PacketHandler.java +++ b/app/src/main/java/io/pslab/communication/PacketHandler.java @@ -2,9 +2,6 @@ import android.util.Log; -import org.json.JSONException; -import org.json.JSONObject; - import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -13,8 +10,10 @@ import java.nio.ByteOrder; import java.nio.charset.StandardCharsets; import java.util.Arrays; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; -import io.pslab.interfaces.HttpCallback; import io.pslab.others.ScienceLabCommon; /** @@ -34,13 +33,15 @@ public class PacketHandler { private int timeout = 500, VERSION_STRING_LENGTH = 8, FW_VERSION_LENGTH = 3; public static int PSLAB_FW_VERSION = 0; ByteBuffer burstBuffer = ByteBuffer.allocate(2000); - private HttpAsyncTask httpAsyncTask; + private SocketClient socketClient; + ExecutorService executor = Executors.newSingleThreadExecutor(); public PacketHandler(int timeout, CommunicationHandler communicationHandler) { this.loadBurst = false; this.connected = false; this.timeout = timeout; this.mCommandsProto = new CommandsProto(); + socketClient = SocketClient.getInstance(); if (communicationHandler != null) { this.mCommunicationHandler = communicationHandler; } @@ -252,20 +253,21 @@ public int commonRead(int bytesToRead) throws IOException { if (mCommunicationHandler != null && mCommunicationHandler.isConnected()) { bytesRead[0] = mCommunicationHandler.read(buffer, bytesToRead, timeout); } else if (ScienceLabCommon.isWifiConnected()) { - httpAsyncTask = new HttpAsyncTask(new HttpCallback() { - @Override - public void success(byte[] t1) { - System.arraycopy(t1, 0, buffer, 0, bytesToRead); + Future future = executor.submit(() -> { + try { + socketClient.read(bytesToRead); + System.arraycopy(socketClient.getReceivedData(), 0, buffer, 0, bytesToRead); bytesRead[0] = bytesToRead; - Log.d(TAG, "Read: " + t1.length); - } - - @Override - public void error(Exception e) { + } catch (Exception e) { Log.e(TAG, "Error reading data over ESP"); } - }, bytesToRead); - httpAsyncTask.execute(new byte[]{}); + return null; + }); + try { + future.get(); + } catch (Exception e) { + throw new IOException("Error reading data", e); + } } return bytesRead[0]; } @@ -274,19 +276,31 @@ public void commonWrite(byte[] data) throws IOException { if (mCommunicationHandler != null && mCommunicationHandler.isConnected()) { mCommunicationHandler.write(data, timeout); } else if (ScienceLabCommon.isWifiConnected()) { - httpAsyncTask = new HttpAsyncTask(new HttpCallback() { - @Override - public void success(byte[] t1) { - Log.d(TAG, "Data written successfully"); - } - - @Override - public void error(Exception e) { - Log.e(TAG, "Error writing data over ESP"); + Future future = executor.submit(() -> { + try { + socketClient.write(data); + } catch (Exception e) { + Log.e(TAG, "Error reading data over ESP"); } - }, 0); - httpAsyncTask.execute(data); + return null; + }); + try { + future.get(); + } catch (Exception e) { + throw new IOException("Error writing data", e); + } } } -} + public void close() { + try { + if (mCommunicationHandler != null) { + mCommunicationHandler.close(); + } else { + socketClient.closeConnection(); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/io/pslab/communication/ScienceLab.java b/app/src/main/java/io/pslab/communication/ScienceLab.java index 4619ffee9..a6173bd20 100644 --- a/app/src/main/java/io/pslab/communication/ScienceLab.java +++ b/app/src/main/java/io/pslab/communication/ScienceLab.java @@ -233,11 +233,7 @@ public void run() { } public void close() { - try { - mCommunicationHandler.close(); - } catch (IOException e) { - e.printStackTrace(); - } + mPacketHandler.close(); } private void captureFullSpeedHrInitialize(String channel, int samples, double timeGap, List args) { @@ -741,6 +737,9 @@ public void setDataSplitting(int dataSplitting) { * @return true is device found; false otherwise */ public boolean isDeviceFound() { + if (mCommunicationHandler == null) { + return false; + } return mCommunicationHandler.isDeviceFound(); } @@ -750,7 +749,8 @@ public boolean isDeviceFound() { * @return true is device is connected; false otherwise */ public boolean isConnected() { - return (ScienceLabCommon.isWifiConnected || mCommunicationHandler.isConnected()); + return ScienceLabCommon.isWifiConnected || + (mCommunicationHandler != null && mCommunicationHandler.isConnected()); } /* DIGITAL SECTION */ diff --git a/app/src/main/java/io/pslab/communication/SocketClient.java b/app/src/main/java/io/pslab/communication/SocketClient.java index bcbc4388f..03c8b32d5 100644 --- a/app/src/main/java/io/pslab/communication/SocketClient.java +++ b/app/src/main/java/io/pslab/communication/SocketClient.java @@ -34,6 +34,8 @@ public void openConnection(String ip, int port) throws IOException { return; } isConnected = true; + socket.setTcpNoDelay(true); + socket.setKeepAlive(true); } public static SocketClient getInstance() { @@ -47,26 +49,31 @@ public boolean isConnected() { return isConnected; } - public void write(byte[] data) throws IOException { + public synchronized void write(byte[] data) throws IOException { if (isConnected && socketClient.isConnected && outputStream != null) { outputStream.write(data); } } - public int read(int bytesToRead) throws IOException { - int bytesRead = 0; - if (isConnected && socketClient.isConnected && inputStream != null) { - bytesRead = inputStream.read(buffer, 0, bytesToRead); - - if (bytesRead > 0) { - receivedData = new byte[bytesRead]; - System.arraycopy(buffer, 0, receivedData, 0, bytesRead); + public synchronized int read(int bytesToBeRead) throws IOException { + int numBytesRead = 0; + int readNow; + Log.v(TAG, "To read : " + bytesToBeRead); + int bytesToBeReadTemp = bytesToBeRead; + receivedData = new byte[DEFAULT_READ_BUFFER_SIZE]; + while (numBytesRead < bytesToBeRead) { + readNow = inputStream.read(buffer, 0, bytesToBeReadTemp); + if (readNow <= 0) { + Log.e(TAG, "Read Error: " + bytesToBeReadTemp); + return numBytesRead; } else { - Log.e(TAG, "Read Error: " + bytesToRead); - return bytesRead; + System.arraycopy(buffer, 0, receivedData, numBytesRead, readNow); + numBytesRead += readNow; + bytesToBeReadTemp -= readNow; } } - return bytesRead; + Log.v("Bytes Read", "" + numBytesRead); + return numBytesRead; } public byte[] getReceivedData() { diff --git a/app/src/main/java/io/pslab/fragment/ESPFragment.java b/app/src/main/java/io/pslab/fragment/ESPFragment.java index ecf16684f..78bec4286 100644 --- a/app/src/main/java/io/pslab/fragment/ESPFragment.java +++ b/app/src/main/java/io/pslab/fragment/ESPFragment.java @@ -19,16 +19,11 @@ import com.google.android.material.snackbar.Snackbar; -import java.io.IOException; import io.pslab.R; -import io.pslab.communication.CommunicationHandler; import io.pslab.communication.SocketClient; import io.pslab.others.CustomSnackBar; import io.pslab.others.ScienceLabCommon; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.Response; public class ESPFragment extends DialogFragment { private static final String TAG = ESPFragment.class.getSimpleName(); @@ -114,6 +109,9 @@ protected void onPostExecute(Boolean result) { } else { Log.v("ESPFragment", "ESP Connection Successful"); ScienceLabCommon.getInstance().openDevice(null); + ScienceLabCommon.isWifiConnected = true; + getParentFragmentManager().beginTransaction().remove(ESPFragment.this).commitAllowingStateLoss(); + getParentFragmentManager().beginTransaction().replace(R.id.frame, HomeFragment.newInstance(true, false)).commitAllowingStateLoss(); } } } diff --git a/app/src/main/java/io/pslab/fragment/HomeFragment.java b/app/src/main/java/io/pslab/fragment/HomeFragment.java index 9574f1e58..be08913be 100644 --- a/app/src/main/java/io/pslab/fragment/HomeFragment.java +++ b/app/src/main/java/io/pslab/fragment/HomeFragment.java @@ -22,12 +22,17 @@ import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; +import com.google.android.material.snackbar.Snackbar; + import java.io.IOException; +import java.util.Objects; import butterknife.BindView; import butterknife.ButterKnife; import butterknife.Unbinder; import io.pslab.R; +import io.pslab.activity.MainActivity; +import io.pslab.others.CustomSnackBar; import io.pslab.others.InitializationVariable; import io.pslab.others.ScienceLabCommon; @@ -97,7 +102,22 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c } imgViewDeviceStatus.setImageResource(R.drawable.icons8_usb_connected_100); tvDeviceStatus.setText(getString(R.string.device_connected_successfully)); - } else { + } + else if (!deviceFound && deviceConnected) { + tvConnectMsg.setVisibility(View.GONE); + try { + tvVersion.setText(scienceLab.getVersion()); + tvVersion.setVisibility(View.VISIBLE); + } catch (IOException e) { + e.printStackTrace(); + } + imgViewDeviceStatus.setImageResource(R.drawable.icons8_wifi_connected_100); + tvDeviceStatus.setText(getString(R.string.device_connected_successfully)); + requireActivity().invalidateOptionsMenu(); + CustomSnackBar.showSnackBar(requireActivity().findViewById(android.R.id.content), + getString(R.string.device_connected_successfully), null, null, Snackbar.LENGTH_SHORT); + } + else { imgViewDeviceStatus.setImageResource(R.drawable.icons_usb_disconnected_100); tvDeviceStatus.setText(getString(R.string.device_not_found)); } diff --git a/app/src/main/java/io/pslab/interfaces/HttpCallback.java b/app/src/main/java/io/pslab/interfaces/HttpCallback.java deleted file mode 100644 index 3bcdd62e8..000000000 --- a/app/src/main/java/io/pslab/interfaces/HttpCallback.java +++ /dev/null @@ -1,6 +0,0 @@ -package io.pslab.interfaces; - -public interface HttpCallback { - void success(T t1); - void error(Exception e); -} diff --git a/app/src/main/java/io/pslab/receivers/WifiDisconnectReceiver.java b/app/src/main/java/io/pslab/receivers/WifiDisconnectReceiver.java new file mode 100644 index 000000000..9dc72a001 --- /dev/null +++ b/app/src/main/java/io/pslab/receivers/WifiDisconnectReceiver.java @@ -0,0 +1,65 @@ +package io.pslab.receivers; + +import android.app.Activity; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.net.wifi.WifiManager; +import android.util.Log; + +import androidx.fragment.app.Fragment; + +import com.google.android.material.snackbar.Snackbar; + + +import io.pslab.R; +import io.pslab.activity.MainActivity; +import io.pslab.activity.PowerSourceActivity; +import io.pslab.communication.PacketHandler; +import io.pslab.fragment.HomeFragment; +import io.pslab.others.CustomSnackBar; +import io.pslab.others.ScienceLabCommon; + +public class WifiDisconnectReceiver extends BroadcastReceiver { + + private final String TAG = this.getClass().getSimpleName(); + private Context activityContext; + + public WifiDisconnectReceiver() { + } + + public WifiDisconnectReceiver(Context context) { + this.activityContext = context; + } + + @Override + public void onReceive(Context context, Intent intent) { + try { + if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(intent.getAction())) { + if (ScienceLabCommon.isWifiConnected) { + ScienceLabCommon.scienceLab.close(); + // Clear saved values in Power Source Instrument + context.getSharedPreferences(PowerSourceActivity.POWER_PREFERENCES, Context.MODE_PRIVATE).edit().clear().apply(); + CustomSnackBar.showSnackBar(((Activity) context).findViewById(android.R.id.content), + "Wifi Device Disconnected", null, null, Snackbar.LENGTH_SHORT); + + PacketHandler.version = ""; + + if (activityContext != null) { + MainActivity mainActivity = (MainActivity) activityContext; + Fragment currentFragment = mainActivity.getSupportFragmentManager().findFragmentById(R.id.frame); + if (currentFragment instanceof HomeFragment) { + mainActivity.getSupportFragmentManager().beginTransaction().replace(R.id.frame, HomeFragment.newInstance(false, false)).commitAllowingStateLoss(); + } + ScienceLabCommon.isWifiConnected = false; + mainActivity.invalidateOptionsMenu(); + } + } else { + Log.v(TAG, "Board isn't connected."); + } + } + } catch (IllegalStateException ignored) { + /**/ + } + } +} diff --git a/app/src/main/res/drawable/ic_wifi_connected.xml b/app/src/main/res/drawable/ic_wifi_connected.xml new file mode 100644 index 000000000..68a3dedc2 --- /dev/null +++ b/app/src/main/res/drawable/ic_wifi_connected.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/icons8_wifi_connected_100.png b/app/src/main/res/drawable/icons8_wifi_connected_100.png new file mode 100644 index 0000000000000000000000000000000000000000..e287453c3a9630d84567e8a3ca700499316b519d GIT binary patch literal 3133 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 Xm0qC?n;O{500000NkvXXu0mjfQ{WDl literal 0 HcmV?d00001 diff --git a/app/src/main/res/layout/home_fragment.xml b/app/src/main/res/layout/home_fragment.xml index 1474c274f..c462b1234 100644 --- a/app/src/main/res/layout/home_fragment.xml +++ b/app/src/main/res/layout/home_fragment.xml @@ -39,9 +39,10 @@ + 30dp 1dp 40dp + 20dp 20dp 60dp 8dp From 3dc1bbff77bffce1b54b0bd1c1f31169814e65ef Mon Sep 17 00:00:00 2001 From: Anashuman Singh Date: Fri, 27 Dec 2024 22:50:35 +0530 Subject: [PATCH 3/3] fix: make Codacy happy --- app/src/main/java/io/pslab/activity/MainActivity.java | 3 +-- .../main/java/io/pslab/communication/PacketHandler.java | 7 ++++--- app/src/main/res/values/dimens.xml | 1 - 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/io/pslab/activity/MainActivity.java b/app/src/main/java/io/pslab/activity/MainActivity.java index bfae90792..a15250bea 100644 --- a/app/src/main/java/io/pslab/activity/MainActivity.java +++ b/app/src/main/java/io/pslab/activity/MainActivity.java @@ -104,7 +104,6 @@ public class MainActivity extends AppCompatActivity { private PendingIntent mPermissionIntent; private CommunicationHandler communicationHandler; private USBDetachReceiver usbDetachReceiver; - private WifiDisconnectReceiver wifiDisconnectReceiver; private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION"; private static final int TIME_INTERVAL = 2000; private long mBackPressed; @@ -142,7 +141,7 @@ protected void onCreate(Bundle savedInstanceState) { IntentFilter wifiDisconnectFilter = new IntentFilter(); wifiDisconnectFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); - wifiDisconnectReceiver = new WifiDisconnectReceiver(this); + WifiDisconnectReceiver wifiDisconnectReceiver = new WifiDisconnectReceiver(this); registerReceiver(wifiDisconnectReceiver, wifiDisconnectFilter); setSupportActionBar(toolbar); diff --git a/app/src/main/java/io/pslab/communication/PacketHandler.java b/app/src/main/java/io/pslab/communication/PacketHandler.java index 28d8b096d..ece99cf4a 100644 --- a/app/src/main/java/io/pslab/communication/PacketHandler.java +++ b/app/src/main/java/io/pslab/communication/PacketHandler.java @@ -280,7 +280,7 @@ public void commonWrite(byte[] data) throws IOException { try { socketClient.write(data); } catch (Exception e) { - Log.e(TAG, "Error reading data over ESP"); + Log.e(TAG, "Error writing data over ESP"); } return null; }); @@ -299,8 +299,9 @@ public void close() { } else { socketClient.closeConnection(); } - } catch (IOException e) { - throw new RuntimeException(e); + executor.shutdown(); + } catch (Exception e) { + Log.e(TAG, "Error closing connection"); } } } \ No newline at end of file diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index ebbd05fff..4ff562cbe 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -271,7 +271,6 @@ 30dp 1dp 40dp - 20dp 20dp 60dp 8dp