diff --git a/Main.qml b/Main.qml
index 7a705dd..e7844b9 100644
--- a/Main.qml
+++ b/Main.qml
@@ -19,11 +19,47 @@ Window {
property int font_normal_text_size: 16
property double distance: 0
property int distance_count: 0
+ property int distance_count_thres: 3
property string mode: "http"
// visibility: Window.FullScreen
Component.onCompleted: {
- if(Qt.platform.os !== "android") {
+ loading_popup.open();
+ }
+
+
+ Popup {
+ id: loading_popup
+ background: Rectangle {
+ color: "#B0121212"
+ radius: 5
+ border.color: root.accent_color
+ border.width: 1
}
+ height: parent.height / 10
+ width: parent.width / 1.1
+ anchors.centerIn: Overlay.overlay
+ closePolicy: Popup.NoAutoClose
+ BusyIndicator {
+ id: loading_indicator
+ running: true
+ anchors {
+ left: parent.left
+ verticalCenter: parent.verticalCenter
+ }
+ }
+ Text {
+ id: loading_text
+ text: "Loading..."
+ anchors {
+ leftMargin: 20
+ left: loading_indicator.right
+ verticalCenter: parent.verticalCenter
+ }
+ verticalAlignment: Text.AlignVCenter
+ color: root.accent_color
+ font.pointSize: root.font_enlarged_text_size
+ }
+
}
Rectangle {
@@ -687,7 +723,10 @@ Window {
root.distance = listener.distance;
error_text.error_string = "";
console.log("Distance count: ", root.distance_count);
- if(root.distance_count >= 5) {
+ if(root.distance_count >= root.distance_count_thres) {
+ if(loading_popup.opened) {
+ loading_popup.close();
+ }
status_label.text = "Recieving values";
let current_min_reading = Math.max(0, (parseFloat(min_thres_input.text)));
let effective_max_reading = Math.max(0, (parseFloat(max_thres_input.text)) - current_min_reading);
@@ -704,7 +743,7 @@ Window {
water_level.color = root.water_color;
}
if(root.distance_count > 1000) {
- root.distance_count = 5;
+ root.distance_count = root.distance_count_thres;
}
console.log("Current reading is: " + current_reading)
console.log("Normalized height is: " + normalized_height)
diff --git a/README.md b/README.md
index 96a9151..7198d51 100644
--- a/README.md
+++ b/README.md
@@ -5,4 +5,13 @@ Builds for android and desktop.
On Android Creates a service from service.cpp and android/src/org/qtproject/example/appwaterLevelSensor/WaterLevelService.java.
Changes in AndroidManifest.xml are important.
On Desktop just waits for values from a UDP Broadcast on local network with port 8176 and shows those values.
-On Android the service does that, and creates an alert notification if the value in broadcast is less than alert threshold.
\ No newline at end of file
+On Android the service does that, and creates an alert notification if the value in broadcast is less than alert threshold.
+
+
+
+Create a new socket in Worker that will instantly start listening.
+In the service launch the threads and immediately send client hello to the worker socket.
+On client hello send command data to the android service.
+On quit send server bye to android service.
+On server bye deinit the sockets that send data to cpp server.
+On next launch, the command and client threads can be reinitialized from the StartService java class.
\ No newline at end of file
diff --git a/android/src/org/qtproject/example/appwaterLevelSensor/WaterLevelService.java b/android/src/org/qtproject/example/appwaterLevelSensor/WaterLevelService.java
index 2d3709f..cc765d0 100644
--- a/android/src/org/qtproject/example/appwaterLevelSensor/WaterLevelService.java
+++ b/android/src/org/qtproject/example/appwaterLevelSensor/WaterLevelService.java
@@ -25,25 +25,87 @@ import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONArray;
import android.widget.Toast;
+import android.os.IBinder;
+import android.os.Handler;
+import android.os.Message;
+import android.os.Messenger;
public class WaterLevelService extends Service {
private static float alert_thres_distance = 1000000;
- private boolean bits_flipped = false;
- private String mode = "";
- private String url = "";
- private Thread udpThread;
- private Thread cmdThread;
- private boolean resetBinds = false;
+ private static boolean bits_flipped = false;
+ private static String mode = "";
+ private static String url = "";
+ private static Thread udpThread;
+ private static Thread cmdThread;
+ private static boolean resetBinds = false;
+ private final IBinder binder = new LocalBinder();
+ final Messenger mMessenger = new Messenger(new IncomingHandler());
+ public static final int MSG_RESTART_THREADS = 1;
- public synchronized boolean checkBound() {
+
+ class IncomingHandler extends Handler {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_RESTART_THREADS:
+ Log.d("UDP Service MainThread", "Received IPC request to restart threads");
+ restartThreads();
+ break;
+ default:
+ super.handleMessage(msg);
+ }
+ }
+ }
+
+
+ public synchronized void restartThreads() {
+ Log.d("UDP Service MainThread", "In synchronized thread stopper.");
+ udpThread.interrupt();
+ cmdThread.interrupt();
+ try {
+ udpThread.join();
+ cmdThread.join();
+ } catch (InterruptedException e) {
+ Log.d("UDP Service MainThread", "Thread joining was interrupted because of: " + e);
+ }
+
+ new Thread(new
+ Runnable() {
+ @Override
+ public void run() {
+ try {
+ // Move your socket and thread starting logic here
+ if (udpThread == null || !udpThread.isAlive()) {
+ udpThread = new Thread(new UDPClient());
+ udpThread.start();
+ }
+ if (cmdThread == null || !cmdThread.isAlive()) {
+ cmdThread = new Thread(new UDPCommandClient());
+ cmdThread.start();
+ }
+ } catch (Exception e) {
+ Log.e("UDP Service MainThread", "Restarting the threads", e);
+ }
+ }
+ }).start();
+ Log.d("UDP Service MainThread", "Actually restarting the thread");
+ }
+
+ public static synchronized boolean checkBound() {
return resetBinds;
}
- public synchronized void setBound(boolean value) {
+ public static synchronized void setBound(boolean value) {
resetBinds = value;
}
+ public class LocalBinder extends android.os.Binder {
+ WaterLevelService getService() {
+ return WaterLevelService.this;
+ }
+ }
+
public class UDPCommandClient implements Runnable {
private DatagramSocket socket_cmd_recv;
private DatagramSocket socket_cmd_send;
@@ -51,7 +113,7 @@ public class WaterLevelService extends Service {
@Override
public void run() {
- Log.d("UDP Service", "Command thread initialising");
+ Log.d("UDP Service CommandThread", "Command thread initialising");
try {
socket_cmd_recv = new DatagramSocket(null);
socket_cmd_send = new DatagramSocket(null);
@@ -59,15 +121,30 @@ public class WaterLevelService extends Service {
socket_cmd_recv.setReuseAddress(true);
socket_cmd_send.setReuseAddress(true);
socket_cmd_recv.bind(new InetSocketAddress(8178));
- socket_cmd_send.bind(new InetSocketAddress(8179));
- Log.d("UDP Service", "Created command thread sockets");
+ socket_cmd_send.bind(new InetSocketAddress(8187));
+ boolean not_send_set = true;
+ Log.d("UDP Service CommandThread", "Created command thread sockets");
while (!Thread.currentThread().isInterrupted()) {
if(socket_cmd_recv.isClosed()) {
socket_cmd_recv.bind(new InetSocketAddress(8178));
}
if(socket_cmd_send.isClosed()) {
- socket_cmd_send.bind(new InetSocketAddress(8179));
+ socket_cmd_send.bind(new InetSocketAddress(8187));
}
+
+ if(not_send_set) {
+ String s_data = new String("");
+ byte[] buff_s = s_data.getBytes(StandardCharsets.UTF_8);
+ DatagramPacket packet = new DatagramPacket(buff_s, buff_s.length, InetAddress.getByName("127.0.0.1"), 8186);
+ try {
+ socket_cmd_send.connect(InetAddress.getByName("127.0.0.1"), 8186);
+ socket_cmd_send.send(packet);
+ } catch(Exception e) {
+ Log.d("UDP Service CommandThread", "Failed to send data to client due to: " + e);
+ }
+ Log.d("UDP Service CommandThread", "Sent set message to client");
+ }
+
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
try {
@@ -76,7 +153,8 @@ public class WaterLevelService extends Service {
continue;
}
String str = new String(buffer, StandardCharsets.UTF_8);
- Log.d("UDP Service ", "Received command packet " + str);
+ Log.d("UDP Service CommandThread", "Received command packet " + str);
+ not_send_set = false;
if(str.startsWith("", "");
- Log.d("UDP Service ", "Flipping " + str);
+ Log.d("UDP Service CommandThread", "Flipping " + str);
if(str.toLowerCase() == "false") {
bits_flipped = false;
}
@@ -110,21 +188,21 @@ public class WaterLevelService extends Service {
str = str.replace("", "");
- Log.d("UDP Service ", "Mode " + str);
+ Log.d("UDP Service CommandThread", "Mode " + str);
mode = str.toLowerCase();
}
else if(str.startsWith("", "");
- Log.d("UDP Service ", "Url " + str);
+ Log.d("UDP Service CommandThread", "Url " + str);
url = str.toLowerCase();
}
}
}
catch (IOException e) {
// showToast("IOException: " + e);
- Log.e("UDP Service", "IOException Error" + e);
+ Log.e("UDP Service CommandThread", "IOException Error" + e);
}
}
@@ -134,11 +212,12 @@ public class WaterLevelService extends Service {
private DatagramSocket socket_recv;
private DatagramSocket socket_send;
private Instant prevAlertTimestamp;
+ private InetAddress address;
private boolean started = false;
@Override
public void run() {
- Log.d("UDP Service", "Client Thread initialising");
+ Log.d("UDP Service ClientThread", "Client Thread initialising");
android.net.wifi.WifiManager wifi = (android.net.wifi.WifiManager) getSystemService(Context.WIFI_SERVICE);
android.net.wifi.WifiManager.MulticastLock multicastLock = wifi.createMulticastLock("water_level_lock");
android.net.wifi.WifiManager.WifiLock wifiLock = wifi.createWifiLock(android.net.wifi.WifiManager.WIFI_MODE_FULL_HIGH_PERF, "WaterLevel:WifiLock");
@@ -167,16 +246,19 @@ public class WaterLevelService extends Service {
socket_send.setReuseAddress(true);
socket_send.bind(new InetSocketAddress(8177));
socket_recv.bind(new InetSocketAddress(8176));
- Log.d("UDP Service", "Created Sockets");
+ Log.d("UDP Service ClientThread", "Created Sockets");
int count = 0;
while (!Thread.currentThread().isInterrupted()) {
count++;
if(count == 3) {
- Log.i("UDP Service", "Thread is running with mode: " + mode);
+ Log.i("UDP Service ClientThread", "Thread is running with mode: " + mode);
count = 0;
}
if(checkBound()) {
- Log.i("UDP Service", "Reconnecting sockets");
+ Log.i("UDP Service ClientThread", "Reconnecting sockets");
+ this.address = InetAddress.getByName("127.0.0.1");
+ socket_recv.disconnect();
+ socket_send.disconnect();
socket_recv.close();
socket_send.close();
socket_recv = null;
@@ -190,7 +272,7 @@ public class WaterLevelService extends Service {
socket_send.bind(new InetSocketAddress(8177));
socket_recv.bind(new InetSocketAddress(8176));
setBound(false);
- Log.i("UDP Service", "Reconnected sockets");
+ Log.i("UDP Service ClientThread", "Reconnected sockets");
}
// if(checkBound()) {
// Log.i("UDP Service", "Reset socket binds: " + mode);
@@ -238,9 +320,10 @@ public class WaterLevelService extends Service {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
- continue;
+ Log.d("UDP Service ClientThread", "Thread exiting due to interrupt.");
+ return;
}
- Log.d("UDP Service", "Http String Url: " + url);
+ Log.d("UDP Service ClientThread", "Http String Url: " + url);
URL t_url = new URL(url);
HttpURLConnection con = (HttpURLConnection) t_url.openConnection();
con.setRequestMethod("GET");
@@ -248,7 +331,7 @@ public class WaterLevelService extends Service {
con.setReadTimeout(5000);
con.setInstanceFollowRedirects(true);
int status = con.getResponseCode();
- Log.d("UDP Service", "Got status from http: " + status);
+ Log.d("UDP Service ClientThread", "Got status from http: " + status);
if(status == 200) {
BufferedReader streamReader = new BufferedReader(new InputStreamReader(con.getInputStream()));
String data = streamReader.readLine();
@@ -258,10 +341,10 @@ public class WaterLevelService extends Service {
float f = (float ) arr.getDouble(0);
updated = obj.getString("updated_on");
buffer = ByteBuffer.allocate(4).putFloat(f).array();
- Log.d("UDP Service", "Got value from http: " + f);
- Log.d("UDP Service", "Last updated on: " + updated);
+ Log.d("UDP Service ClientThread", "Got value from http: " + f);
+ Log.d("UDP Service ClientThread", "Last updated on: " + updated);
} catch (JSONException e) {
- Log.e("UDP Service", "Invalid Json");
+ Log.e("UDP Service ClientThread", "Invalid Json");
// showToast("Invalid Json" + e);
continue;
}
@@ -273,12 +356,13 @@ public class WaterLevelService extends Service {
}
}
else {
- Log.d("UDP Service", "Invalid mode: " + mode);
+ Log.d("UDP Service ClientThread", "Invalid mode: " + mode);
// showToast("Invalid mode: " + mode);
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
- continue;
+ Log.d("UDP Service ClientThread", "Thread exiting due to interrupt.");
+ return;
}
continue;
}
@@ -289,8 +373,8 @@ public class WaterLevelService extends Service {
else {
f = ByteBuffer.wrap(buffer).order(ByteOrder.BIG_ENDIAN).getFloat();
}
- Log.d("UDP Service ", "Received packet: " + f);
- Log.d("UDP Service ", "Threshold is: " + alert_thres_distance);
+ Log.d("UDP Service ClientThread", "Received packet: " + f);
+ Log.d("UDP Service ClientThread", "Threshold is: " + alert_thres_distance);
boolean duration_passed = false;
if(!started) {
duration_passed = true;
@@ -311,7 +395,7 @@ public class WaterLevelService extends Service {
.setContentText("Water Level is below alert threshold")
.setPriority(Notification.PRIORITY_LOW);
manager.notify(2, builder.build());
- Log.d("UDP Service", "Notification sent");
+ Log.d("UDP Service ClientThread", "Notification sent");
if(!started) {
started = true;
}
@@ -319,20 +403,20 @@ public class WaterLevelService extends Service {
if(socket_send.isClosed()) {
socket_send.bind(new InetSocketAddress(8177));
}
- DatagramPacket send_packet = new DatagramPacket(buffer, buffer.length, InetAddress.getByName("localhost"), 8180);
+ DatagramPacket send_packet = new DatagramPacket(buffer, buffer.length, InetAddress.getByName("127.0.0.1"), 8180);
socket_send.send(send_packet);
- Log.d("UDP Service ", "Sent packet");
+ Log.d("UDP Service ClientThread", "Sent packet");
if(mode.equals("http")) {
byte[] buff2 = updated.getBytes(StandardCharsets.UTF_8);
- DatagramPacket send_packet_2 = new DatagramPacket(buff2, buff2.length, InetAddress.getByName("localhost"), 8185);
+ DatagramPacket send_packet_2 = new DatagramPacket(buff2, buff2.length, InetAddress.getByName("127.0.0.1"), 8185);
socket_send.send(send_packet_2);
- Log.d("UDP Service ", "Sent last updated packet");
+ Log.d("UDP Service ClientThread", "Sent last updated packet");
}
}
}
catch (IOException e) {
// showToast("IOException: " + e);
- Log.e("UDP Service", "IOException Error" + e);
+ Log.e("UDP Service ClientThread", "IOException Error" + e);
} finally {
if (wifiLock.isHeld())
wifiLock.release();
@@ -347,7 +431,7 @@ public class WaterLevelService extends Service {
}
public void startWaterLevelService() {
- Log.d("UDP Service", "Starting the service from Activity");
+ Log.d("UDP Service MainThread", "Starting the service from Activity");
Intent intent = new Intent(this, WaterLevelService.class);
@@ -355,25 +439,25 @@ public class WaterLevelService extends Service {
}
public WaterLevelService() {
super();
- Log.i("UDP Service", "Class is created");
+ Log.i("UDP Service MainThread", "Class is created");
}
@Override
- public android.os.IBinder onBind(android.content.Intent intent) { return null; }
+ public android.os.IBinder onBind(android.content.Intent intent) { return mMessenger.getBinder(); }
@Override
public void onCreate() {
super.onCreate();
Notification notification = createNotification();
startForeground(1, notification);
- Log.i("UDP Service", "Creating Service");
+ Log.i("UDP Service MainThread", "Creating Service");
}
@Override
public void onDestroy() {
super.onDestroy();
- Log.i("UDP Service", "Destroying Service");
+ Log.i("UDP Service MainThread", "Destroying Service");
}
@Override
@@ -383,7 +467,7 @@ public class WaterLevelService extends Service {
if (intent == null) {
- Log.w("UDP Service", "Service restarted with null intent. Stopping to avoid crash.");
+ Log.w("UDP Service MainThread", "Service restarted with null intent. Stopping to avoid crash.");
stopSelf();
return START_NOT_STICKY;
}
@@ -402,12 +486,12 @@ public class WaterLevelService extends Service {
cmdThread.start();
}
} catch (Exception e) {
- Log.e("UDP Service", "Error starting threads", e);
+ Log.e("UDP Service MainThread", "Error starting threads", e);
}
}
}).start();
- Log.d("UDP Service", "Actually starting the thread");
+ Log.d("UDP Service MainThread", "Actually starting the thread");
int ret = super.onStartCommand(intent, flags, startId);
@@ -444,7 +528,7 @@ public class WaterLevelService extends Service {
}
public static void startQtAndroidService(QtActivity activity) {
- Log.d("UDP Service", "Starting the service");
+ Log.d("UDP Service MainThread", "Starting the service");
Intent intent = new Intent(activity, WaterLevelService.class);
activity.startForegroundService(intent);
diff --git a/android/src/org/qtproject/example/appwaterLevelSensor/WaterLevelServiceStarter.java b/android/src/org/qtproject/example/appwaterLevelSensor/WaterLevelServiceStarter.java
index 84a36f6..9dccce9 100644
--- a/android/src/org/qtproject/example/appwaterLevelSensor/WaterLevelServiceStarter.java
+++ b/android/src/org/qtproject/example/appwaterLevelSensor/WaterLevelServiceStarter.java
@@ -10,9 +10,51 @@ import android.app.ActivityManager.RunningServiceInfo;
import org.qtproject.qt.android.bindings.QtActivity;
import android.os.Handler;
import android.os.Looper;
+import android.content.ServiceConnection;
+import android.content.ComponentName;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.RemoteException;
public class WaterLevelServiceStarter {
+ private static Messenger mServiceMessenger = null;
+ private static boolean mBound = false;
+ private static boolean restart_bind = false;
+ private static ServiceConnection connection = new ServiceConnection() {
+
+ @Override
+ public void onServiceConnected(ComponentName className, IBinder service) {
+ mServiceMessenger = new Messenger(service);
+ mBound = true;
+ Log.d("UDP Service StarterThread", "Connected to Service object reference");
+ if(restart_bind)
+ {
+ sendRestartMessage();
+ Log.d("UDP Service StarterThread", "Restart Threads in Service.");
+ }
+ restart_bind = false;
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName arg0) {
+ mServiceMessenger = null;
+ mBound = false;
+ }
+ };
+
+ public static void startAndBindService(Context context) {
+ Intent intent = new Intent(context, WaterLevelService.class);
+ context.startForegroundService(intent);
+ context.bindService(intent, connection, Context.BIND_AUTO_CREATE);
+ }
+
+ public static void bindService(Context context) {
+ restart_bind = true;
+ Intent intent = new Intent(context, WaterLevelService.class);
+ context.bindService(intent, connection, Context.BIND_AUTO_CREATE);
+ }
private static boolean isMyServiceRunning(Class> serviceClass, Context context) {
ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
@@ -24,6 +66,7 @@ public class WaterLevelServiceStarter {
return false;
}
+
private static int getServicePid(Class> serviceClass, Context context) {
ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
@@ -34,6 +77,20 @@ public class WaterLevelServiceStarter {
return 0;
}
+
+ public static void sendRestartMessage() {
+ if (!mBound || mServiceMessenger == null) {
+ Log.d("UDP Service StarterThread", "Service is not running.");
+ }
+ try {
+ Message msg = Message.obtain(null, WaterLevelService.MSG_RESTART_THREADS);
+ mServiceMessenger.send(msg);
+ Log.d("UDP Service StarterThread", "Sent restart signal to remote process");
+ } catch (RemoteException e) {
+ Log.e("UDP Service StarterThread", "Failed to send message", e);
+ }
+ }
+
public static void startService(Context context) {
// Log.d("UDP Service", "Starting service via QtActivity instance");
@@ -45,15 +102,16 @@ public class WaterLevelServiceStarter {
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
+
if (!isMyServiceRunning(WaterLevelService.class, context)) {
- Log.d("UDP Service", "Starting service safely on Main Looper");
- Intent intent = new Intent(context, WaterLevelService.class);
- context.startForegroundService(intent);
+ Log.d("UDP Service StarterThread", "Starting service safely on Main Looper");
+ startAndBindService(context);
}
else {
- Log.d("UDP Service", "Service already running");
+ Log.d("UDP Service StarterThread", "Service already running, so restarting the threads.");
+ bindService(context);
}
- Log.d("UDP Service", "Background service running with pid: " + getServicePid(WaterLevelService.class, context));
+ Log.d("UDP Service StarterThread", "Background service running with pid: " + getServicePid(WaterLevelService.class, context));
}
});
}
diff --git a/udplistener.cpp b/udplistener.cpp
index e44a9eb..155df4e 100644
--- a/udplistener.cpp
+++ b/udplistener.cpp
@@ -11,6 +11,7 @@ UDPListener::UDPListener(QObject *parent)
connect(worker, &Worker::lastUpdateddatagramReceived, this, &UDPListener::lastUpdateddatagramReceived);
connect(worker, &Worker::datagramReceived, this, &UDPListener::datagramRecieved);
connect(worker, &Worker::socketError, this, &UDPListener::socketError);
+ connect(worker, &Worker::sendConfig, this, &UDPListener::sendConfigOnSet);
connect(this, &UDPListener::startWorker, worker, &Worker::run);
connect(this, &UDPListener::changeWorkerMode, worker, &Worker::changeMode);
thread->start();
@@ -33,52 +34,15 @@ void UDPListener::setDistance(double newDistance)
emit distanceChanged();
}
-void UDPListener::moveAppToBackground()
+void UDPListener::sendConfigOnSet()
{
-#ifdef Q_OS_ANDROID
- service->moveAppToBackground();
-#endif
-}
-
-void UDPListener::lastUpdateddatagramReceived(QByteArray data)
-{
- QString s_data = QString::fromUtf8(data);
- qDebug() << "Main Class last updated on: " << s_data;
- QDateTime time = QDateTime::fromString(s_data, "dd/MM/yy hh:mm:ss");
- QDateTime thres_time = QDateTime::currentDateTime().addSecs(-1800);
- if(time.isValid() && time < thres_time)
- {
- emit lastUpdatedChanged(s_data, false);
- }
- else if(time > thres_time && time.isValid()) {
- emit lastUpdatedChanged(s_data, true);
- }
- else if(!time.isValid()) {
- emit lastUpdatedChanged("Invalid Date", true);
- }
-}
-
-void UDPListener::continueDestruction()
-{
- destroyed = true;
-}
-
-void UDPListener::resetAverages()
-{
- averages.clear();
-}
-
-void UDPListener::setFlipBits(bool flip_bits)
-{
- m_flip_bits = flip_bits;
-}
-
-void UDPListener::setConfig(float distance, bool flip_bits, QString mode, QString url)
-{
- setFlipBits(flip_bits);
+ bool flip_bits = m_flip_bits;
+ QString url = m_url;
+ QString mode = m_mode;
+ float distance = m_distance;
if(!command_socket) {
command_socket = new QUdpSocket(this);
- bool bind = command_socket->bind(8181);
+ bool bind = command_socket->bind(QHostAddress::Any, 0);
if(bind) {
QNetworkDatagram data1, data2, data3, data4;
data1.setDestination(QHostAddress::LocalHost, 8178);
@@ -122,12 +86,63 @@ void UDPListener::setConfig(float distance, bool flip_bits, QString mode, QStrin
command_socket->deleteLater();
command_socket = nullptr;
+ qDebug() << "Sent all Command Statements.";
emit changeWorkerMode(mode, url);
}
else {
showError("Command Socket Bind Failed");
}
}
+}
+
+void UDPListener::moveAppToBackground()
+{
+#ifdef Q_OS_ANDROID
+ service->moveAppToBackground();
+#endif
+}
+
+void UDPListener::lastUpdateddatagramReceived(QByteArray data)
+{
+ QString s_data = QString::fromUtf8(data);
+ qDebug() << "Main Class last updated on: " << s_data;
+ QDateTime time = QDateTime::fromString(s_data, "dd/MM/yy hh:mm:ss").addYears(100);
+ QDateTime thres_time = QDateTime::currentDateTime().addSecs(-1800);
+ if(time.isValid() && thres_time < time)
+ {
+ emit lastUpdatedChanged(s_data, false);
+ }
+ else if(thres_time > time && time.isValid()) {
+ emit lastUpdatedChanged(s_data, true);
+ }
+ else if(!time.isValid()) {
+ emit lastUpdatedChanged("Invalid Date", true);
+ }
+}
+
+void UDPListener::continueDestruction()
+{
+ destroyed = true;
+}
+
+void UDPListener::resetAverages()
+{
+ averages.clear();
+}
+
+void UDPListener::setFlipBits(bool flip_bits)
+{
+ m_flip_bits = flip_bits;
+}
+
+void UDPListener::setConfig(float distance, bool flip_bits, QString mode, QString url)
+{
+ setFlipBits(flip_bits);
+ setDistance(distance);
+ setMode(mode);
+ setUrl(url);
+ emit changeWorkerMode(mode, url);
+ qDebug() << "Setting config from UI completed." << flip_bits << distance << mode << url;
averages.clear();
}
@@ -279,6 +294,11 @@ void Worker::stop()
socket->close();
delete socket;
}
+ if(socket_3) {
+ disconnect(socket_3, nullptr, nullptr, nullptr);
+ socket_3->close();
+ delete socket_3;
+ }
if(httpTimer) {
disconnect(httpTimer, nullptr, nullptr, nullptr);
delete httpTimer;
@@ -295,27 +315,36 @@ void Worker::run()
using namespace std::chrono_literals;
socket = new QUdpSocket(this);
socket_2 = new QUdpSocket(this);
+ socket_3 = new QUdpSocket(this);
httpTimer = new QTimer(this);
manager = new QNetworkAccessManager(this);
#ifdef Q_OS_ANDROID
// If it is android use it as a command socket;
- bool bind = socket->bind(QHostAddress::Any, 8180, QUdpSocket::ReuseAddressHint);
- bool bind2 = socket_2->bind(QHostAddress::Any, 8185, QUdpSocket::ReuseAddressHint);
+ bool bind = socket->bind(QHostAddress::LocalHost, 8180, QUdpSocket::ReuseAddressHint | QUdpSocket::ShareAddress);
+ bool bind2 = socket_2->bind(QHostAddress::LocalHost, 8185, QUdpSocket::ReuseAddressHint | QUdpSocket::ShareAddress);
+ bool bind3 = socket_3->bind(QHostAddress::LocalHost, 8186, QUdpSocket::ReuseAddressHint | QUdpSocket::ShareAddress);
#else
// Else use it as a receiver;
bool bind = socket->bind(QHostAddress("192.168.1.255"), 8176);
bool bind2 = true;
#endif
- if(!bind || !bind2)
+ if(!bind || !bind2 || !bind3)
{
qDebug() << "UI Worker socket bind failed" << bind << socket->errorString();
+ qDebug() << "UI Worker socket bind failed" << bind2 << socket_2->errorString();
+ qDebug() << "UI Worker socket bind failed" << bind3 << socket_3->errorString();
emit socketError(socket->errorString());
emit socketError(socket_2->errorString());
+ emit socketError(socket_3->errorString());
qApp->exit(-1);
}
connect(httpTimer, &QTimer::timeout, this, &Worker::httpTimerTimeout);
connect(socket, &QUdpSocket::readyRead, this, &Worker::socketDataReceived);
connect(socket_2, &QUdpSocket::readyRead, this, &Worker::socket2DataReceived);
+ connect(socket_3, &QUdpSocket::readyRead, this, &Worker::socket3DataReceived);
+#ifdef Q_OS_ANDROID
+ qDebug() << "Waiting for message from service.";
+#endif
}
@@ -333,6 +362,43 @@ void Worker::changeMode(QString mode, QString url)
httpTimer->stop();
socketDataReceived();
}
+ if(socket) {
+ if(socket->hasPendingDatagrams()) {
+ socketDataReceived();
+ }
+ }
+ if(socket_2) {
+ if(socket_2->hasPendingDatagrams()) {
+ socket2DataReceived();
+ }
+ }
+ if(socket_3) {
+ if(socket_3->hasPendingDatagrams()) {
+ socket3DataReceived();
+ }
+ }
+
+}
+
+void Worker::socket3DataReceived()
+{
+ if(socket_3->hasPendingDatagrams()) {
+ while(this->mode == "" && this->url == "") {
+ QCoreApplication::processEvents();
+ // qDebug() << "Worker is waiting for mode to be set.";
+ }
+ size_t data_size = socket_3->pendingDatagramSize();
+ qDebug() << "Socket 3 has pending data: " << data_size;
+ if(data_size < 100000) {
+ char buff[data_size];
+ socket_3->readDatagram(buff, data_size);
+ QByteArray data = QByteArray::fromRawData(buff, data_size);
+ if(QString::fromUtf8(data) == "") {
+ qDebug() << "Data Received from Service Threads.";
+ emit sendConfig();
+ }
+ }
+ }
}
void Worker::socket2DataReceived()
@@ -349,6 +415,9 @@ void Worker::socket2DataReceived()
else if(mode == "udp") {
qDebug() << "Last Updated on Socket data received in udp mode ignoring it.";
}
+ else {
+ qDebug() << "Mode is not set in socket 2";
+ }
}
}
@@ -373,5 +442,34 @@ void Worker::socketDataReceived()
else if(mode == "http") {
qDebug() << "Socket data received in http mode ignoring it.";
}
+ else {
+ qDebug() << "Mode is not set in socket.";
+ }
}
}
+
+QString UDPListener::mode() const
+{
+ return m_mode;
+}
+
+void UDPListener::setMode(const QString &newMode)
+{
+ if (m_mode == newMode)
+ return;
+ m_mode = newMode;
+ emit modeChanged();
+}
+
+QString UDPListener::url() const
+{
+ return m_url;
+}
+
+void UDPListener::setUrl(const QString &newUrl)
+{
+ if (m_url == newUrl)
+ return;
+ m_url = newUrl;
+ emit urlChanged();
+}
diff --git a/udplistener.h b/udplistener.h
index 8c123c8..079dd35 100644
--- a/udplistener.h
+++ b/udplistener.h
@@ -25,6 +25,7 @@ class Worker: public QObject {
Q_OBJECT
QUdpSocket *socket = nullptr;
QUdpSocket *socket_2 = nullptr;
+ QUdpSocket *socket_3 = nullptr;
QString mode = "";
QString url = "";
QNetworkAccessManager *manager = nullptr;
@@ -32,6 +33,7 @@ class Worker: public QObject {
public:
explicit Worker(QObject *parent = nullptr);
signals:
+ void sendConfig();
void stopped();
void socketError(QString error);
void lastUpdateddatagramReceived(QByteArray data);
@@ -43,6 +45,7 @@ public slots:
void run();
void changeMode(QString mode, QString url);
private slots:
+ void socket3DataReceived();
void socket2DataReceived();
void socketDataReceived();
};
@@ -52,6 +55,8 @@ class UDPListener : public QObject
Q_OBJECT
QML_ELEMENT
Q_PROPERTY(double distance READ distance WRITE setDistance NOTIFY distanceChanged FINAL)
+ Q_PROPERTY(QString mode READ mode WRITE setMode NOTIFY modeChanged FINAL)
+ Q_PROPERTY(QString url READ url WRITE setUrl NOTIFY urlChanged FINAL)
bool destroyed = false;
#ifdef Q_OS_ANDROID
service *service = nullptr;
@@ -60,6 +65,12 @@ public:
explicit UDPListener(QObject *parent = nullptr);
double distance() const;
void setDistance(double newDistance);
+ QString mode() const;
+ void setMode(const QString &newMode);
+
+ QString url() const;
+ void setUrl(const QString &newUrl);
+
signals:
void lastUpdatedChanged(QString last_updated, bool warn);
void stopWorker();
@@ -70,7 +81,12 @@ signals:
void disconnected();
void distanceReceived(double dist, QString timestamp);
void changeWorkerMode(QString mode, QString url);
+ void modeChanged();
+ void initLoadFinished();
+ void urlChanged();
+
public slots:
+ void sendConfigOnSet();
void moveAppToBackground();
void lastUpdateddatagramReceived(QByteArray data);
void continueDestruction();
@@ -93,6 +109,8 @@ private:
QThread *thread = nullptr;
QTimer *timer = nullptr;
bool m_flip_bits;
+ QString m_mode;
+ QString m_url;
};
#endif // UDPLISTENER_H