正在查看: xDrip+ v04633772025.07.16 应用的 DesertComms.java JAVA 源代码文件
本页面展示 JAVA 反编译生成的源代码文件,支持语法高亮显示。 仅供安全研究与技术分析使用,严禁用于任何非法用途。请遵守相关法律法规。
正在查看: xDrip+ v04633772025.07.16 应用的 DesertComms.java JAVA 源代码文件
本页面展示 JAVA 反编译生成的源代码文件,支持语法高亮显示。 仅供安全研究与技术分析使用,严禁用于任何非法用途。请遵守相关法律法规。
package com.eveningoutpost.dexdrip.utilitymodels.desertsync;
import android.os.PowerManager;
import com.eveningoutpost.dexdrip.Home;
import com.eveningoutpost.dexdrip.importedlibraries.usbserial.driver.UsbId;
import com.eveningoutpost.dexdrip.models.DesertSync;
import com.eveningoutpost.dexdrip.models.JoH;
import com.eveningoutpost.dexdrip.models.UserError;
import com.eveningoutpost.dexdrip.utilitymodels.PersistentStore;
import com.eveningoutpost.dexdrip.utilitymodels.Pref;
import com.eveningoutpost.dexdrip.utilitymodels.StatusItem;
import com.eveningoutpost.dexdrip.webservices.XdripWebService;
import com.google.gson.annotations.Expose;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.TimeUnit;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class DesertComms {
private static final String TAG = "DesertComms";
private static volatile int comms_failures;
private static volatile String lastLoadedIP;
private static OkHttpClient okHttpClient;
private static final LinkedBlockingDeque<QueueItem> queue = new LinkedBlockingDeque<>();
public static boolean pushToOasis(String str, String str2, String str3) {
if (Home.get_follower()) {
String oasisIP = getOasisIP();
if (oasisIP.length() == 0) {
return false;
}
String httpUrl = HttpUrl.parse(getInitialUrl(oasisIP)).newBuilder().addPathSegment("sync").addPathSegment("push").addPathSegment(str).addPathSegment(str2).addEncodedPathSegment(urlEncode(str3)).build().toString();
UserError.Log.d(TAG, "To master: " + httpUrl);
queue.add(new QueueItem(httpUrl));
runInBackground();
return true;
}
if (!Home.get_master()) {
return true;
}
UserError.Log.d(TAG, "We are master so push to followers.");
for (String str4 : DesertSync.getActivePeers()) {
String str5 = TAG;
UserError.Log.d(str5, "Master attempting to push to follower: " + str4);
String httpUrl2 = HttpUrl.parse(getInitialUrl(str4)).newBuilder().addPathSegment("sync").addPathSegment("push").addPathSegment(str).addPathSegment(str2).addEncodedPathSegment(urlEncode(str3)).build().toString();
UserError.Log.d(str5, "To follower: " + httpUrl2);
queue.add(new QueueItem(httpUrl2).setHandler(QueueHandler.ToFollower));
}
runInBackground();
return true;
}
public static boolean pullFromOasis(String str, long j) {
String oasisIP = getOasisIP();
if (oasisIP.length() == 0) {
return false;
}
try {
String httpUrl = HttpUrl.parse(getInitialUrl(oasisIP)).newBuilder().addPathSegment("sync").addPathSegment("pull").addPathSegment("" + j).addPathSegment(str).build().toString();
UserError.Log.d(TAG, httpUrl);
queue.add(new QueueItem(httpUrl).setHandler(QueueHandler.Pull));
runInBackground();
return true;
} catch (NullPointerException unused) {
UserError.Log.e(TAG, "Exception parsing url: -" + oasisIP + "- probably invalid ip");
return false;
}
}
public static boolean probeOasis(String str, String str2) {
if (JoH.emptyString(str2)) {
return false;
}
if (Home.get_follower()) {
String httpUrl = HttpUrl.parse(getInitialUrl(str2)).newBuilder().addPathSegment("sync").addPathSegment("id").addPathSegment(str).build().toString();
UserError.Log.d(TAG, "PROBE: " + httpUrl);
queue.add(new QueueItem(httpUrl).setHandler(QueueHandler.MasterPing));
runInBackground();
return true;
}
UserError.Log.e(TAG, "Probe cancelled as not follower");
return true;
}
private static String getOasisIPfromPrefs() {
return Pref.getString("desert_sync_master_ip", "").trim().replace("/", "");
}
private static String getOasisIP() {
String oasisIPfromPrefs = getOasisIPfromPrefs();
if (JoH.emptyString(lastLoadedIP)) {
lastLoadedIP = oasisIPfromPrefs;
}
setCurrentToBackup(oasisIPfromPrefs, lastLoadedIP);
return oasisIPfromPrefs;
}
public static void setOasisIP(String str) {
setCurrentToBackup(str, null);
Pref.setString("desert_sync_master_ip", str);
UserError.Log.uel(TAG, "Master IP updated to: " + str);
}
private static void setCurrentToBackup(String str, String str2) {
if (str2 == null) {
str2 = getOasisIPfromPrefs();
}
if (str2.equals(str) || str2.equals(PersistentStore.getString("DesertComms-OasisIP")) || JoH.emptyString(str2)) {
return;
}
PersistentStore.setString("DesertComms-OasisIP", str2);
UserError.Log.d(TAG, "Saving to backup: " + str2);
}
public static String getOasisBackupIP() {
String string = PersistentStore.getString("DesertComms-OasisIP");
if (JoH.emptyString(string)) {
return null;
}
return string;
}
private static void runInBackground() {
new Thread(new Runnable() {
@Override
public final void run() {
DesertComms.lambda$runInBackground$0();
}
}).start();
}
public static void lambda$runInBackground$0() {
LinkedBlockingDeque<QueueItem> linkedBlockingDeque = queue;
if (linkedBlockingDeque.size() == 0) {
return;
}
PowerManager.WakeLock wakeLock = JoH.getWakeLock("DesertComms send", UsbId.SILABS_CP2102);
UserError.Log.d(TAG, "Queue size: " + linkedBlockingDeque.size());
try {
String httpNext = httpNext();
checkCommsFailures(httpNext == null);
if ((httpNext != null && linkedBlockingDeque.size() > 0) || Home.get_master()) {
runInBackground();
}
} finally {
JoH.releaseWakeLock(wakeLock);
}
}
private static String httpNext() {
LinkedBlockingDeque<QueueItem> linkedBlockingDeque = queue;
if (linkedBlockingDeque.peekFirst() == null) {
return null;
}
try {
QueueItem takeFirst = linkedBlockingDeque.takeFirst();
takeFirst.retried++;
takeFirst.updateLastProcessed();
UserError.Log.d(TAG, "Next item: " + takeFirst.toS());
String httpGet = httpGet(takeFirst.getUrl((!Home.get_follower() || takeFirst.handler == QueueHandler.MasterPing) ? null : getOasisIP()));
takeFirst.result = httpGet;
takeFirst.handler.process(takeFirst);
if (httpGet != null || takeFirst.expired()) {
linkedBlockingDeque.remove(takeFirst);
}
return httpGet;
} catch (InterruptedException unused) {
UserError.Log.e(TAG, "Got interrupted");
return null;
}
}
private static String httpGet(String str) {
if (str == null) {
return null;
}
String hashPassword = XdripWebService.hashPassword(Pref.getString(DesertSync.PREF_WEBSERVICE_SECRET, ""));
Request.Builder addHeader = new Request.Builder().url(str).addHeader("User-Agent", "xDrip+ Desert Comms");
if (hashPassword != null) {
addHeader.addHeader("api-secret", hashPassword);
}
try {
Response execute = getHttpInstance().newCall(addHeader.build()).execute();
try {
if (execute.isSuccessful()) {
String string = execute.body().string();
execute.close();
return string;
}
if (JoH.ratelimit("desert-error-response", 180)) {
UserError.Log.wtf(TAG, "Got error code: " + execute.code() + " " + execute.message() + " " + execute.body().toString());
}
execute.close();
return null;
} catch (Throwable th) {
if (execute != null) {
try {
execute.close();
} catch (Throwable th2) {
th.addSuppressed(th2);
}
}
throw th;
}
} catch (IOException | NullPointerException unused) {
return null;
}
}
private static OkHttpClient getHttpInstance() {
if (okHttpClient == null) {
OkHttpClient.Builder builder = new OkHttpClient.Builder();
TimeUnit timeUnit = TimeUnit.SECONDS;
builder.connectTimeout(10L, timeUnit);
builder.readTimeout(40L, timeUnit);
builder.writeTimeout(20L, timeUnit);
try {
builder.sslSocketFactory(TrustManager.getSSLSocketFactory(), TrustManager.getNaiveTrustManager());
} catch (Exception unused) {
UserError.Log.wtf(TAG, "Failed to set up https!");
}
builder.hostnameVerifier(TrustManager.getXdripHostVerifier());
okHttpClient = builder.build();
}
return okHttpClient;
}
private static String urlEncode(String str) {
try {
return URLEncoder.encode(str, "UTF-8");
} catch (Exception unused) {
return null;
}
}
private static void checkCommsFailures(boolean z) {
if (z) {
comms_failures++;
String str = TAG;
UserError.Log.d(str, "Comms failures increased to: " + comms_failures);
if (Home.get_master() || comms_failures <= 2 || !JoH.pratelimit("desert-check-comms", 1800) || RouteTools.reachable(getOasisIP())) {
return;
}
UserError.Log.e(str, "Oasis master IP appears unreachable: " + getOasisIP());
JoH.showNotification("Desert Sync Failure", "Master unreachable: " + getOasisIP() + " changed?", null, 1017, false, true, false);
return;
}
if (!Home.get_master() && comms_failures > 0) {
UserError.Log.d(TAG, "Comms restored after " + comms_failures + " failures");
if (comms_failures > 2) {
JoH.cancelNotification(1017);
}
}
comms_failures = 0;
}
private static String getInitialUrl(String str) {
StringBuilder sb = new StringBuilder();
sb.append("http");
sb.append(useHTTPS() ? "s" : "");
sb.append("://");
sb.append(str);
sb.append(":1758");
sb.append(useHTTPS() ? "1" : "0");
return sb.toString();
}
private static boolean useHTTPS() {
return Pref.getBooleanDefaultFalse("desert_use_https");
}
private static class QueueItem {
String result;
@Expose
final String url;
@Expose
long lastProcessedTime = -1;
@Expose
int retried = 0;
@Expose
QueueHandler handler = QueueHandler.None;
@Expose
final long entryTime = JoH.tsl();
QueueItem(String str) {
this.url = str;
}
QueueItem setHandler(QueueHandler queueHandler) {
this.handler = queueHandler;
return this;
}
String getUrl(String str) {
if (JoH.emptyString(str)) {
return this.url;
}
try {
return HttpUrl.parse(this.url).newBuilder().host(str).build().toString();
} catch (NullPointerException unused) {
return null;
}
}
String urlIP() {
try {
return HttpUrl.parse(this.url).host();
} catch (NullPointerException unused) {
return null;
}
}
void updateLastProcessed() {
this.lastProcessedTime = JoH.tsl();
}
boolean expired() {
return oneHit() || this.retried > 10 || JoH.msSince(this.entryTime) > 86400000;
}
boolean oneHit() {
QueueHandler queueHandler = this.handler;
return queueHandler == QueueHandler.ToFollower || queueHandler == QueueHandler.MasterPing || queueHandler == QueueHandler.Pull;
}
String toS() {
return JoH.defaultGsonInstance().toJson(this);
}
}
static class AnonymousClass1 {
static final int[] $SwitchMap$com$eveningoutpost$dexdrip$utilitymodels$desertsync$DesertComms$QueueHandler;
static {
int[] iArr = new int[QueueHandler.values().length];
$SwitchMap$com$eveningoutpost$dexdrip$utilitymodels$desertsync$DesertComms$QueueHandler = iArr;
try {
iArr[QueueHandler.Pull.ordinal()] = 1;
} catch (NoSuchFieldError unused) {
}
try {
$SwitchMap$com$eveningoutpost$dexdrip$utilitymodels$desertsync$DesertComms$QueueHandler[QueueHandler.ToFollower.ordinal()] = 2;
} catch (NoSuchFieldError unused2) {
}
try {
$SwitchMap$com$eveningoutpost$dexdrip$utilitymodels$desertsync$DesertComms$QueueHandler[QueueHandler.MasterPing.ordinal()] = 3;
} catch (NoSuchFieldError unused3) {
}
}
}
enum QueueHandler {
None,
Pull,
MasterPing,
ToFollower;
void process(QueueItem queueItem) {
int i = AnonymousClass1.$SwitchMap$com$eveningoutpost$dexdrip$utilitymodels$desertsync$DesertComms$QueueHandler[ordinal()];
if (i == 1) {
String str = queueItem.result;
if (str == null) {
DesertSync.pullFailed(queueItem.urlIP());
return;
} else {
DesertSync.fromPull(str);
return;
}
}
if (i == 2) {
DesertSync.checkIpChange(queueItem.result);
} else {
if (i != 3) {
return;
}
DesertSync.masterIdReply(queueItem.result, queueItem.urlIP());
}
}
}
public static List<StatusItem> megaStatus() {
ArrayList arrayList = new ArrayList();
if (Home.get_follower()) {
if (JoH.emptyString(getOasisIP())) {
arrayList.add(new StatusItem("Desert Master", "Not known yet - needs QR code scan?"));
} else {
arrayList.add(new StatusItem("Desert Master", getOasisIP(), RouteTools.reachable(getOasisIP()) ? StatusItem.Highlight.NORMAL : StatusItem.Highlight.BAD));
}
if (Home.get_engineering_mode()) {
arrayList.add(new StatusItem("Desert Backup", getOasisBackupIP()));
arrayList.add(new StatusItem("Our IP", RouteTools.getBestInterfaceAddress()));
}
}
return arrayList;
}
}