Moved web server to separate file to simplify SdServer, and fixed issue with fault alarms not being raised over network connection.

This commit is contained in:
Graham Jones
2015-12-08 18:28:14 +00:00
parent ba13ae226c
commit 9826fda1ba
4 changed files with 242 additions and 196 deletions

View File

@@ -325,6 +325,10 @@ public class MainActivity extends Activity {
tv.setText("WARNING"); tv.setText("WARNING");
tv.setBackgroundColor(warnColour); tv.setBackgroundColor(warnColour);
} }
if (mConnection.mSdServer.mSdData.alarmState == 4) {
tv.setText("FAULT");
tv.setBackgroundColor(warnColour);
}
if (mConnection.mSdServer.mSdData.alarmStanding) { if (mConnection.mSdServer.mSdData.alarmStanding) {
tv.setText("**ALARM**"); tv.setText("**ALARM**");
tv.setBackgroundColor(alarmColour); tv.setBackgroundColor(alarmColour);

View File

@@ -116,7 +116,7 @@ public class SdDataSourceNetwork extends SdDataSource {
sdData.serverOK = false; sdData.serverOK = false;
sdData.pebbleConnected = false; sdData.pebbleConnected = false;
sdData.pebbleAppRunning = false; sdData.pebbleAppRunning = false;
sdData.alarmState = 0; sdData.alarmState = 4;
sdData.alarmPhrase = "Warning - No Connection to Server"; sdData.alarmPhrase = "Warning - No Connection to Server";
Log.v(TAG,"doInBackground(): No Connection to Server - sdData = "+sdData.toString()); Log.v(TAG,"doInBackground(): No Connection to Server - sdData = "+sdData.toString());
} else { } else {
@@ -135,7 +135,7 @@ public class SdDataSourceNetwork extends SdDataSource {
sdData.serverOK = false; sdData.serverOK = false;
sdData.pebbleConnected = false; sdData.pebbleConnected = false;
sdData.pebbleAppRunning = false; sdData.pebbleAppRunning = false;
sdData.alarmState = 0; sdData.alarmState = 4;
sdData.alarmPhrase = "Warning - No Connection to Server"; sdData.alarmPhrase = "Warning - No Connection to Server";
Log.v(TAG,"doInBackground(): IOException - "+e.toString()); Log.v(TAG,"doInBackground(): IOException - "+e.toString());
return sdData; return sdData;

View File

@@ -78,7 +78,7 @@ public class SdServer extends Service implements SdDataReceiver {
private NotificationManager mNM; private NotificationManager mNM;
private WebServer webServer = null; private SdWebServer webServer = null;
private final static String TAG = "SdServer"; private final static String TAG = "SdServer";
private Timer dataLogTimer = null; private Timer dataLogTimer = null;
private CancelAudibleTimer mCancelAudibleTimer = null; private CancelAudibleTimer mCancelAudibleTimer = null;
@@ -276,7 +276,7 @@ public class SdServer extends Service implements SdDataReceiver {
* @param sdData * @param sdData
*/ */
public void onSdDataReceived(SdData sdData) { public void onSdDataReceived(SdData sdData) {
Log.v(TAG, "onSdDataReceived()"); Log.v(TAG, "onSdDataReceived() - "+sdData.toString());
if (sdData.alarmState == 0) { if (sdData.alarmState == 0) {
if ((!mLatchAlarms) || if ((!mLatchAlarms) ||
(mLatchAlarms && (mLatchAlarms &&
@@ -354,12 +354,22 @@ public class SdServer extends Service implements SdDataReceiver {
} }
} }
// Fault
if ((sdData.alarmState == 4)) {
sdData.alarmPhrase = "FAULT";
faultWarningBeep();
}
mSdData = sdData; mSdData = sdData;
if (webServer!=null) webServer.setSdData(mSdData);
Log.v(TAG,"onSdDataReceived() - setting mSdData to "+mSdData.toString()); Log.v(TAG,"onSdDataReceived() - setting mSdData to "+mSdData.toString());
} }
// Called by SdDataSource when a fault condition is detected.
public void onSdDataFault(SdData sdData) { public void onSdDataFault(SdData sdData) {
Log.v(TAG,"onSdDataFault()"); Log.v(TAG,"onSdDataFault()");
mSdData = sdData;
mSdData.alarmState = 4; // set fault alarm state.
if (webServer!=null) webServer.setSdData(mSdData);
if (mAudibleFaultWarning) { if (mAudibleFaultWarning) {
faultWarningBeep(); faultWarningBeep();
} }
@@ -494,7 +504,7 @@ public class SdServer extends Service implements SdDataReceiver {
protected void startWebServer() { protected void startWebServer() {
Log.v(TAG, "startWebServer()"); Log.v(TAG, "startWebServer()");
if (webServer == null) { if (webServer == null) {
webServer = new WebServer(); webServer = new SdWebServer(getApplicationContext(),getDataStorageDir(),mSdData);
try { try {
webServer.start(); webServer.start();
} catch (IOException ioe) { } catch (IOException ioe) {
@@ -666,195 +676,4 @@ public class SdServer extends Service implements SdDataReceiver {
/**
* Class describing the seizure detector web server - appears on port
* 8080.
*/
private class WebServer extends NanoHTTPD {
private String TAG = "WebServer";
public WebServer() {
// Set the port to listen on (8080)
super(8080);
}
@Override
public Response serve(String uri, Method method,
Map<String, String> header,
Map<String, String> parameters,
Map<String, String> files) {
Log.v(TAG, "WebServer.serve() - uri=" + uri + " Method=" + method.toString());
String answer = "Error - you should not see this message! - Something wrong in WebServer.serve()";
Iterator it = parameters.keySet().iterator();
while (it.hasNext()) {
Object key = it.next();
Object value = parameters.get(key);
//Log.v(TAG,"Request parameters - key="+key+" value="+value);
}
if (uri.equals("/")) uri = "/index.html";
switch (uri) {
case "/data":
//Log.v(TAG,"WebServer.serve() - Returning data");
try {
answer = mSdData.toString();
} catch (Exception ex) {
Log.v(TAG, "Error Creating Data Object - " + ex.toString());
answer = "Error Creating Data Object";
}
break;
case "/settings":
//Log.v(TAG,"WebServer.serve() - Returning settings");
try {
JSONObject jsonObj = new JSONObject();
jsonObj.put("alarmFreqMin", mSdData.alarmFreqMin);
jsonObj.put("alarmFreqMax", mSdData.alarmFreqMax);
jsonObj.put("nMin", mSdData.nMin);
jsonObj.put("nMax", mSdData.nMax);
jsonObj.put("warnTime", mSdData.warnTime);
jsonObj.put("alarmTime", mSdData.alarmTime);
jsonObj.put("alarmThresh", mSdData.alarmThresh);
jsonObj.put("alarmRatioThresh", mSdData.alarmRatioThresh);
jsonObj.put("batteryPc", mSdData.batteryPc);
answer = jsonObj.toString();
} catch (Exception ex) {
Log.v(TAG, "Error Creating Data Object - " + ex.toString());
answer = "Error Creating Data Object";
}
break;
case "/spectrum":
Log.v(TAG, "WebServer.serve() - Returning spectrum - 1");
try {
JSONObject jsonObj = new JSONObject();
Log.v(TAG, "WebServer.serve() - Returning spectrum - 2");
// Initialised it this way because one phone was ok with JSONArray(mSdData.simpleSpec), and the other crashed...
JSONArray arr = new JSONArray();
for (int i = 0; i < mSdData.simpleSpec.length; i++) {
arr.put(mSdData.simpleSpec[i]);
}
Log.v(TAG, "WebServer.serve() - Returning spectrum - 3");
jsonObj.put("simpleSpec", arr);
Log.v(TAG, "WebServer.serve() - Returning spectrum - 4");
answer = jsonObj.toString();
Log.v(TAG, "WebServer.serve() - Returning spectrum - 5" + answer);
} catch (Exception ex) {
Log.v(TAG, "Error Creating Data Object - " + ex.toString());
answer = "Error Creating Data Object";
}
break;
default:
if (uri.startsWith("/index.html") ||
uri.startsWith("/favicon.ico") ||
uri.startsWith("/js/") ||
uri.startsWith("/css/") ||
uri.startsWith("/img/")) {
//Log.v(TAG,"Serving File");
return serveFile(uri);
} else if (uri.startsWith("/logs")) {
Log.v(TAG, "WebServer.serve() - serving data logs - uri=" + uri);
NanoHTTPD.Response resp = serveLogFile(uri);
Log.v(TAG, "WebServer.serve() - response = " + resp.toString());
return resp;
} else {
Log.v(TAG, "WebServer.serve() - Unknown uri -" +
uri);
answer = "Unknown URI: ";
}
}
return new NanoHTTPD.Response(answer);
}
/**
* Return a file from the external storage folder
*/
NanoHTTPD.Response serveLogFile(String uri) {
NanoHTTPD.Response res;
InputStream ip = null;
String uripart;
Log.v(TAG, "serveLogFile(" + uri + ")");
try {
if (ip != null) ip.close();
String storageDir = getDataStorageDir().toString();
StringTokenizer uriParts = new StringTokenizer(uri, "/");
Log.v(TAG, "serveExternalFile - number of tokens = " + uriParts.countTokens());
while (uriParts.hasMoreTokens()) {
uripart = uriParts.nextToken();
Log.v(TAG, "uripart=" + uripart);
}
// If we have only given a "/logs" URI, return a list of
// available files.
// Re-start the StringTokenizer from the start.
uriParts = new StringTokenizer(uri, "/");
Log.v(TAG, "serveExternalFile - number of tokens = "
+ uriParts.countTokens());
if (uriParts.countTokens() == 1) {
Log.v(TAG, "Returning list of files");
File dirs = getDataStorageDir();
try {
JSONObject jsonObj = new JSONObject();
if (dirs.exists()) {
String[] fileList = dirs.list();
JSONArray arr = new JSONArray();
for (int i = 0; i < fileList.length; i++)
arr.put(fileList[i]);
jsonObj.put("logFileList", arr);
}
res = new NanoHTTPD.Response(NanoHTTPD.Response.Status.OK,
"text/html", jsonObj.toString());
} catch (Exception ex) {
res = new NanoHTTPD.Response(NanoHTTPD.Response.Status.OK,
"text/html", "ERROR - " + ex.toString());
}
return res;
}
uripart = uriParts.nextToken(); // This will just be /logs
uripart = uriParts.nextToken(); // this is the requested file.
String fname = storageDir + "/" + uripart;
Log.v(TAG, "serveLogFile - uri=" + uri + ", fname=" + fname);
ip = new FileInputStream(fname);
String mimeStr = "text/html";
res = new NanoHTTPD.Response(NanoHTTPD.Response.Status.OK,
mimeStr, ip);
res.addHeader("Content-Length", "" + ip.available());
} catch (IOException ex) {
Log.v(TAG, "serveLogFile(): Error Opening File - " + ex.toString());
res = new NanoHTTPD.Response("serveLogFile(): Error Opening file " + uri);
}
return (res);
}
/**
* Return a file from the apps /assets folder
*/
NanoHTTPD.Response serveFile(String uri) {
NanoHTTPD.Response res;
InputStream ip = null;
try {
if (ip != null) ip.close();
String assetPath = "www";
String fname = assetPath + uri;
//Log.v(TAG,"serveFile - uri="+uri+", fname="+fname);
AssetManager assetManager = getResources().getAssets();
ip = assetManager.open(fname);
String mimeStr = "text/html";
res = new NanoHTTPD.Response(NanoHTTPD.Response.Status.OK,
mimeStr, ip);
res.addHeader("Content-Length", "" + ip.available());
} catch (IOException ex) {
Log.v(TAG, "serveFile(): Error Opening File - " + ex.toString());
res = new NanoHTTPD.Response("serveFile(): Error Opening file " + uri);
}
return (res);
}
}
} }

View File

@@ -0,0 +1,223 @@
package uk.org.openseizuredetector;
import android.content.Context;
import android.content.res.AssetManager;
import android.util.Log;
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.Map;
import java.util.StringTokenizer;
import fi.iki.elonen.NanoHTTPD;
/**
* Class describing the seizure detector web server - appears on port
* 8080.
*/
public class SdWebServer extends NanoHTTPD {
private String TAG = "WebServer";
private SdData mSdData;
private Context mContext;
private File mDataStorageDir = null;
public SdWebServer(Context context, File storageDir, SdData sdData) {
// Set the port to listen on (8080)
super(8080);
mSdData = sdData;
mContext = context;
mDataStorageDir = storageDir;
}
public void setSdData(SdData sdData) {
Log.v(TAG,"setSdData()");
mSdData = sdData;
}
@Override
public Response serve(String uri, Method method,
Map<String, String> header,
Map<String, String> parameters,
Map<String, String> files) {
Log.v(TAG, "WebServer.serve() - uri=" + uri + " Method=" + method.toString());
String answer = "Error - you should not see this message! - Something wrong in WebServer.serve()";
Iterator it = parameters.keySet().iterator();
while (it.hasNext()) {
Object key = it.next();
Object value = parameters.get(key);
//Log.v(TAG,"Request parameters - key="+key+" value="+value);
}
if (uri.equals("/")) uri = "/index.html";
switch (uri) {
case "/data":
//Log.v(TAG,"WebServer.serve() - Returning data");
try {
answer = mSdData.toString();
} catch (Exception ex) {
Log.v(TAG, "Error Creating Data Object - " + ex.toString());
answer = "Error Creating Data Object";
}
break;
case "/settings":
//Log.v(TAG,"WebServer.serve() - Returning settings");
try {
JSONObject jsonObj = new JSONObject();
jsonObj.put("alarmFreqMin", mSdData.alarmFreqMin);
jsonObj.put("alarmFreqMax", mSdData.alarmFreqMax);
jsonObj.put("nMin", mSdData.nMin);
jsonObj.put("nMax", mSdData.nMax);
jsonObj.put("warnTime", mSdData.warnTime);
jsonObj.put("alarmTime", mSdData.alarmTime);
jsonObj.put("alarmThresh", mSdData.alarmThresh);
jsonObj.put("alarmRatioThresh", mSdData.alarmRatioThresh);
jsonObj.put("batteryPc", mSdData.batteryPc);
answer = jsonObj.toString();
} catch (Exception ex) {
Log.v(TAG, "Error Creating Data Object - " + ex.toString());
answer = "Error Creating Data Object";
}
break;
case "/spectrum":
Log.v(TAG, "WebServer.serve() - Returning spectrum - 1");
try {
JSONObject jsonObj = new JSONObject();
Log.v(TAG, "WebServer.serve() - Returning spectrum - 2");
// Initialised it this way because one phone was ok with JSONArray(mSdData.simpleSpec), and the other crashed...
JSONArray arr = new JSONArray();
for (int i = 0; i < mSdData.simpleSpec.length; i++) {
arr.put(mSdData.simpleSpec[i]);
}
Log.v(TAG, "WebServer.serve() - Returning spectrum - 3");
jsonObj.put("simpleSpec", arr);
Log.v(TAG, "WebServer.serve() - Returning spectrum - 4");
answer = jsonObj.toString();
Log.v(TAG, "WebServer.serve() - Returning spectrum - 5" + answer);
} catch (Exception ex) {
Log.v(TAG, "Error Creating Data Object - " + ex.toString());
answer = "Error Creating Data Object";
}
break;
default:
if (uri.startsWith("/index.html") ||
uri.startsWith("/favicon.ico") ||
uri.startsWith("/js/") ||
uri.startsWith("/css/") ||
uri.startsWith("/img/")) {
//Log.v(TAG,"Serving File");
return serveFile(uri);
} else if (uri.startsWith("/logs")) {
Log.v(TAG, "WebServer.serve() - serving data logs - uri=" + uri);
NanoHTTPD.Response resp = serveLogFile(uri);
Log.v(TAG, "WebServer.serve() - response = " + resp.toString());
return resp;
} else {
Log.v(TAG, "WebServer.serve() - Unknown uri -" +
uri);
answer = "Unknown URI: ";
}
}
return new NanoHTTPD.Response(answer);
}
/**
* Return a file from the external storage folder
*/
NanoHTTPD.Response serveLogFile(String uri) {
NanoHTTPD.Response res;
InputStream ip = null;
String uripart;
Log.v(TAG, "serveLogFile(" + uri + ")");
try {
if (ip != null) ip.close();
StringTokenizer uriParts = new StringTokenizer(uri, "/");
Log.v(TAG, "serveExternalFile - number of tokens = " + uriParts.countTokens());
while (uriParts.hasMoreTokens()) {
uripart = uriParts.nextToken();
Log.v(TAG, "uripart=" + uripart);
}
// If we have only given a "/logs" URI, return a list of
// available files.
// Re-start the StringTokenizer from the start.
uriParts = new StringTokenizer(uri, "/");
Log.v(TAG, "serveExternalFile - number of tokens = "
+ uriParts.countTokens());
if (uriParts.countTokens() == 1) {
Log.v(TAG, "Returning list of files");
File dirs = mDataStorageDir;
try {
JSONObject jsonObj = new JSONObject();
if (dirs.exists()) {
String[] fileList = dirs.list();
JSONArray arr = new JSONArray();
for (int i = 0; i < fileList.length; i++)
arr.put(fileList[i]);
jsonObj.put("logFileList", arr);
}
res = new NanoHTTPD.Response(NanoHTTPD.Response.Status.OK,
"text/html", jsonObj.toString());
} catch (Exception ex) {
res = new NanoHTTPD.Response(NanoHTTPD.Response.Status.OK,
"text/html", "ERROR - " + ex.toString());
}
return res;
}
uripart = uriParts.nextToken(); // This will just be /logs
uripart = uriParts.nextToken(); // this is the requested file.
String fname = mDataStorageDir.toString() + "/" + uripart;
Log.v(TAG, "serveLogFile - uri=" + uri + ", fname=" + fname);
ip = new FileInputStream(fname);
String mimeStr = "text/html";
res = new NanoHTTPD.Response(NanoHTTPD.Response.Status.OK,
mimeStr, ip);
res.addHeader("Content-Length", "" + ip.available());
} catch (IOException ex) {
Log.v(TAG, "serveLogFile(): Error Opening File - " + ex.toString());
res = new NanoHTTPD.Response("serveLogFile(): Error Opening file " + uri);
}
return (res);
}
/**
* Return a file from the apps /assets folder
*/
NanoHTTPD.Response serveFile(String uri) {
NanoHTTPD.Response res;
InputStream ip = null;
try {
if (ip != null) ip.close();
String assetPath = "www";
String fname = assetPath + uri;
//Log.v(TAG,"serveFile - uri="+uri+", fname="+fname);
AssetManager assetManager = mContext.getResources().getAssets();
ip = assetManager.open(fname);
String mimeStr = "text/html";
res = new NanoHTTPD.Response(NanoHTTPD.Response.Status.OK,
mimeStr, ip);
res.addHeader("Content-Length", "" + ip.available());
} catch (IOException ex) {
Log.v(TAG, "serveFile(): Error Opening File - " + ex.toString());
res = new NanoHTTPD.Response("serveFile(): Error Opening file " + uri);
}
return (res);
}
}