Tweaking SMS protocol
This commit is contained in:
@@ -610,8 +610,8 @@ public abstract class SdDataSource {
|
|||||||
mSdData.alarmCause = "";
|
mSdData.alarmCause = "";
|
||||||
|
|
||||||
boolean flapDetected = flapCheck();
|
boolean flapDetected = flapCheck();
|
||||||
alarmCheck(flapDetected);
|
|
||||||
hrCheck();
|
hrCheck();
|
||||||
|
alarmCheck(flapDetected);
|
||||||
o2SatCheck();
|
o2SatCheck();
|
||||||
fallCheck();
|
fallCheck();
|
||||||
muteCheck();
|
muteCheck();
|
||||||
@@ -739,7 +739,10 @@ public abstract class SdDataSource {
|
|||||||
mAlarmCount += mSamplePeriod;
|
mAlarmCount += mSamplePeriod;
|
||||||
|
|
||||||
if (mAlarmCount > mAlarmTime) {
|
if (mAlarmCount > mAlarmTime) {
|
||||||
if (mRequireHrForSeizureAlarm) {
|
if (mSdData.alarmState == 2) {
|
||||||
|
// Already in full alarm. Do not require HR confirmation again.
|
||||||
|
mSdData.alarmState = 2;
|
||||||
|
} else if (mRequireHrForSeizureAlarm) {
|
||||||
if (hasRecentHrConfirmation()) {
|
if (hasRecentHrConfirmation()) {
|
||||||
mSdData.alarmState = 2;
|
mSdData.alarmState = 2;
|
||||||
mSdData.alarmCause = mSdData.alarmCause + "HR_CONFIRM ";
|
mSdData.alarmCause = mSdData.alarmCause + "HR_CONFIRM ";
|
||||||
@@ -753,9 +756,6 @@ public abstract class SdDataSource {
|
|||||||
// Existing behavior
|
// Existing behavior
|
||||||
mSdData.alarmState = 2;
|
mSdData.alarmState = 2;
|
||||||
}
|
}
|
||||||
} else if (mAlarmCount > mWarnTime) {
|
|
||||||
// warning
|
|
||||||
mSdData.alarmState = 1;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// If we are not in an ALARM state, revert back to WARNING, otherwise
|
// If we are not in an ALARM state, revert back to WARNING, otherwise
|
||||||
|
|||||||
@@ -125,8 +125,19 @@ public class SdServer extends Service implements SdDataReceiver {
|
|||||||
private boolean mMp3Alarm = false;
|
private boolean mMp3Alarm = false;
|
||||||
private boolean mPhoneAlarm = false;
|
private boolean mPhoneAlarm = false;
|
||||||
private boolean mSMSAlarm = false;
|
private boolean mSMSAlarm = false;
|
||||||
private boolean mFlogaEmergencyEscalation = true;
|
// Emergency-services escalation SMS.
|
||||||
|
// This is separate from the normal carer/contact SMS.
|
||||||
|
private boolean mEmergencySmsEnabled = false;
|
||||||
|
private boolean mEmergencySmsNotifyContacts = true;
|
||||||
|
private String mEmergencySmsNumber = "";
|
||||||
|
private String mEmergencySmsMessage =
|
||||||
|
"Possible seizure emergency. The wearer may be having a tonic-clonic seizure and the alarm has remained active."; private int mEmergencySmsDelaySecs = 300;
|
||||||
|
private EmergencySmsTimer mEmergencySmsTimer = null;
|
||||||
|
private boolean mEmergencySmsSent = false;
|
||||||
|
|
||||||
private long mAlarmStartTime = 0;
|
private long mAlarmStartTime = 0;
|
||||||
|
private String mLastLocationUrl = "";
|
||||||
|
private String mLastAlarmDateStr = "";
|
||||||
private String[] mSMSNumbers;
|
private String[] mSMSNumbers;
|
||||||
private String mSMSMsgStr = "default SMS Message";
|
private String mSMSMsgStr = "default SMS Message";
|
||||||
private String mSMSFalseAlarmMsgStr = "default SMS False Alarm Message";
|
private String mSMSFalseAlarmMsgStr = "default SMS False Alarm Message";
|
||||||
@@ -657,7 +668,16 @@ public class SdServer extends Service implements SdDataReceiver {
|
|||||||
if ((sdData.alarmState == 2) || (sdData.alarmState == 5)) {
|
if ((sdData.alarmState == 2) || (sdData.alarmState == 5)) {
|
||||||
sdData.alarmPhrase = "ALARM";
|
sdData.alarmPhrase = "ALARM";
|
||||||
sdData.alarmStanding = true;
|
sdData.alarmStanding = true;
|
||||||
if (mAlarmStartTime == 0) mAlarmStartTime = System.currentTimeMillis();
|
|
||||||
|
if (mAlarmStartTime == 0) {
|
||||||
|
mAlarmStartTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
Time tnow = new Time(Time.getCurrentTimezone());
|
||||||
|
tnow.setToNow();
|
||||||
|
mLastAlarmDateStr = tnow.format("%H:%M:%S %d/%m/%Y");
|
||||||
|
|
||||||
|
startEmergencySmsTimer();
|
||||||
|
}
|
||||||
if (mLogAlarms) {
|
if (mLogAlarms) {
|
||||||
Log.v(TAG, "***ALARM*** - Logging to SD Card");
|
Log.v(TAG, "***ALARM*** - Logging to SD Card");
|
||||||
//writeAlarmToSD();
|
//writeAlarmToSD();
|
||||||
@@ -678,12 +698,6 @@ public class SdServer extends Service implements SdDataReceiver {
|
|||||||
- mSMSTime.toMillis(false))
|
- mSMSTime.toMillis(false))
|
||||||
> 60000) {
|
> 60000) {
|
||||||
sendSMSAlarm();
|
sendSMSAlarm();
|
||||||
// Floga: escalate to emergency call if seizure longer than 5 minutes
|
|
||||||
long alarmDurationSecs = (System.currentTimeMillis() - mAlarmStartTime) / 1000;
|
|
||||||
if (alarmDurationSecs >= 300 && mFlogaEmergencyEscalation) {
|
|
||||||
sendPhoneAlarm();
|
|
||||||
Log.v(TAG, "Floga: 5 minute threshold reached - calling emergency contacts");
|
|
||||||
}
|
|
||||||
mSMSTime = tnow;
|
mSMSTime = tnow;
|
||||||
} else {
|
} else {
|
||||||
mUtil.showToast(getString(R.string.SMSAlarmAlreadySentMsg));
|
mUtil.showToast(getString(R.string.SMSAlarmAlreadySentMsg));
|
||||||
@@ -1067,6 +1081,46 @@ public class SdServer extends Service implements SdDataReceiver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void startEmergencySmsTimer() {
|
||||||
|
if (!mEmergencySmsEnabled) {
|
||||||
|
Log.v(TAG, "startEmergencySmsTimer() - emergency SMS disabled");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mEmergencySmsSent) {
|
||||||
|
Log.v(TAG, "startEmergencySmsTimer() - emergency SMS already sent");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mEmergencySmsTimer != null) {
|
||||||
|
Log.v(TAG, "startEmergencySmsTimer() - timer already running");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mEmergencySmsNumber == null || mEmergencySmsNumber.trim().length() == 0) {
|
||||||
|
Log.w(TAG, "startEmergencySmsTimer() - no emergency SMS number set");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.i(TAG, "startEmergencySmsTimer() - starting emergency SMS timer for "
|
||||||
|
+ mEmergencySmsDelaySecs + " seconds");
|
||||||
|
|
||||||
|
runOnUiThread(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
mEmergencySmsTimer =
|
||||||
|
new EmergencySmsTimer(mEmergencySmsDelaySecs * 1000L, 1000);
|
||||||
|
mEmergencySmsTimer.start();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void stopEmergencySmsTimer() {
|
||||||
|
if (mEmergencySmsTimer != null) {
|
||||||
|
Log.i(TAG, "stopEmergencySmsTimer() - cancelling emergency SMS timer");
|
||||||
|
mEmergencySmsTimer.cancel();
|
||||||
|
mEmergencySmsTimer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Start the timer that will automatically re-set a latched alarm after a given period.
|
* Start the timer that will automatically re-set a latched alarm after a given period.
|
||||||
@@ -1111,6 +1165,12 @@ public class SdServer extends Service implements SdDataReceiver {
|
|||||||
Log.i(TAG, "acceptAlarm()");
|
Log.i(TAG, "acceptAlarm()");
|
||||||
mSdData.alarmStanding = false;
|
mSdData.alarmStanding = false;
|
||||||
mSdData.fallAlarmStanding = false;
|
mSdData.fallAlarmStanding = false;
|
||||||
|
mAlarmStartTime = 0;
|
||||||
|
mLastAlarmDateStr = "";
|
||||||
|
mEmergencySmsSent = false;
|
||||||
|
|
||||||
|
stopEmergencySmsTimer();
|
||||||
|
|
||||||
mSdDataSource.acceptAlarm();
|
mSdDataSource.acceptAlarm();
|
||||||
stopLatchTimer();
|
stopLatchTimer();
|
||||||
}
|
}
|
||||||
@@ -1315,7 +1375,24 @@ public class SdServer extends Service implements SdDataReceiver {
|
|||||||
mSMSAlarm = SP.getBoolean("SMSAlarm", false);
|
mSMSAlarm = SP.getBoolean("SMSAlarm", false);
|
||||||
Log.v(TAG, "updatePrefs() - mSMSAlarm = " + mSMSAlarm);
|
Log.v(TAG, "updatePrefs() - mSMSAlarm = " + mSMSAlarm);
|
||||||
mUtil.writeToSysLogFile("updatePrefs() - mSMSAlarm = " + mSMSAlarm);
|
mUtil.writeToSysLogFile("updatePrefs() - mSMSAlarm = " + mSMSAlarm);
|
||||||
mFlogaEmergencyEscalation = SP.getBoolean("FlogaEmergencyEscalation", true);
|
mEmergencySmsEnabled = SP.getBoolean("EmergencySmsEnabled", false);
|
||||||
|
mEmergencySmsNotifyContacts = SP.getBoolean("EmergencySmsNotifyContacts", true);
|
||||||
|
mEmergencySmsNumber = SP.getString("EmergencySmsNumber", "");
|
||||||
|
mEmergencySmsMessage = SP.getString(
|
||||||
|
"EmergencySmsMessage",
|
||||||
|
"Possible seizure emergency. The wearer may be having a tonic-clonic seizure and the alarm has remained active."
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
String emergencyDelayStr = SP.getString("EmergencySmsDelaySecs", "300");
|
||||||
|
mEmergencySmsDelaySecs = Integer.parseInt(emergencyDelayStr);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
mEmergencySmsDelaySecs = 300;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.v(TAG, "updatePrefs() - mEmergencySmsEnabled = " + mEmergencySmsEnabled);
|
||||||
|
Log.v(TAG, "updatePrefs() - mEmergencySmsNumber = " + mEmergencySmsNumber);
|
||||||
|
Log.v(TAG, "updatePrefs() - mEmergencySmsDelaySecs = " + mEmergencySmsDelaySecs);
|
||||||
mPhoneAlarm = SP.getBoolean("PhoneCallAlarm", false);
|
mPhoneAlarm = SP.getBoolean("PhoneCallAlarm", false);
|
||||||
Log.v(TAG, "updatePrefs() - mSMSAlarm = " + mSMSAlarm);
|
Log.v(TAG, "updatePrefs() - mSMSAlarm = " + mSMSAlarm);
|
||||||
mUtil.writeToSysLogFile("updatePrefs() - mSMSAlarm = " + mSMSAlarm);
|
mUtil.writeToSysLogFile("updatePrefs() - mSMSAlarm = " + mSMSAlarm);
|
||||||
@@ -1509,6 +1586,7 @@ public class SdServer extends Service implements SdDataReceiver {
|
|||||||
+ ";u=" + df.format(ll.getAccuracy()) + "'>here</a>";
|
+ ";u=" + df.format(ll.getAccuracy()) + "'>here</a>";
|
||||||
String googleUrl = "https://www.google.com/maps/place?q="
|
String googleUrl = "https://www.google.com/maps/place?q="
|
||||||
+ ll.getLatitude() + "%2C" + ll.getLongitude();
|
+ ll.getLatitude() + "%2C" + ll.getLongitude();
|
||||||
|
mLastLocationUrl = googleUrl;
|
||||||
String shortUuidStr = mUuidStr.substring(mUuidStr.length() - 6);
|
String shortUuidStr = mUuidStr.substring(mUuidStr.length() - 6);
|
||||||
|
|
||||||
String messageStr = "Location update for seizure detected at "
|
String messageStr = "Location update for seizure detected at "
|
||||||
@@ -1532,7 +1610,69 @@ public class SdServer extends Service implements SdDataReceiver {
|
|||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
private void sendSMSDirect(String phoneNo, String msgStr) {
|
||||||
|
String number = phoneNo == null ? "" : phoneNo.trim();
|
||||||
|
|
||||||
|
if (number.length() == 0) {
|
||||||
|
Log.w(TAG, "sendSMSDirect() - empty phone number, skipping");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.i(TAG, "sendSMSDirect() - Sending to " + number);
|
||||||
|
|
||||||
|
try {
|
||||||
|
SmsManager sm = SmsManager.getDefault();
|
||||||
|
sm.sendTextMessage(number, null, msgStr, null, null);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "sendSMSDirect - Failed to send SMS Message");
|
||||||
|
mUtil.writeToSysLogFile("sendSMSDirect - Failed to send SMS Message");
|
||||||
|
Log.e(TAG, e.toString());
|
||||||
|
mUtil.showToast(getString(R.string.failed_to_send_sms));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void sendEmergencySms() {
|
||||||
|
String shortUuidStr = mUuidStr.substring(mUuidStr.length() - 6);
|
||||||
|
|
||||||
|
String locationPart;
|
||||||
|
if (mLastLocationUrl != null && mLastLocationUrl.length() > 0) {
|
||||||
|
locationPart = " Location: " + mLastLocationUrl;
|
||||||
|
} else {
|
||||||
|
locationPart = " Location unavailable.";
|
||||||
|
}
|
||||||
|
|
||||||
|
String alarmTimePart;
|
||||||
|
if (mLastAlarmDateStr != null && mLastAlarmDateStr.length() > 0) {
|
||||||
|
alarmTimePart = " Alarm time: " + mLastAlarmDateStr + ".";
|
||||||
|
} else {
|
||||||
|
alarmTimePart = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
String emergencyMessage = mEmergencySmsMessage
|
||||||
|
+ alarmTimePart
|
||||||
|
+ " Alarm duration: "
|
||||||
|
+ mEmergencySmsDelaySecs
|
||||||
|
+ " seconds."
|
||||||
|
+ locationPart
|
||||||
|
+ " Device ID: "
|
||||||
|
+ shortUuidStr;
|
||||||
|
|
||||||
|
Log.i(TAG, "sendEmergencySms() - sending emergency SMS to " + mEmergencySmsNumber);
|
||||||
|
Log.i(TAG, "sendEmergencySms() - message: " + emergencyMessage);
|
||||||
|
|
||||||
|
sendSMSDirect(mEmergencySmsNumber, emergencyMessage);
|
||||||
|
|
||||||
|
if (mEmergencySmsNotifyContacts) {
|
||||||
|
String contactMessage = "Emergency services have been contacted for seizure alert"
|
||||||
|
+ alarmTimePart
|
||||||
|
+ locationPart
|
||||||
|
+ " Device: "
|
||||||
|
+ shortUuidStr;
|
||||||
|
|
||||||
|
for (int i = 0; i < mSMSNumbers.length; i++) {
|
||||||
|
sendSMSDirect(mSMSNumbers[i], contactMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Latch alarm in alarm state for a given period (mLatchAlarmPeriod seconds) after the alarm is raised.
|
* Latch alarm in alarm state for a given period (mLatchAlarmPeriod seconds) after the alarm is raised.
|
||||||
@@ -1619,7 +1759,37 @@ public class SdServer extends Service implements SdDataReceiver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class EmergencySmsTimer extends CountDownTimer {
|
||||||
|
public EmergencySmsTimer(long startTime, long interval) {
|
||||||
|
super(startTime, interval);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFinish() {
|
||||||
|
Log.i(TAG, "EmergencySmsTimer.onFinish()");
|
||||||
|
|
||||||
|
mEmergencySmsTimer = null;
|
||||||
|
|
||||||
|
if (mEmergencySmsSent) {
|
||||||
|
Log.i(TAG, "EmergencySmsTimer.onFinish() - already sent");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mSdData == null || !mSdData.alarmStanding) {
|
||||||
|
Log.i(TAG, "EmergencySmsTimer.onFinish() - alarm no longer standing, not sending");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sendEmergencySms();
|
||||||
|
mEmergencySmsSent = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTick(long msRemaining) {
|
||||||
|
Log.v(TAG, "EmergencySmsTimer.onTick() - time remaining = "
|
||||||
|
+ msRemaining / 1000 + " sec");
|
||||||
|
}
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Inhibit fault alarm initiation for a period to avoid spurious warning
|
* Inhibit fault alarm initiation for a period to avoid spurious warning
|
||||||
* beeps caused by short term network interruptions.
|
* beeps caused by short term network interruptions.
|
||||||
|
|||||||
@@ -87,6 +87,41 @@
|
|||||||
android:summary="@string/sms_false_alarm_message_summary"
|
android:summary="@string/sms_false_alarm_message_summary"
|
||||||
android:title="@string/sms_false_alarm_message_title" />
|
android:title="@string/sms_false_alarm_message_title" />
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
|
<PreferenceCategory android:title="Emergency Services SMS Settings">
|
||||||
|
|
||||||
|
<CheckBoxPreference
|
||||||
|
android:defaultValue="false"
|
||||||
|
android:key="EmergencySmsEnabled"
|
||||||
|
android:summary="Send a separate SMS to the emergency services test number if the seizure alarm remains active for the configured delay."
|
||||||
|
android:title="Enable emergency services SMS" />
|
||||||
|
|
||||||
|
<EditTextPreference
|
||||||
|
android:defaultValue=""
|
||||||
|
android:key="EmergencySmsNumber"
|
||||||
|
android:summary="Test number for emergency services escalation. Use a project/test number, not a real emergency number."
|
||||||
|
android:title="Emergency services test number" />
|
||||||
|
|
||||||
|
<EditTextPreference
|
||||||
|
android:defaultValue="300"
|
||||||
|
android:key="EmergencySmsDelaySecs"
|
||||||
|
android:inputType="number"
|
||||||
|
android:summary="Delay before emergency services SMS is sent. Use 300 for 5 minutes; use a shorter value for testing."
|
||||||
|
android:title="Emergency SMS delay seconds" />
|
||||||
|
|
||||||
|
<EditTextPreference
|
||||||
|
android:defaultValue="Possible seizure emergency. The wearer may be having a tonic-clonic seizure and the alarm has remained active."
|
||||||
|
android:key="EmergencySmsMessage"
|
||||||
|
android:summary="Message prefix for the emergency services SMS."
|
||||||
|
android:title="Emergency services SMS message" />
|
||||||
|
|
||||||
|
<CheckBoxPreference
|
||||||
|
android:defaultValue="true"
|
||||||
|
android:key="EmergencySmsNotifyContacts"
|
||||||
|
android:summary="Also send a follow-up SMS to normal contacts when the emergency services SMS is sent."
|
||||||
|
android:title="Notify contacts after emergency SMS" />
|
||||||
|
|
||||||
|
</PreferenceCategory>
|
||||||
<!--
|
<!--
|
||||||
<PreferenceCategory android:title="Phone Call Alarm Settings">
|
<PreferenceCategory android:title="Phone Call Alarm Settings">
|
||||||
<CheckBoxPreference
|
<CheckBoxPreference
|
||||||
|
|||||||
Reference in New Issue
Block a user