From d69bcc95e19e596b03b772c8f6dbdfb9a2d27c1d Mon Sep 17 00:00:00 2001 From: kalynstricklin Date: Wed, 15 Apr 2026 07:54:18 -0500 Subject: [PATCH 1/3] added discovery service, need to update with paths to rule.txt # Conflicts: # sensorhub-android-app/src/org/sensorhub/android/MainActivity.java --- .gitmodules | 3 + sensorhub-android-app/build.gradle | 1 + .../res/layout/activity_app_status.xml | 50 +++++++++++++++++ .../res/values/strings_app_status.xml | 1 + .../res/xml/pref_settings.xml | 7 +++ .../sensorhub/android/AppStatusActivity.java | 4 ++ .../org/sensorhub/android/MainActivity.java | 55 ++++++++++++++++--- settings.gradle | 3 + submodules/botts-addons | 1 + 9 files changed, 118 insertions(+), 7 deletions(-) create mode 160000 submodules/botts-addons diff --git a/.gitmodules b/.gitmodules index 189cbdf..437f68a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -6,3 +6,6 @@ path = submodules/osh-core url = git@github.com:kalynstricklin/osh-core.git branch = update-moduleutils +[submodule "submodules/botts-addons"] + path = submodules/botts-addons + url = git@github.com:Botts-Innovative-Research/botts-addons.git diff --git a/sensorhub-android-app/build.gradle b/sensorhub-android-app/build.gradle index 986801d..f4899e8 100644 --- a/sensorhub-android-app/build.gradle +++ b/sensorhub-android-app/build.gradle @@ -24,6 +24,7 @@ dependencies { implementation project(path: ':sensorhub-datastore-h2') implementation project(path: ':sensorhub-service-consys') + implementation project(path: ':sensorhub-service-discovery') implementation project(':sensorhub-android-ste') implementation project(':sensorhub-android-meshtastic') implementation project(':sensorhub-android-polar') diff --git a/sensorhub-android-app/res/layout/activity_app_status.xml b/sensorhub-android-app/res/layout/activity_app_status.xml index 0b735b5..0f9ef58 100644 --- a/sensorhub-android-app/res/layout/activity_app_status.xml +++ b/sensorhub-android-app/res/layout/activity_app_status.xml @@ -137,6 +137,56 @@ + + + + + + + + + + + + + + + + + SOS Service Status ConSys Service Status + Discovery Service Status HTTP Server Status Android Sensor Status Android Sensor Storage Status diff --git a/sensorhub-android-app/res/xml/pref_settings.xml b/sensorhub-android-app/res/xml/pref_settings.xml index cd0433c..d3d2db9 100644 --- a/sensorhub-android-app/res/xml/pref_settings.xml +++ b/sensorhub-android-app/res/xml/pref_settings.xml @@ -119,6 +119,13 @@ android:defaultValue="true" android:layout="@layout/preference_switch_item" /> + + diff --git a/sensorhub-android-app/src/org/sensorhub/android/AppStatusActivity.java b/sensorhub-android-app/src/org/sensorhub/android/AppStatusActivity.java index b214732..a5a9a67 100644 --- a/sensorhub-android-app/src/org/sensorhub/android/AppStatusActivity.java +++ b/sensorhub-android-app/src/org/sensorhub/android/AppStatusActivity.java @@ -28,6 +28,7 @@ protected void onCreate(Bundle savedInstanceState) { String sosStatus = intent.getStringExtra("sosService"); String consSysStatus = intent.getStringExtra("conSysService"); + String discoveryStatus = intent.getStringExtra("discoveryService"); String httpStatus = intent.getStringExtra("httpStatus"); String sensorStatus = intent.getStringExtra("androidSensorStatus"); String sensorStorageStatus = intent.getStringExtra("sensorStorageStatus"); @@ -35,12 +36,14 @@ protected void onCreate(Bundle savedInstanceState) { // Set status text TextView sosStatusView = findViewById(R.id.sos_service_state); TextView conSysStatusView = findViewById(R.id.consys_service_state); + TextView discoveryStatusView = findViewById(R.id.discovery_service_state); TextView httpStatusView = findViewById(R.id.http_service_state); TextView sensorStatusView = findViewById(R.id.sensor_service_state); TextView storageStatusView = findViewById(R.id.storage_service_state); sosStatusView.setText(sosStatus); conSysStatusView.setText(consSysStatus); + discoveryStatusView.setText(discoveryStatus); httpStatusView.setText(httpStatus); sensorStatusView.setText(sensorStatus); storageStatusView.setText(sensorStorageStatus); @@ -48,6 +51,7 @@ protected void onCreate(Bundle savedInstanceState) { // Color the status indicator dots setStatusDotColor(findViewById(R.id.sos_status_dot), sosStatus); setStatusDotColor(findViewById(R.id.consys_status_dot), consSysStatus); + setStatusDotColor(findViewById(R.id.discovery_status_dot), discoveryStatus); setStatusDotColor(findViewById(R.id.http_status_dot), httpStatus); setStatusDotColor(findViewById(R.id.sensor_status_dot), sensorStatus); setStatusDotColor(findViewById(R.id.storage_status_dot), sensorStorageStatus); diff --git a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java index 2586375..927bfb0 100644 --- a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java +++ b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java @@ -14,6 +14,8 @@ package org.sensorhub.android; +import static org.sensorhub.android.SensorHubService.context; + import android.Manifest; import android.annotation.SuppressLint; import android.app.AlertDialog; @@ -47,6 +49,8 @@ import androidx.appcompat.app.AppCompatActivity; import androidx.fragment.app.Fragment; +import com.botts.impl.service.discovery.DiscoveryService; +import com.botts.impl.service.discovery.DiscoveryServiceConfig; import com.google.android.material.appbar.MaterialToolbar; import com.google.android.material.bottomnavigation.BottomNavigationView; import com.google.android.material.dialog.MaterialAlertDialogBuilder; @@ -104,7 +108,11 @@ import org.slf4j.LoggerFactory; import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; @@ -243,6 +251,7 @@ public void updateConfig(SharedPreferences prefs, String runName) Boolean isApiServiceEnabled = prefs.getBoolean("api_service", true); Boolean isSosServiceEnabled = prefs.getBoolean("sos_service", true); + Boolean isDiscoveryServiceEnabled = prefs.getBoolean("discovery_service", true); Boolean isClientEnabled = prefs.getBoolean("enable_client", true); Boolean isTLSEnabled = prefs.getBoolean("enable_tls", false); @@ -372,6 +381,30 @@ public boolean verify(String arg0, SSLSession arg1) { conSysApiService.enableTransactional = true; conSysApiService.exposedResources = new ObsSystemDatabaseViewConfig(); + // Discovery Service + DiscoveryServiceConfig discoveryServiceConfig = new DiscoveryServiceConfig(); + discoveryServiceConfig.moduleClass = DiscoveryService.class.getCanonicalName(); + discoveryServiceConfig.id = "DISCOVERY_SERVICE"; + discoveryServiceConfig.name= "Discovery Service"; + discoveryServiceConfig.autoStart = true; + + InputStream inputStream = context.getResources().openRawResource(R.raw.rules); + File outFile = new File(context.getFilesDir(), "rules.txt"); + try (OutputStream outputStream = new FileOutputStream(outFile)) { + byte[] buffer = new byte[1024]; + int length; + while ((length = inputStream.read(buffer)) > 0) { + outputStream.write(buffer, 0, length); + } + outputStream.flush(); + } catch (FileNotFoundException e) { + throw new RuntimeException(e); + } catch (IOException e) { + throw new RuntimeException(e); + } + discoveryServiceConfig.rulesFilePath = outFile.getAbsolutePath(); + + // OAuth ConSysOAuthConfig conSysOAuthConfig = new ConSysOAuthConfig(); conSysOAuthConfig.oAuthEnabled = isOAuthEnabled; conSysOAuthConfig.tokenEndpoint = tokenEndpoint; @@ -523,6 +556,18 @@ public boolean verify(String arg0, SSLSession arg1) { sensorhubConfig.add(controllerConfig); } + //---------- SERVICES --------------------- + if (isApiServiceEnabled) { + sensorhubConfig.add(conSysApiService); + } + if (isSosServiceEnabled) { + sensorhubConfig.add(sosConfig); + } + if (isDiscoveryServiceEnabled) { + sensorhubConfig.add(discoveryServiceConfig); + } + + // Template Driver enabled = prefs.getBoolean("template_enabled", false); if (enabled) { @@ -535,13 +580,6 @@ public boolean verify(String arg0, SSLSession arg1) { sensorhubConfig.add(templateConfig); } - - if (isApiServiceEnabled) { - sensorhubConfig.add(conSysApiService); - } - if (isSosServiceEnabled) { - sensorhubConfig.add(sosConfig); - } } protected void addSosTConfig(SensorConfig sensorConf, String user, String pwd) @@ -691,6 +729,9 @@ else if(id == R.id.action_status) { case "CON_SYS_SERVICE": statusIntent.putExtra("conSysService", status); break; + case "DISCOVERY_SERVICE": + statusIntent.putExtra("discoveryService", status); + break; case "ANDROID_SENSORS": statusIntent.putExtra("androidSensorStatus", status); break; diff --git a/settings.gradle b/settings.gradle index 8a7c624..d9ac7b4 100644 --- a/settings.gradle +++ b/settings.gradle @@ -32,6 +32,9 @@ def repos = [ 'sensors/health/sensorhub-driver-angelsensor', 'processing/sensorhub-process-vecmath', 'processing/sensorhub-process-geoloc' + ], + 'botts-addons' : [ + 'services/sensorhub-service-discovery' ] ] diff --git a/submodules/botts-addons b/submodules/botts-addons new file mode 160000 index 0000000..7381f8c --- /dev/null +++ b/submodules/botts-addons @@ -0,0 +1 @@ +Subproject commit 7381f8c06d7cdbaa03aa9a66f4bc6451cb1d712b From 8ad0df3458e69623d10416f8d65f6859bbb8d4e4 Mon Sep 17 00:00:00 2001 From: kalynstricklin Date: Thu, 16 Apr 2026 08:41:55 -0500 Subject: [PATCH 2/3] update the discovery service rules to download from a link --- .../res/xml/pref_settings.xml | 7 +++ .../org/sensorhub/android/MainActivity.java | 57 +++++++++++-------- 2 files changed, 41 insertions(+), 23 deletions(-) diff --git a/sensorhub-android-app/res/xml/pref_settings.xml b/sensorhub-android-app/res/xml/pref_settings.xml index d3d2db9..d7b52dd 100644 --- a/sensorhub-android-app/res/xml/pref_settings.xml +++ b/sensorhub-android-app/res/xml/pref_settings.xml @@ -126,6 +126,13 @@ android:defaultValue="true" android:layout="@layout/preference_switch_item" /> + diff --git a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java index 927bfb0..779e316 100644 --- a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java +++ b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java @@ -113,6 +113,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; @@ -126,6 +127,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.concurrent.FutureTask; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; @@ -388,19 +390,29 @@ public boolean verify(String arg0, SSLSession arg1) { discoveryServiceConfig.name= "Discovery Service"; discoveryServiceConfig.autoStart = true; - InputStream inputStream = context.getResources().openRawResource(R.raw.rules); File outFile = new File(context.getFilesDir(), "rules.txt"); - try (OutputStream outputStream = new FileOutputStream(outFile)) { - byte[] buffer = new byte[1024]; - int length; - while ((length = inputStream.read(buffer)) > 0) { - outputStream.write(buffer, 0, length); + String rulesLink = prefs.getString("rules_link", ""); + FutureTask downloadTask = new java.util.concurrent.FutureTask<>(() -> { + URL rulesUrl = new URL(rulesLink); + HttpURLConnection conn = (HttpURLConnection) rulesUrl.openConnection(); + conn.setInstanceFollowRedirects(true); + try (InputStream in = conn.getInputStream(); + OutputStream out = new FileOutputStream(outFile)) { + byte[] buffer = new byte[1024]; + int len; + while ((len = in.read(buffer)) > 0) { + out.write(buffer, 0, len); + } + } finally { + conn.disconnect(); } - outputStream.flush(); - } catch (FileNotFoundException e) { - throw new RuntimeException(e); - } catch (IOException e) { - throw new RuntimeException(e); + return null; + }); + new Thread(downloadTask).start(); + try { + downloadTask.get(); + } catch (Exception e) { + Log.e("OSH - Discovery", "Failed to download rules file", e); } discoveryServiceConfig.rulesFilePath = outFile.getAbsolutePath(); @@ -556,18 +568,6 @@ public boolean verify(String arg0, SSLSession arg1) { sensorhubConfig.add(controllerConfig); } - //---------- SERVICES --------------------- - if (isApiServiceEnabled) { - sensorhubConfig.add(conSysApiService); - } - if (isSosServiceEnabled) { - sensorhubConfig.add(sosConfig); - } - if (isDiscoveryServiceEnabled) { - sensorhubConfig.add(discoveryServiceConfig); - } - - // Template Driver enabled = prefs.getBoolean("template_enabled", false); if (enabled) { @@ -580,6 +580,17 @@ public boolean verify(String arg0, SSLSession arg1) { sensorhubConfig.add(templateConfig); } + //---------- SERVICES --------------------- + if (isApiServiceEnabled) { + sensorhubConfig.add(conSysApiService); + } + if (isSosServiceEnabled) { + sensorhubConfig.add(sosConfig); + } + if (isDiscoveryServiceEnabled) { + sensorhubConfig.add(discoveryServiceConfig); + } + } protected void addSosTConfig(SensorConfig sensorConf, String user, String pwd) From e50f127dd181ff9c024bbb9f1cbfda84f7f3c5a6 Mon Sep 17 00:00:00 2001 From: kalynstricklin Date: Thu, 16 Apr 2026 08:45:04 -0500 Subject: [PATCH 3/3] Update MainActivity.java --- .../src/org/sensorhub/android/MainActivity.java | 1 - 1 file changed, 1 deletion(-) diff --git a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java index 779e316..2eed33f 100644 --- a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java +++ b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java @@ -108,7 +108,6 @@ import org.slf4j.LoggerFactory; import java.io.File; -import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream;