--- /dev/null
+# Settings
+config.mk
+
+# Local files
+local/
+
+# Vim junk
+*~
+*.swp
+
+# Android junk
+bin/
+gen/
+obj/
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.sycapp"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
+ <uses-sdk
+ android:minSdkVersion="14"
+ android:targetSdkVersion="18" />
+
+ <application
+ android:allowBackup="true"
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ android:theme="@style/AppTheme" >
+ <activity
+ android:name="com.example.sycapp.MainActivity"
+ android:label="@string/app_name" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
--- /dev/null
+-include config.mk
+
+# Settings
+PROGRAM ?= sycApp
+PACKAGE ?= com.example.sycapp
+KEYFILE ?= ~/.android/android.p12
+KEYTYPE ?= pkcs12
+KEYNAME ?= android
+ANDROID ?= /opt/android-sdk-update-manager/platforms/android-18/android.jar
+SDKLIB ?= /opt/android-sdk-update-manager/tools/lib/sdklib.jar
+TOOLS ?= /opt/android-sdk-update-manager/build-tools/19.0.1
+
+# Variables
+PATH := $(PATH):$(TOOLS)
+DIR := $(subst .,/,$(PACKAGE))
+RES := $(wildcard res/*/*.*)
+SRC := $(wildcard src/$(DIR)/*.java)
+GEN := gen/$(DIR)/R.java
+OBJ := obj/$(DIR)/R.class
+APK := java -classpath $(SDKLIB) \
+ com.android.sdklib.build.ApkBuilderMain
+
+# Targets
+debug: bin/$(PROGRAM).dbg
+
+release: bin/$(PROGRAM).apk
+
+compile: $(OBJ)
+
+clean:
+ rm -rf bin gen obj
+
+# ADB targets
+logcat:
+ adb logcat $(PROGRAM):D AndroidRuntime:E '*:S'
+
+run: bin/install.stamp
+ adb shell am start -W \
+ -a android.intent.action.MAIN \
+ -n $(PACKAGE)/.MainActivity
+
+install bin/install.stamp: bin/$(PROGRAM).dbg
+ adb install -r $+
+ touch bin/install.stamp
+
+uninstall:
+ adb uninstall $(PACKAGE)
+ rm -f bin/install.stamp
+
+# Rules
+%.dbg: %.dex %.res | bin
+ @echo "APK $@.in"
+ @$(APK) $@.in -f $*.dex -z $*.res
+ @echo "ALIGN $@"
+ @zipalign -f 4 $@.in $@
+
+%.apk: %.dex %.res | bin
+ @echo "APKU $@.in"
+ @$(APK) $@.in -u -f $*.dex -z $*.res
+ @echo "SIGN $@.in"
+ @jarsigner -storetype $(KEYTYPE) \
+ -keystore $(KEYFILE) \
+ $@.in $(KEYNAME)
+ @echo "ALIGN $@"
+ @zipalign -f 4 $@.in $@
+
+%.dex: $(OBJ) makefile | bin
+ @echo "DEX $@ obj"
+ @dx --dex --output $@ obj
+
+%.res: AndroidManifest.xml $(RES) | bin
+ @echo "RES $@"
+ @aapt package -f -m \
+ -I $(ANDROID) \
+ -M AndroidManifest.xml \
+ -S res \
+ -F $*.res
+
+$(OBJ): $(SRC) $(GEN) makefile | obj
+ @echo "JAVAC obj/*.class $+"
+ @JARS=$(ANDROID); \
+ javac -g \
+ -Xlint:unchecked \
+ -Xlint:deprecation \
+ -bootclasspath $$JARS \
+ -encoding UTF-8 \
+ -source 1.5 \
+ -target 1.5 \
+ -classpath obj \
+ -d obj \
+ $(filter-out makefile,$+)
+
+$(GEN): AndroidManifest.xml $(RES) | gen
+ @echo "GEN $@"
+ @aapt package -f -m \
+ -I $(ANDROID) \
+ -M AndroidManifest.xml \
+ -S res \
+ -J gen
+
+# Directories
+bin gen obj:
+ @mkdir -p $@
+
+# Keep intermediate files
+.SECONDARY:
--- /dev/null
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:paddingBottom="@dimen/activity_vertical_margin"
+ android:paddingLeft="@dimen/activity_horizontal_margin"
+ android:paddingRight="@dimen/activity_horizontal_margin"
+ android:paddingTop="@dimen/activity_vertical_margin"
+ tools:context=".MainActivity" >
+
+ <Switch
+ android:id="@+id/logSwitch"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentBottom="true"
+ android:layout_alignParentLeft="true"
+ android:layout_marginBottom="146dp" />
+
+ <EditText
+ android:id="@+id/fileText"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignBaseline="@+id/logSwitch"
+ android:layout_alignBottom="@+id/logSwitch"
+ android:layout_toRightOf="@+id/TextView1"
+ android:ems="10"
+ android:width="150dp" >
+
+ <requestFocus />
+
+ </EditText>
+
+ <TextView
+ android:id="@+id/textView2"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignBaseline="@+id/xvlSwitch"
+ android:layout_alignBottom="@+id/xvlSwitch"
+ android:layout_alignLeft="@+id/TextView1"
+ android:text="Xively Upload"
+ android:textAppearance="?android:attr/textAppearanceLarge" />
+
+ <TextView
+ android:id="@+id/textView3"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignLeft="@+id/textView2"
+ android:layout_alignTop="@+id/evtSwitch"
+ android:text="Event Generation"
+ android:textAppearance="?android:attr/textAppearanceLarge" />
+
+ <Switch
+ android:id="@+id/evtSwitch"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@+id/xvlSwitch"
+ android:layout_marginTop="23dp"
+ android:layout_toLeftOf="@+id/TextView1" />
+
+ <Switch
+ android:id="@+id/xvlSwitch"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@+id/fileText"
+ android:layout_marginTop="26dp"
+ android:layout_toLeftOf="@+id/TextView1" />
+
+ <Button
+ android:id="@+id/evtBttn"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignBaseline="@+id/textView3"
+ android:layout_alignBottom="@+id/textView3"
+ android:layout_alignRight="@+id/xvlBttn"
+ android:text="Config" />
+
+ <Button
+ android:id="@+id/xvlBttn"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignBaseline="@+id/textView2"
+ android:layout_alignBottom="@+id/textView2"
+ android:layout_toRightOf="@+id/fileText"
+ android:text="Config" />
+
+ <TextView
+ android:id="@+id/TextView1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_above="@+id/xvlSwitch"
+ android:layout_marginLeft="23dp"
+ android:layout_toRightOf="@+id/logSwitch"
+ android:text="Logging into File"
+ android:textAppearance="?android:attr/textAppearanceLarge" />
+
+ <Button
+ android:id="@+id/startBttn"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignLeft="@+id/logSwitch"
+ android:layout_alignRight="@+id/fileBttn"
+ android:text="Start" />
+
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentBottom="true"
+ android:layout_alignParentRight="true"
+ android:layout_alignTop="@+id/startBttn"
+ android:layout_toRightOf="@+id/evtBttn"
+ android:paddingLeft="10dp" >
+
+ <TextView
+ android:id="@+id/dataStream1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="10.42"
+ android:lines="26"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:width="210dp" />
+
+ <TextView
+ android:id="@+id/dataStream2"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="10.42"
+ android:lines="26"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:width="210dp" />
+
+ </LinearLayout>
+
+ <Button
+ android:id="@+id/fileBttn"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignLeft="@+id/xvlBttn"
+ android:layout_alignTop="@+id/fileText"
+ android:text="Config" />
+
+</RelativeLayout>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+
+ <EditText
+ android:id="@+id/oneLineEdit"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:ems="10" >
+
+ <requestFocus />
+ </EditText>
+
+</LinearLayout>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="horizontal" >
+
+ <TableLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <TableRow
+ android:id="@+id/tableRow1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" >
+
+ <TextView
+ android:id="@+id/textView1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingLeft="10dp"
+ android:paddingRight="10dp"
+ android:text="Xively Feed :"
+ android:textAppearance="?android:attr/textAppearanceLarge" />
+
+ <EditText
+ android:id="@+id/xvlFeed"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:ems="16" >
+
+ <requestFocus />
+ </EditText>
+
+ </TableRow>
+
+ <TableRow
+ android:id="@+id/tableRow2"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" >
+
+ <TextView
+ android:id="@+id/textView2"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingLeft="10dp"
+ android:text="Xively ApiKey:"
+ android:textAppearance="?android:attr/textAppearanceLarge" />
+
+ <EditText
+ android:id="@+id/xvlKey"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:ems="10" />
+
+ </TableRow>
+
+ <TableRow
+ android:id="@+id/tableRow3"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" >
+ </TableRow>
+
+ <TableRow
+ android:id="@+id/tableRow4"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" >
+ </TableRow>
+ </TableLayout>
+
+</LinearLayout>
--- /dev/null
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <item
+ android:id="@+id/action_settings"
+ android:orderInCategory="100"
+ android:showAsAction="never"
+ android:title="@string/action_settings"/>
+
+</menu>
--- /dev/null
+<resources>
+
+ <!-- Default screen margins, per the Android Design guidelines. -->
+ <dimen name="activity_horizontal_margin">16dp</dimen>
+ <dimen name="activity_vertical_margin">16dp</dimen>
+
+</resources>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+ <string name="app_name">sycApp</string>
+ <string name="action_settings">Settings</string>
+ <string name="hello_world">Hello world!</string>
+
+</resources>
--- /dev/null
+<resources>
+
+ <!--
+ Base application theme, dependent on API level. This theme is replaced
+ by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
+ -->
+ <style name="AppBaseTheme" parent="android:Theme.Light">
+ <!--
+ Theme customizations available in newer API levels can go in
+ res/values-vXX/styles.xml, while customizations related to
+ backward-compatibility can go here.
+ -->
+ </style>
+
+ <!-- Application theme. -->
+ <style name="AppTheme" parent="AppBaseTheme">
+ <!-- All customizations that are NOT specific to a particular API-level can go here. -->
+ </style>
+
+</resources>
--- /dev/null
+package com.example.sycapp;
+
+import java.util.Timer;
+import java.util.TimerTask;
+
+public class EventGen {
+
+ private boolean evtEnable = true;
+ private int interval;
+
+
+ EventGen(){
+ this.interval = 1000;
+ }
+ public void SetEnable(boolean checked){
+ this.evtEnable = checked;
+ }
+ public void setInterval(int newInt){
+ this.interval = newInt;
+ }
+ public SerialData genTriggerCmd(int did){
+ SerialData command = new SerialData();
+ command.initMessage((short)0x0008, (short)did, (long)0, (long)0, (long)interval);
+ return command;
+ }
+}
--- /dev/null
+package com.example.sycapp;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.util.Vector;
+
+import android.os.Environment;
+
+public class FileLogger {
+ private String fileName = "logFile.txt";
+ private boolean logEnable = true;
+
+ FileLogger(){
+
+ }
+
+ public void setEnable(boolean bool){
+ logEnable = bool;
+ }
+
+ public void setNewFile(String newFileName){
+ fileName = newFileName;
+ Util.debug("[F#0]"+fileName);
+ }
+
+ public String getFileName(){
+ return fileName;
+ }
+
+ public void writeExternal(Vector<SerialData> sData){
+ //if(!logEnable) return;
+ try{
+ File myFile = new File(Environment
+ .getExternalStorageDirectory(), fileName);
+
+ //Util.debug("[F#1]"+fileName);
+ //if (!myFile.exists())
+ //myFile.createNewFile();
+ FileOutputStream fex;
+ fex = new FileOutputStream(myFile,true);
+ for (int i = 0; i < sData.size(); i++){
+ SerialData data = sData.get(i);
+ fex.write(("[Node "+Integer.toString(data.devID)+"] "+data.timeStamp()+"\n").getBytes()) ;
+ }
+ fex.flush();
+ fex.close();
+ }catch(Exception e){
+ Util.debug("M#7"+e.toString());
+ }
+ }
+}
--- /dev/null
+package com.example.sycapp;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.Vector;
+
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.os.Environment;
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.text.format.Time;
+import android.text.method.ScrollingMovementMethod;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.CompoundButton;
+import android.widget.CompoundButton.OnCheckedChangeListener;
+import android.widget.EditText;
+import android.widget.Switch;
+import android.widget.TextView;
+import android.widget.Toast;
+import android.hardware.usb.*;
+
+public class MainActivity extends Activity {
+
+ //private String fileNameExt = "logFile.txt";
+ //private String fileName = "logFile";
+ private FileOutputStream fout;
+ private FileInputStream fin;
+
+ // for serial
+ private SerialIO serial;
+ private SerialIO serial0;
+ private SerialIO serial1;
+ private SerialIO serial2;
+ private SerialIO serial3;
+ private SerialIO serial4;
+ private SerialIO serial5;
+ private Timer timer;
+ private final int interval = 100;
+ private final int xvlTimeUp = 2500;
+ private long currentSeconds;
+
+ // for xively
+ private XivelyUL xively;
+
+ // TODO: need to be deleted
+ private EventGen evtGen;
+
+ private FileLogger fileLog;
+
+
+ // view related
+ private Switch logSW;
+ private Switch xvlSW;
+ private Switch evtSW;
+ private Button startBttn;
+ private Button logBttn;
+ private Button xvlBttn;
+ private Button evtBttn;
+ private EditText fileText;
+ private EditText xvlFeed;
+ private EditText xvlKey;
+ private EditText evtTrInt;
+ private EditText newName;
+ private TextView stream1;
+ private TextView stream2;
+ private TextView diffStr;
+
+ private boolean logEnable;
+
+ private View xvlView;
+ private View evtView;
+ private View logView;
+
+
+ //Display
+ private final int LINENUM = 30;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ Util.debug("Program Start!!");
+
+ LayoutInflater viewGen = LayoutInflater.from(this);
+ //LayoutInflater viewGen = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ this.xvlView = viewGen.inflate(R.layout.xively_cfg_layout, null, false);
+ this.evtView = viewGen.inflate(R.layout.one_alert_layout, null, false);
+ this.logView = viewGen.inflate(R.layout.one_alert_layout, null, false);
+
+ this.timer = new Timer();
+
+ // initial layout
+ this.logSW = (Switch) findViewById(R.id.logSwitch);
+ this.xvlSW = (Switch) findViewById(R.id.xvlSwitch);
+ this.evtSW = (Switch) findViewById(R.id.evtSwitch);
+ this.logBttn = (Button) findViewById(R.id.fileBttn);
+ this.xvlBttn = (Button) findViewById(R.id.xvlBttn);
+ this.evtBttn = (Button) findViewById(R.id.evtBttn);
+ this.startBttn=(Button) findViewById(R.id.startBttn);
+ this.stream1 = (TextView) findViewById(R.id.dataStream1);
+ this.stream2 = (TextView) findViewById(R.id.dataStream2);
+ this.fileText= (EditText) findViewById(R.id.fileText);
+ this.xvlFeed = (EditText) xvlView.findViewById(R.id.xvlFeed);
+ this.xvlKey = (EditText) xvlView.findViewById(R.id.xvlKey);
+ this.evtTrInt= (EditText) evtView.findViewById(R.id.oneLineEdit);
+ this.newName = (EditText) logView.findViewById(R.id.oneLineEdit);
+
+ this.logSW.setOnCheckedChangeListener(new SwitchChangedListener());
+ this.xvlSW.setOnCheckedChangeListener(new SwitchChangedListener());
+ this.evtSW.setOnCheckedChangeListener(new SwitchChangedListener());
+ this.startBttn.setOnClickListener(new ButtonClickListener());
+ this.logBttn .setOnClickListener(new ButtonClickListener());
+ this.xvlBttn .setOnClickListener(new ButtonClickListener());
+ this.evtBttn .setOnClickListener(new ButtonClickListener());
+
+ /*logSW .setEnabled(false);
+ xvlSW .setEnabled(false);
+ evtSW .setEnabled(false);
+ logBttn.setEnabled(false);
+ xvlBttn.setEnabled(false);
+ evtBttn.setEnabled(false);*/
+
+
+
+
+
+
+ //try {fout = openFileOutput(fileName, Context.MODE_PRIVATE);
+ // fin = openFileInput (fileName);}
+ //catch(Exception e) {Util.debug("[M#1]"+e.toString());}
+ this.serial = new SerialIO(fout);
+ //this.serial0= new SerialIO("/dev/ttyO0");
+ this.serial1= new SerialIO("/dev/ttyO1", 1);
+ this.serial2= new SerialIO("/dev/ttyO2", 2);
+ //this.serial3= new SerialIO("/dev/ttyO3");
+ this.xively = new XivelyUL();
+ this.evtGen = new EventGen();
+ this.fileLog= new FileLogger();
+
+ //logEnable = true;
+ xively.setEnable(false);
+ evtGen.SetEnable(false);
+ fileLog.setEnable(false);
+
+
+ //stream1.setMovementMethod(new ScrollingMovementMethod().getInstance());
+ timer.scheduleAtFixedRate(new MainCycle(), 0, interval);
+
+
+ /*stream1.append("aa\n");
+ stream1.append("bb\n");
+ stream1.append("cc\n");
+ stream1.append("dd\n");
+ stream1.append("ee\n");
+ stream1.append("aa\n");
+ stream1.append("bb\n");
+ stream1.append("cc\n");
+ stream1.append("dd\n");
+ stream1.append("ee\n");
+ stream1.append("aa\n");
+ stream1.append("bb\n");
+ stream1.append("cc\n");
+ stream1.append("dd\n");
+ stream1.append("ee\n");
+ stream1.append("aa\n");
+ stream1.append("bb\n");
+ stream1.append("cc\n");
+ stream1.append("dd\n");
+ stream1.append("ee\n");
+ stream1.append("aa\n");
+ stream1.append("bb\n");
+ stream1.append("cc\n");
+ stream1.append("dd\n");
+ stream1.append("ee\n");
+ stream1.append("aa\n");
+ stream1.append("bb\n");
+ stream1.append("cc\n");
+ stream1.append("dd\n");
+ stream1.append("ee\n");
+ stream1.append("aa\n");
+ stream1.append("bb\n");
+ stream1.append("cc\n");
+ stream1.append("dd\n");
+ stream1.append("ee\n");
+ stream1.append("aa\n");
+ stream1.append("bb\n");
+ stream1.append("cc\n");
+ stream1.append("dd\n");
+ stream1.append("ee\n");
+ stream1.append("aa\n");
+ stream1.append("bb\n");
+ stream1.append("cc\n");
+ stream1.append("dd\n");
+ stream1.append("ee\n");
+ stream1.append("aa\n");
+ stream1.append("bb\n");
+ stream1.append("cc\n");
+ stream1.append("dd\n");
+ stream1.append("ee\n");
+ stream1.append("aa\n");
+ stream1.append("bb\n");
+ stream1.append("cc\n");
+ stream1.append("dd\n");
+ stream1.append("ee\n");
+ stream1.append("aa\n");
+ stream1.append("bb\n");
+ stream1.append("cc\n");
+ stream1.append("dd\n");
+ stream1.append("ee\n");*/
+
+
+
+ /*String longText = "aaaaaaaaaaaaaaaaaaaaaa\nbbbbbbbbbbbbbbbbbbbb\ncccccccccccccccccccc\n"+
+ "dddddddddddddddddddddd\neeeeeeeeeeeeeeeeeeee\nffffffffffffffffffff\n"+
+ "gggggggggggggggggggggg\nhhhhhhhhhhhhhhhhhhhh\niiiiiiiiiiiiiiiiiiii\n"+
+ "jjjjjjjjjjjjjjjjjjjjjj\nkkkkkkkkkkkkkkkkkkkk\nllllllllllllllllllll\n"+
+ "mmmmmmmmmmmmmmmmmmmmmm\nnnnnnnnnnnnnnnnnnnnn\noooooooooooooooooooo\n"+
+ "pppppppppppppppppppppp\nqqqqqqqqqqqqqqqqqqqq\nrrrrrrrrrrrrrrrrrrrr\n";*/
+
+ //stream2.setText(longText);
+ }
+
+ /*private int lineEnd(TextView text){
+ int lineEnd = -1;
+ if (text.getLineCount()< LINENUM)return -1;
+ String s = text.getText().toString();
+ if (s.length()==0)return -1;
+ while (lineEnd<s.length()&&s.charAt(lineEnd)!='\n'){
+ lineEnd++;
+ }
+ if(lineEnd>=s.length())return -1;
+ return lineEnd+1;
+ }*/
+ /*private void cutLines(TextView text){
+ String s = text.getText().toString();
+ if (s.length()==0)return;
+ while (text.getLineCount()> LINENUM){
+ int lineEnd = 0;
+ while (lineEnd<s.length()&&s.charAt(lineEnd)!='\n'){
+ lineEnd++;
+ }
+ if(lineEnd>=s.length())return;
+ text.getEditableText().delete(0, lineEnd+1);
+ }
+ }*/
+
+ /*private void cutLines(TextView text){
+ String content = text.getText().toString();
+ int totalLen = text.getLineCount();
+ int _nCnt = 0;
+ if(totalLen<LINENUM){
+ return;
+ }else if(totalLen <2*LINENUM){
+ //Approach 1
+ int i;
+ for(i=0; i<content.length(); i++){
+ if(content.charAt(i)=='i'){
+ _nCnt++;
+ if(_nCnt == LINENUM){
+ break;
+ }
+ }
+ }
+ if(i==content.length())return;
+ text.getEditableText().delete(0, i+1);
+ }else{
+ //Approach 2
+ int i;
+ if (totalLen<=LINENUM)return;
+ for(i=content.length(); i>0; i--){
+ if(content.charAt(i)=='\n'){
+ _nCnt++;
+ if((_nCnt+LINENUM-1)>=totalLen){
+ break;
+ }
+ }
+ }
+ if(i<0)return;
+ text.getEditableText().delete(0, i+1);
+ }
+ }*/
+
+ private void cutLines(TextView text){
+ String content = text.getText().toString();
+ int totalLine = text.getLineCount();
+ if (totalLine>LINENUM+1){
+ text.getEditableText().delete(0, 25*(totalLine-1-LINENUM));
+ }
+ }
+
+
+
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.main, menu);
+ return true;
+ }
+
+ private void initTimeStamp(){
+ long currentTimeM = System.currentTimeMillis();
+ SerialData initiator = new SerialData();
+ initiator.initMessage((short)0x00FF, (short)1, currentTimeM, (long)(currentTimeM+1000), (long)100);
+ serial1.send(initiator.initToBytes());
+ initiator.initMessage((short)0x80FF, (short)2, currentTimeM, (long)(currentTimeM+1000), (long)100);
+ serial2.send(initiator.initToBytes());
+ int i;
+ i=0;
+ }
+
+ //--------------------------------------------------------------------
+ // Log Data Related
+
+ private class SwitchChangedListener implements OnCheckedChangeListener{
+
+ @Override
+ public void onCheckedChanged(CompoundButton sw, boolean checked) {
+ // TODO Auto-generated method stub
+ switch(sw.getId()){
+ case R.id.logSwitch: logEnable = !checked; break;
+ case R.id.xvlSwitch: xively.setEnable(checked); break;
+ case R.id.evtSwitch: evtGen.SetEnable(checked); break;
+ }
+ }
+ }
+
+ private class ButtonClickListener implements OnClickListener{
+
+ @Override
+ public void onClick(View v) {
+ switch(v.getId()){
+ case R.id.startBttn:
+ //for(int i=0; i<100;i++){
+ initTimeStamp();
+ //}
+ logSW .setEnabled(true);
+ xvlSW .setEnabled(true);
+ evtSW .setEnabled(true);
+ logBttn.setEnabled(true);
+ xvlBttn.setEnabled(true);
+ evtBttn.setEnabled(true);
+ break;
+ case R.id.fileBttn:
+ AlertDialog.Builder fileDialog = new AlertDialog.Builder(MainActivity.this);
+ fileDialog.setTitle("New File Name");
+ fileDialog.setView(logView);
+ fileDialog.setPositiveButton("Save", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ String newFileName = newName.getText().toString();
+ if (newFileName==""){
+ toast("Fail:Empty File Name");
+ }else{
+ toast("File Setting Succeed");
+ //fileNameExt = newFileName+".txt";
+ fileLog.setNewFile(newFileName+".txt");
+ toast("New File Name Available");
+ }
+ dismiss(logView);
+ dialog.dismiss();
+ }
+ });
+ fileDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ dismiss(logView);
+ dialog.dismiss();
+ }
+ });
+ fileDialog.create().show();
+ break;
+
+ /*try{
+ String newFileName = fileText.getText().toString();
+ if(newFileName==""){
+ Toast.makeText(getApplicationContext(), "Fail:Empty File Name", Toast.LENGTH_LONG).show();
+ return;
+ }
+ fileNameExt = fileText.getText().toString()+".txt";
+ Toast.makeText(getApplicationContext(), "Change Success!!", Toast.LENGTH_LONG).show();
+ //fileNameExt = "newFile.txt";
+ Util.debug("[M#8]FileName Changed to:"+fileNameExt);
+ }catch (Exception e){
+ Util.debug("[M#0]"+e.toString());
+ }
+
+ break;*/
+ case R.id.xvlBttn:
+ Util.debug("[M#10]I'm clicked");
+ AlertDialog.Builder xvlDialog = new AlertDialog.Builder(MainActivity.this);
+ xvlDialog.setTitle("Xively Configuration");
+ xvlDialog.setView(xvlView);
+ xvlDialog.setPositiveButton("Save", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ toast("Xively Feed/Key Set");
+ String newXvlFeed = xvlFeed.getText().toString();
+ String newXvlKey = xvlKey.getText().toString();
+ if (newXvlFeed!="") xively.setFeedID(newXvlFeed);
+ if (newXvlKey !="") xively.setApiKey(newXvlKey);
+ xively.createChannel("mbed1");
+ xively.createChannel("mbed2");
+ dismiss(xvlView);
+ dialog.dismiss();
+ }
+ });
+ xvlDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int arg1) {
+ dismiss(xvlView);
+ dialog.dismiss();
+ }
+ });
+ xvlDialog.setNeutralButton("Reset", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which){
+ toast("Xively Reset Succeed!");
+ xively.resetFeedID();
+ xively.resetApiKey();
+ dismiss(xvlView);
+ dialog.dismiss();
+ }
+ });
+ xvlDialog.create().show();
+ break;
+ case R.id.evtBttn:
+ AlertDialog.Builder evtDialog = new AlertDialog.Builder(MainActivity.this);
+ evtDialog.setTitle("Event Trigger Interval(ms)");
+ evtDialog.setView(evtView);
+ evtDialog.setPositiveButton("Save", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ String newIntervalS = evtTrInt.getText().toString();
+ if(newIntervalS.length()>0) {
+ int interval = Integer.parseInt(evtTrInt.getText().toString());
+ if (interval<10||interval>10000){
+ toast("Fail:In valid Interval");
+ }else{
+ toast("Setting Succeed!");
+ evtGen.setInterval(interval);
+ SerialData cmd = evtGen.genTriggerCmd(1);
+ serial1.send(cmd.initToBytes());
+ cmd = evtGen.genTriggerCmd(2);
+ serial2.send(cmd.initToBytes());
+ }
+ }
+ dismiss(evtView);
+ dialog.dismiss();
+ }
+ });
+ evtDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ dismiss(evtView);
+ dialog.dismiss();
+ }
+ });
+ evtDialog.create().show();
+ break;
+
+ }
+ }
+ }
+
+ private void toast(String s){
+ Toast.makeText(getApplicationContext(), s, Toast.LENGTH_LONG).show();
+ }
+
+ private void dismiss(View view){
+ ViewGroup vg = (ViewGroup) view.getParent();
+ vg.removeView(view);
+ }
+
+ /*private void writeExternal(Vector<SerialData> sData){
+ try{
+ File myFile = new File(Environment
+ .getExternalStorageDirectory(), fileNameExt);
+ //if (!myFile.exists())
+ //myFile.createNewFile();
+ FileOutputStream fex;
+ fex = new FileOutputStream(myFile,true);
+ for (int i = 0; i < sData.size(); i++){
+ SerialData data = sData.get(i);
+ fex.write(("[Node "+Integer.toString(data.devID)+"] ["+Integer.toString(data.msgSeq)+"] "+data.timeStamp()+"\n").getBytes()) ;
+ }
+ fex.flush();
+ fex.close();
+ }catch(Exception e){
+ Util.debug("M#7"+e.toString());
+ }
+ }*/
+
+ /*private void writeData(Vector<SerialData> sData){
+ if (sData==null){
+ return;
+ }
+ try{
+ OutputStreamWriter outputStreamWriter = new OutputStreamWriter(openFileOutput(fileName, Context.MODE_APPEND));
+
+ for(int i=0; i<sData.size(); i++){
+ SerialData data = sData.get(i);
+ //fout = (data.devId==1)?fout1:fout2;
+ outputStreamWriter.write("[Node "+Integer.toString(data.devID)+"] "+data.timeStamp()+"\n");
+ }
+ outputStreamWriter.close();
+ }catch(Exception e){
+ Util.debug("[M#5]"+e.toString());
+ }
+ }*/
+
+ /*private String readData() {
+
+ String ret = "";
+
+ try {
+ InputStream inputStream = openFileInput(fileName);
+
+ if ( inputStream != null ) {
+ InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
+ BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
+ String receiveString = "";
+ StringBuilder stringBuilder = new StringBuilder();
+
+ while ( (receiveString = bufferedReader.readLine()) != null ) {
+ stringBuilder.append(receiveString);
+ }
+
+ inputStream.close();
+ ret = stringBuilder.toString();
+ }
+ }
+ catch (FileNotFoundException e) {
+ Util.debug("File not found: " + e.toString());
+ } catch (IOException e) {
+ Util.debug("Can not read file: " + e.toString());
+ }
+ return ret;
+ }*/
+
+ // Serial 1 for the moment
+ private void packToView(Vector<SerialData> data){
+ for(int i=0; i<data.size(); i++){
+ SerialData d = data.get(i);
+ if(d.portId==1){
+ stream1.append(d.devID+": "+d.timeDisplay()+"\n");
+ }else{
+ stream2.append(d.devID+": "+d.timeDisplay()+"\n");
+ }
+ }
+ }
+
+ private void simpleCal(Vector<SerialData> v1, Vector<SerialData> v2){
+ SerialData d1;
+ SerialData d2;
+ int i=0;
+ int j=0;
+ while(i<v1.size()&& j<v2.size()){
+ d1 = v1.get(i);
+ d2 = v1.get(j);
+ //if(abs(d1.))
+ }
+ }
+
+ private void timeDiff(int wrS1, int wrN1, int wrS2, int wrN2){
+ /*long t1 = (long)(((long)(wrS1)*(long)(1000))+((long)(wrN1)/(long)(1000000)));
+ long t2 = (long)(((long)(wrS2)*(long)(1000))+((long)(wrN2)/(long)(1000000)));
+ String tt1 = new SimpleDateFormat("yyyy-MM-dd", Locale.US).
+ format(new Date(currentTimeM)).toString()*/
+ }
+
+ private int cnt=0;
+ private int xvlCnt;
+ private int dspCnt;
+ private int did_temp = 1;
+ private class MainCycle extends TimerTask{
+
+ @Override
+ public void run() {
+
+ cnt++;
+ dspCnt++;
+ xvlCnt++;
+
+ // for debugger
+ if(cnt>=1000/interval){
+ cnt = 0;
+ Util.debug("check for alive");
+ }
+
+
+ //Serial
+ Vector<SerialData> data = serial1.checkPort();
+ Vector<SerialData> data2 = serial2.checkPort();
+ data.addAll(data2);
+
+ //Fot test: data generator:
+ /*SerialData sd = new SerialData();
+ did_temp = (did_temp==1)?2:1;
+ sd.evtMessage((short)did_temp, (short)0, System.currentTimeMillis(), (long)0);
+ Vector<SerialData> data= new Vector<SerialData>();
+ data.add(sd);*/
+
+
+
+ //Xively
+ new XivelyPack().execute(data); //always pack data
+ if (xvlCnt>=2500/interval){
+ xvlCnt = 0;
+ new XivelyUpload().execute(); //upload when it is time
+ }
+
+ //File Log
+ new LogToFile().execute(data);
+
+
+ //Display
+ final Vector<SerialData> dataToDisplay = data;
+ runOnUiThread(new Runnable(){
+ @Override
+ public void run() {
+ packToView(dataToDisplay);
+ if(dspCnt>=1000/interval){
+ dspCnt = 0;
+ cutLines(stream1);
+ cutLines(stream2);
+ }
+ }
+
+ });
+
+
+
+
+
+ /*Vector<SerialData> data = serial.checkPort();
+ new XivelyPack().execute(data);
+
+ xvlCnt++;
+ if(xvlCnt == (xvlTimeUp/interval)){
+ new XivelyUpload().execute();
+ }
+
+ new LogToFile().execute(data);*/
+
+
+
+
+
+
+
+ //Original WorkFlow
+ /*Vector<SerialData> data = serial.checkPort();
+ xively.packSerialData(data);
+
+ xvlCnt++;
+ if(xvlCnt == (xvlTimeUp/interval)){
+ xively.uploadData();
+ }*/
+
+ //fileLog.writeExternal(data);
+ //if(logEnable){ writeExternal(data);Util.debug("[M#9]Recording");}
+ //else {Util.debug("[M#9]Not writing because of the permit");}
+ //writeData(data);
+ //Util.debug("[Read Result]"+readData());
+ //Util.debug("[Read Result] "+Integer.toString(data.size()));
+
+ //xively.packSerialData(data);
+
+ //test for logThread
+ /*SerialData sd = new SerialData();
+ sd.evtMessage((short)0, (short)0, System.currentTimeMillis(), (long)0);
+ Vector<SerialData> v= new Vector<SerialData>();
+ v.add(sd);*/
+ //xively.uploadData();
+ }
+ }
+
+ int seq = 0;
+ private void test(){
+ SerialData evtData = new SerialData();
+ evtData.evtMessage((short)1, (short)0, System.currentTimeMillis(), 0);
+ serial.send(evtData.evtToBytes());
+ /*SerialData syncData = new SerialData();
+ syncData.evtMessage((short)1, (short)0, System.currentTimeMillis(), 0);
+ //syncData.syncMessage(seq++, System.currentTimeMillis());*/
+ //syncData.syncMessage(seq++, System.currentTimeMillis());
+ }
+
+ private class LogToFile extends AsyncTask<Vector,Void,Void>{
+ @Override
+ @SuppressWarnings("unchecked")
+ protected Void doInBackground(Vector... dataVctArray) {
+ fileLog.writeExternal(dataVctArray[0]);
+ return null;
+ }
+ }
+
+ private class XivelyPack extends AsyncTask<Vector,Void,Void>{
+ @Override
+ @SuppressWarnings("unchecked")
+ protected Void doInBackground(Vector... dataVctArray) {
+ xively.packSerialData(dataVctArray[0]);
+ return null;
+ }
+
+ }
+
+ private class XivelyUpload extends AsyncTask<Void, Void, Void>{
+
+ @Override
+ protected Void doInBackground(Void... voids) {
+ xively.uploadData();
+ return null;
+ }
+ }
+}
--- /dev/null
+package com.example.sycapp;
+
+import java.util.Date;
+import java.util.Locale;
+import java.text.SimpleDateFormat;
+
+public class SerialData {
+ public static final short HEADER =0x1234;
+ public static final int sync_int16Cnt=3;
+ public static final int sync_int32Cnt=3;
+ public static final int evt_int16Cnt=5;
+ public static final int evt_int32Cnt=4;
+
+ public static enum MessageID {MSG_ID_INIT,
+ MSG_ID_SYNC,
+ MSG_ID_EVENT,
+ MSG_MAX_ID,};
+ public short msgID; //head
+ public short length;
+ public short cksum;
+
+ public short valID;
+ public short devID=1; //TODO!!ChangeBack!!!!!!
+ public long worldT;
+ public int wrdS;
+ public int wrdN;
+ public long startT;
+ public int stS;
+ public int stN;
+ public long periodT;
+ public int prS;
+ public int prN;
+
+ public int msgSeq;
+ public long receiveT;
+ public int rcS;
+ public int rcN;
+
+ public short evtID;
+ public long turnOnT;
+ public int toS;
+ public int toN;
+ public int portId;
+
+ // Constructor
+ SerialData(){
+
+ }
+
+ SerialData(short[] st, int[] it, int portId){
+ this.msgID = st[0];
+ this.length = st[1];
+ this.cksum = st[2];
+ this.devID = st[3];
+ this.evtID = st[4];
+ this.wrdS = it[0];
+ this.wrdN = it[1];
+ this.toS = it[2];
+ this.toN = it[3];
+ this.portId = portId;
+ }
+
+
+ // Message Type
+ public void initMessage(short vld, short did, long wrt, long stt, long prt){
+ this.worldT = wrt;
+ this.startT = stt;
+ this.periodT= prt;
+
+
+ this.msgID = (short) MessageID.MSG_ID_INIT.ordinal();
+ this.length= 28;
+ this.cksum = (short)((long)vld+(long)did+wrt+stt+prt);
+
+ this.valID = vld;
+ this.devID = did;
+ this.wrdS = toSeconds(worldT);
+ this.wrdN = toNanoSec(worldT);
+ this.stS = toSeconds(startT);
+ this.stN = toNanoSec(startT);
+ this.prS = toSeconds(periodT);
+ this.prN = toNanoSec(periodT);
+ }
+
+ public void syncMessage(int seq, long time){
+ this.receiveT = time;
+
+ this.msgID = (short) MessageID.MSG_ID_SYNC.ordinal();
+ this.length = 12;
+ this.cksum = (short)((long)seq+time);
+
+ this.msgSeq = seq;
+ this.rcS = toSeconds(receiveT);
+ this.rcN = toNanoSec(receiveT);
+
+ }
+
+ public void evtMessage(short did, short eid, long wrt, long lt){
+ this.worldT = wrt;
+ this.turnOnT = lt;
+
+
+ this.msgID = (short) MessageID.MSG_ID_EVENT.ordinal();
+ this.length = 20;
+ this.cksum = (short)((long)did+(long)eid+wrt+lt);
+
+ this.devID = did;
+ this.evtID = eid;
+ this.wrdS = toSeconds(wrt);
+ this.wrdN = toNanoSec(wrt);
+ this.toS = toSeconds(turnOnT);
+ this.toN = toNanoSec(turnOnT);
+ }
+
+ private int toSeconds(long t){
+ return (int)(long)(t/1000);
+ }
+ private int toNanoSec(long t){
+ int sc = toSeconds(t);
+ return (int)(long)((t-sc*1000)*1000000);
+ }
+
+
+ // Message to Bytes
+ public byte[] initToBytes(){
+ byte[] dataInByte = new byte[36];
+ int i[] = new int[1];
+ i[0] = 0;
+ if (this.msgID == (short)MessageID.MSG_ID_INIT.ordinal()){
+ intoByteArray(dataInByte, HEADER ,i);
+ intoByteArray(dataInByte, msgID ,i);
+ intoByteArray(dataInByte, length ,i);
+ intoByteArray(dataInByte, cksum ,i);
+
+ intoByteArray(dataInByte, valID ,i);
+ intoByteArray(dataInByte, devID ,i);
+
+ intoByteArray(dataInByte, wrdS ,i);
+ intoByteArray(dataInByte, wrdN ,i);
+ intoByteArray(dataInByte, stS ,i);
+ intoByteArray(dataInByte, stN ,i);
+ intoByteArray(dataInByte, prS ,i);
+ intoByteArray(dataInByte, prN ,i);
+
+ }
+ return dataInByte;
+ }
+
+ public byte[] evtToBytes(){
+ byte[] dataInByte = new byte[28];
+ int i[] = new int[1];
+ i[0] = 0;
+ if (this.msgID == (short)MessageID.MSG_ID_EVENT.ordinal()){
+ intoByteArray(dataInByte, HEADER ,i);
+ intoByteArray(dataInByte, msgID ,i);
+ intoByteArray(dataInByte, length ,i);
+ intoByteArray(dataInByte, cksum ,i);
+
+ intoByteArray(dataInByte, devID ,i);
+ intoByteArray(dataInByte, evtID ,i);
+
+ intoByteArray(dataInByte, wrdS ,i);
+ intoByteArray(dataInByte, wrdN ,i);
+ intoByteArray(dataInByte, toS ,i);
+ intoByteArray(dataInByte, toN ,i);
+ }
+ return dataInByte;
+ }
+
+ public byte[] syncToBytes(){
+ byte[] dataInByte = new byte[28];
+ int i[] = new int[1];
+ i[0] = 0;
+ if (this.msgID == (short)MessageID.MSG_ID_SYNC.ordinal()){
+ intoByteArray(dataInByte, HEADER ,i);
+ intoByteArray(dataInByte, msgID ,i);
+ intoByteArray(dataInByte, length ,i);
+ intoByteArray(dataInByte, cksum ,i);
+
+ intoByteArray(dataInByte, msgSeq ,i);
+ intoByteArray(dataInByte, rcS ,i);
+ intoByteArray(dataInByte, rcN ,i);
+
+ }
+ return dataInByte;
+ }
+
+ private void intoByteArray(byte[] bytes, short st, int[] index){
+ for(int i=0; i<2; i++, index[0]++){
+ bytes[index[0]]=byteNo(st,i+1);
+ }
+ }
+ private void intoByteArray(byte[] bytes, int it, int[] index){
+ for(int i =0; i<4; i++, index[0]++){
+ bytes[index[0]]=byteNo(it,i+1);
+ }
+ }
+
+ //Original
+ /*private byte byteNo(Short st, int i){
+ return (byte)(st>>(8*(2-i))&0xFF);
+ }
+ private byte byteNo(Integer in, int i){
+ return (byte)(in>>(8*(4-i))&0xFF);
+ }*/
+
+ private byte byteNo(Short st, int i){
+ return (byte)(st>>(8*(i-1))&0xFF);
+ }
+ private byte byteNo(Integer in, int i){
+ return (byte)(in>>(8*(i-1))&0xFF);
+ }
+
+
+ // Time Stamp Related
+ public String timeStamp(int seconds, int nanosec){
+
+ long currentTimeM = (long)(((long)(seconds)*(long)(1000))+((long)(nanosec)/(long)(1000000)));
+ if (((int)((nanosec-((int)(nanosec/1000000000))*1000000000)/10))<0){
+ int i=0;
+ int temp = (int)(nanosec/1000000000);
+ Util.debug("[S#7]"+Long.toString(nanosec));
+ Util.debug("[S#7]"+Integer.toString(temp));
+ temp = ((int)(nanosec/1000000000))*1000000000;
+ Util.debug("[S#7]"+Integer.toString(temp));
+ temp = (nanosec-((int)(nanosec/1000000000))*1000000000)/10;
+ Util.debug("[S#7]"+Integer.toString(temp));
+ i++;
+ }
+ return ""
+ + new SimpleDateFormat("yyyy-MM-dd", Locale.US).
+ format(new Date(currentTimeM)).toString()
+ + "T"
+ + new SimpleDateFormat("HH:mm:ss", Locale.US).
+ format(new Date(currentTimeM)).toString()
+ + "." + Integer.toString((int)((nanosec-((int)(nanosec/1000000000))*1000000000)/10))
+ + "Z";
+ }
+
+ public String timeStamp(){
+ int seconds = wrdS;
+ int nanosec = wrdN;
+ long currentTimeM = (long)(((long)(seconds)*(long)(1000))+((long)(nanosec)/(long)(1000000)));
+ String decimal = Integer.toString((int)((nanosec-(int)((long)(nanosec/1000000000))*1000000000)/10));
+ while(decimal.length()<8){
+ decimal = "0" + decimal;
+ }
+ return ""
+ + new SimpleDateFormat("yyyy-MM-dd", Locale.US).
+ format(new Date(currentTimeM)).toString()
+ + "T"
+ + new SimpleDateFormat("HH:mm:ss", Locale.US).
+ format(new Date(currentTimeM)).toString()
+ + "." + decimal
+ + "Z";
+ }
+
+ public String timeDisplay(){
+ int seconds = wrdS;
+ int nanosec = wrdN;
+ long currentTimeM = (long)(((long)(seconds)*(long)(1000))+((long)(nanosec)/(long)(1000000)));
+ String decimal = Integer.toString((int)((nanosec-(int)((long)(nanosec/1000000000))*1000000000)/10));
+ while(decimal.length()<8){
+ decimal = "0" + decimal;
+ }
+ return ""
+ + new SimpleDateFormat("MM-dd", Locale.US).
+ format(new Date(currentTimeM)).toString()
+ + "^"
+ + new SimpleDateFormat("HH:mm:ss", Locale.US).
+ format(new Date(currentTimeM)).toString()
+ + "." + decimal
+ + "Z";
+ }
+}
--- /dev/null
+package com.example.sycapp;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.util.Vector;
+
+import android.content.Context;
+
+public class SerialIO{
+ private OutputStream sout;
+ private InputStream sin;
+
+
+ private Vector<SerialData> parsedData;
+ // Serial Data
+ private final short HEADER = SerialData.HEADER;
+ private final byte HEADER_FST = (byte)(HEADER>>8&0xFF);
+ private final byte HEADER_SCD = (byte)(HEADER&0xFF);
+ private final int int16Cnt = SerialData.evt_int16Cnt;
+ private final int int32Cnt = SerialData.evt_int32Cnt;
+
+
+ // Serial Buffer
+ private int int16Idx;
+ private int int32Idx;
+ private byte[] buffer = new byte[4];
+ private int int16_;
+ private int int32_;
+ private int parseStatus = 0;
+ private short int16Buffer[] = new short[int16Cnt];
+ private int int32Buffer[] = new int [int32Cnt];
+ private int portId;
+
+
+ // Constructors
+ SerialIO(String portName, int portId){
+ try {
+ this.sout = new BufferedOutputStream(new FileOutputStream(new File(portName)));
+ this.sin = new FileInputStream(new File(portName));
+ this.parsedData = new Vector<SerialData>();
+ this.portId = portId;
+ } catch (Exception e) {
+ Util.debug("[S#0]"+e.toString());
+ }
+ }
+
+ SerialIO(FileOutputStream fo){
+ try {
+ this.sout = new BufferedOutputStream(new FileOutputStream(new File("/dev/ttyO1")));
+ this.sin = new FileInputStream(new File("/dev/ttyO1"));
+ this.parsedData = new Vector<SerialData>();
+ } catch (Exception e) {
+ Util.debug("[S#0]"+e.toString());
+ }
+ }
+
+ // Write & Read Routines
+ public void send(byte[] content){
+ try{
+ sout.write(content);
+ sout.flush();
+ }catch(Exception e){
+ Util.debug("[S#5]"+e.toString());
+ }
+ }
+ public void send(String content){
+ try{
+ sout.write(content.getBytes());
+ sout.flush();
+ }catch(Exception e){
+ Util.debug("[S#4]"+e.toString());
+ }
+ }
+
+ public Vector<SerialData> checkPort(){
+ parsedData.clear();
+ try {
+ if( sin.available()>0){
+ onDataReceived();
+ }
+ } catch (Exception e) {
+ Util.debug("[S#2]" +e.toString());
+ }
+ return parsedData;
+ }
+
+
+ private void onDataReceived(){
+ //Util.debug("[Serial] OnDataReceived!");
+ SerialData sData = new SerialData();
+ try {
+ byte buffer[] = new byte[sin.available()];
+ sin.read(buffer,0, sin.available());
+ parseByteFlow(buffer);
+ }
+ catch (Exception e){Util.debug("[S#1]"+e.toString());}
+ }
+
+
+ // TODO: need to be changed back
+ public void parseByteFlow(byte[] byteFlow){
+ for (int i=0; i<byteFlow.length; ){
+ switch(parseStatus){
+ case 0: // looking for 1st part of HEADER
+ //if (byteFlow[i++]==HEADER_FST){ parseStatus = 1;}
+ if (byteFlow[i++]==HEADER_SCD){ parseStatus = 1;}
+ break;
+ case 1: // looking for 2nd half of HEADER
+ //if (byteFlow[i++]!=HEADER_SCD){
+ if (byteFlow[i++]!=HEADER_FST){
+ parseStatus = 0;
+ }else {
+ parseStatus = 2;
+ int16Idx=0; int32Idx=0;
+ }
+ break;
+ case 2: // packing int16
+ buffer[int16_++]=byteFlow[i++];
+ if (int16_==2){
+ int16_ = 0;
+ int16Buffer[int16Idx++] = ByteBuffer.wrap(flipInt16(buffer)).getShort();
+ if(int16Idx==int16Cnt){
+ int16Idx = 0;
+ parseStatus = 3;
+ }
+ }
+ break;
+ case 3: // packing int32
+ buffer[int32_++]=byteFlow[i++];
+ if (int32_==4){
+ int32_ = 0;
+ int32Buffer[int32Idx++] = ByteBuffer.wrap(flipInt32(buffer)).getInt();
+ if(int32Idx==int32Cnt){
+ int32Idx = 0;
+ parseStatus = 0;
+ if (isValidData(int16Buffer, int32Buffer)){
+ parsedData.add(new SerialData(int16Buffer, int32Buffer, this.portId));
+ }
+ int j=0;
+ }
+ }
+ break;
+ }
+
+ }
+ //return logEnable? parsedData:null;
+ }
+
+ private byte[] flipInt16(byte[] buff){
+ byte temp = buff[0];
+ buff[0] = buff[1];
+ buff[1] = temp;
+ return buff;
+ }
+
+ private byte[] flipInt32(byte[] buff){
+ byte temp = buff[0];
+ buff[0] = buff[3];
+ buff[3] = temp;
+
+ temp = buff[1];
+ buff[1] = buff[2];
+ buff[2] = temp;
+ return buff;
+ }
+
+ private boolean isValidData(short[] int16, int[] int32){
+ return true;
+ }
+
+ private byte[] combineBytes(byte[] b1, byte[] b2){
+ byte[] result = new byte[b1.length+b2.length];
+ System.arraycopy(b1, 0, result, 0, b1.length);
+ System.arraycopy(b2, 0, result, b1.length, b2.length);
+ return result;
+ }
+
+
+}
--- /dev/null
+/*
+ * Copyright 2009 Cedric Priscal
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.sycapp;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import android.util.Log;
+
+public class SerialPort {
+
+ private static final String TAG = "SerialPort";
+
+ /*
+ * Do not remove or rename the field mFd: it is used by native method close();
+ */
+ private FileDescriptor mFd;
+ private FileInputStream mFileInputStream;
+ private FileOutputStream mFileOutputStream;
+
+ public SerialPort(File device, int baudrate, int flags) throws SecurityException, IOException {
+
+ /* Check access permission */
+ if (!device.canRead() || !device.canWrite()) {
+ try {
+ /* Missing read/write permission, trying to chmod the file */
+ Process su;
+ su = Runtime.getRuntime().exec("/system/bin/su");
+ String cmd = "chmod 666 " + device.getAbsolutePath() + "\n"
+ + "exit\n";
+ su.getOutputStream().write(cmd.getBytes());
+ if ((su.waitFor() != 0) || !device.canRead()
+ || !device.canWrite()) {
+ throw new SecurityException();
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new SecurityException();
+ }
+ }
+
+ mFd = open(device.getAbsolutePath(), baudrate, flags);
+ if (mFd == null) {
+ Log.e(TAG, "native open returns null");
+ throw new IOException();
+ }
+ mFileInputStream = new FileInputStream(mFd);
+ mFileOutputStream = new FileOutputStream(mFd);
+ }
+
+ // Getters and setters
+ public InputStream getInputStream() {
+ return mFileInputStream;
+ }
+
+ public OutputStream getOutputStream() {
+ return mFileOutputStream;
+ }
+
+ // JNI
+ private native static FileDescriptor open(String path, int baudrate, int flags);
+ public native void close();
+ static {
+ System.loadLibrary("serial_port");
+ }
+}
--- /dev/null
+package com.example.sycapp;
+
+import android.util.Log;
+
+public class Util
+{
+ /* Debugging */
+ public static void debug(String txt, Exception e)
+ {
+ Log.d("sycApp", txt, e);
+ }
+ public static void debug(String txt)
+ {
+ Log.d("sycApp", txt);
+ }
+}
--- /dev/null
+package com.example.sycapp;
+
+
+import java.io.InputStream;
+import java.util.Vector;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpPut;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import android.os.AsyncTask;
+
+public class XivelyUL { // Xively Uploader
+
+ //need to check things
+ private static final String url = "http://api.xively.com/v2/feeds/";
+ private static final String FEEDID = "2132088837";
+ private String feedID = "2132088837";
+ private static final String APIKEY = "gj9NLNCwZdUh7eI5ocDJJVgqFT3yT8MkhdFZpw8y8T0YFKGi";
+ private String apiKey = "gj9NLNCwZdUh7eI5ocDJJVgqFT3yT8MkhdFZpw8y8T0YFKGi";
+ private static String dataStream1 = "mbed1";
+ private static String dataStream2 = "mbed2";
+ private final int CAPACITY_PER_RQST = 500;
+ private int numInBuffer = 0;
+ private int value1 = 0;
+ private int value2 = 0;
+ private int ls_vl1 = 0; // for the current value thing
+ private int ls_vl2 = 0;
+ private boolean xvlEnable = true;
+
+
+
+ private JSONObject xivelyData;
+ private JSONArray mbed1Data;
+ private JSONArray mbed2Data;
+ private DefaultHttpClient xivelyRequester;
+ //private HttpPost xivelyPost;
+ private HttpPut xivelyUpload;
+ private HttpPost xivelyChannel;
+
+
+ XivelyUL(){
+ mbed1Data = new JSONArray();
+ mbed2Data = new JSONArray();
+ xivelyData = new JSONObject();
+ xivelyRequester= new DefaultHttpClient();
+
+ //createChannel(dataStream1);
+ //createChannel(dataStream2);
+ }
+
+
+ /*public void XvlUlTest(){
+
+ String data = "{\"version\":\"1.0.0\",\"datastreams\" : [ {"
+ +"\"id\" : \"mbed1\",\"datapoints\":["
+ +"{\"at\":\"2013-04-22T00:35:43Z\",\"value\":\"42\"},"
+ +"{\"at\":\"2013-04-22T00:55:43Z\",\"value\":\"84\"},"
+ +"{\"at\":\"2013-04-22T01:15:43Z\",\"value\":\"41\"},"
+ +"{\"at\":\"2013-04-22T01:35:43Z\",\"value\":\"83\"}],"
+ +"\"current_value\" : \"40\"}]}";
+ try {
+ StringEntity se = new StringEntity(data);
+ xivelyUpload.setEntity(se);
+ xivelyUpload.setHeader("Accept","application/json");
+ xivelyUpload.addHeader("X-ApiKey", apiKey);
+ ResponseHandler responseHandler = new BasicResponseHandler();
+ //xivelyRequester.execute(xivelyUpload, responseHandler);
+ new xivelyHelper().execute();
+ } catch (Exception e){
+ Util.debug("[X#2]"+e.toString());
+ }
+ }*/
+
+ public void setFeedID(String newID){
+ feedID = newID;
+ }
+
+ public void setApiKey(String newKey){
+ apiKey = newKey;
+ }
+
+ public void resetFeedID(){
+ feedID = FEEDID;
+ }
+
+ public void resetApiKey(){
+ apiKey = APIKEY;
+ }
+
+
+ public void setEnable(boolean bool){
+ xvlEnable = bool;
+ }
+
+ // Pack Data
+ public void packSerialData(Vector<SerialData> sdata){
+ for(int i=0; i<sdata.size(); i++){
+ if(numInBuffer>=CAPACITY_PER_RQST) return;
+ packData(sdata.get(i));
+ numInBuffer++;
+ Util.debug("[Buffer#2]"+Integer.toString(numInBuffer));
+ }
+ }
+
+ private void packData(SerialData data){
+ try {
+ //TODO: deviceID stuff!!!
+ if(data.devID==1){
+ if (ls_vl1==-1){
+ ls_vl1=0;
+ }else{
+ JSONObject dataPoint = new JSONObject();
+ dataPoint.put("at", data.timeStamp());
+ dataPoint.put("value",flip(data.devID));
+ mbed1Data.put(dataPoint);
+ }
+ }else if(data.devID==2){
+ if (ls_vl2==-1){
+ ls_vl2=0;
+ }else{
+ JSONObject dataPoint = new JSONObject();
+ dataPoint.put("value",flip(data.devID));
+ dataPoint.put("at", data.timeStamp());
+ mbed2Data.put(dataPoint);
+ }
+ }
+ }catch (JSONException e) {
+ Util.debug("[X#0]"+e.toString());
+ }
+ }
+
+
+
+ public void createChannel(String newChannel){
+ new XivelyChannel().execute(url, newChannel);
+ }
+
+
+
+ // Data Upload
+ public void uploadData(){
+ if(numInBuffer>10){
+ packToStream();
+ new XivelyUpload().execute(url);
+ numInBuffer = 0;
+ Util.debug("[Buffer#1]"+Integer.toString(numInBuffer));
+ }
+ }
+
+
+ private void packToStream(){
+ //JSONObject dataFlow = new JSONObject();
+ JSONArray dataPoints= new JSONArray();
+ JSONObject eachPoints= new JSONObject();
+
+ try{
+ eachPoints.put("id", dataStream1);
+ //eachPoints.put("current_value",flip(1));
+ eachPoints.put("datapoints", mbed1Data);
+
+ dataPoints.put(eachPoints);
+ eachPoints = new JSONObject();
+
+ //dataPoints.put
+ eachPoints.put("id", dataStream2);
+ //eachPoints.put("current_value",flip(2));
+ eachPoints.put("datapoints", mbed2Data);
+
+ dataPoints.put(eachPoints);
+
+ xivelyData.put("datastreams", dataPoints);
+ xivelyData.put("version", "1.0.0");
+ Util.debug("[X#5]"+xivelyData.toString(1));
+ }
+ catch(Exception e){
+ Util.debug("[X#1]"+e.toString());
+ }
+
+ mbed1Data = new JSONArray(); // clear uploaded datapoints
+ mbed2Data = new JSONArray();
+ }
+
+
+ private int flip(int mbed){
+ if (mbed==1){
+ value1 = (value1==1)?0:1;
+ return value1;
+ }
+ if (mbed==2){
+ value2 = (value2==1)?0:1;
+ return value2;
+ }
+ return -1;
+ }
+
+ // Http Service Helper
+ private class XivelyUpload extends AsyncTask<String,Void,Void>{
+
+ @Override
+ protected Void doInBackground(String... url_) {
+ try{
+ String s = url_[0]+feedID+".json";
+ s = s+"";
+ xivelyUpload = new HttpPut(url_[0]+feedID+".json");
+ StringEntity se = new StringEntity(xivelyData.toString());
+ xivelyUpload.setEntity(se);
+ xivelyUpload.setHeader("Accept","application/json");
+ xivelyUpload.addHeader("X-ApiKey", apiKey);
+
+ HttpResponse response = xivelyRequester.execute(xivelyUpload);
+ InputStream inputStream = response.getEntity().getContent();
+ xivelyData = new JSONObject();
+
+ if(inputStream != null)
+ Util.debug("[X#3]"+inputStream.toString());
+ else
+ Util.debug("[X#3]Not working!!");
+ }catch (Exception e){
+ Util.debug("[X#4]"+e.toString());
+ }
+ return null;
+ }
+ }
+
+ private class XivelyChannel extends AsyncTask<String,Void,Void>{
+
+ @Override
+ protected Void doInBackground(String... params) {
+ try{
+ JSONObject channelFrame = new JSONObject();
+ JSONObject chanRqstBody = new JSONObject();
+ chanRqstBody.put("tags", "");
+ chanRqstBody.put("id", params[1]);
+ chanRqstBody.put("unit", new JSONObject().put("symbol", "").put("label", ""));
+ channelFrame.put("datastreams",new JSONArray().put(chanRqstBody));
+
+ xivelyChannel = new HttpPost(params[0]+feedID+"/datastreams.json");
+ StringEntity se = new StringEntity(channelFrame.toString());
+ xivelyChannel.setEntity(se);
+ xivelyChannel.setHeader("Accept","application/json");
+ xivelyChannel.addHeader("X-ApiKey", apiKey);
+
+ HttpResponse response = xivelyRequester.execute(xivelyChannel);
+ InputStream inputStream = response.getEntity().getContent();
+
+ if(inputStream != null)
+ Util.debug("[X#3]"+inputStream.toString());
+ else
+ Util.debug("[X#3]Not working!!");
+ }catch (Exception e){
+ Util.debug("[X#4]"+e.toString());
+ }
+ return null;
+ }
+ }
+}
\ No newline at end of file