aboutsummaryrefslogtreecommitdiffstats
path: root/Software
diff options
context:
space:
mode:
authorRoy Ben-Shabat <Roy@Twine-s.com>2017-12-03 10:29:17 +0200
committerRoy Ben-Shabat <Roy@Twine-s.com>2017-12-03 10:29:17 +0200
commit05c7e42a8ce55a21c94338febad593bfbf638655 (patch)
tree5465475f3565da1b724f4cd9bfcc0eb3b67fd167 /Software
parent3a70d596ada24ad6f92f729d564ab29c3e249f06 (diff)
downloadTango-05c7e42a8ce55a21c94338febad593bfbf638655.tar.gz
Tango-05c7e42a8ce55a21c94338febad593bfbf638655.zip
MERGE
Diffstat (limited to 'Software')
-rw-r--r--Software/Android_Studio/Tango.DAL/build.gradle13
-rw-r--r--Software/Android_Studio/Tango.DAL/src/main/java/com/twine/tango/dal/MyOpenHelper.java28
-rw-r--r--Software/Android_Studio/Tango.DAL/src/main/java/com/twine/tango/dal/TangoDB.java73
-rw-r--r--Software/Android_Studio/Tango.DAL/src/main/java/com/twine/tango/dal/dao/OrganizationsDAO.java18
-rw-r--r--Software/Android_Studio/Tango.DAL/src/main/res/raw/tangodbbin0 -> 516096 bytes
-rw-r--r--Software/Android_Studio/Tango.Integration/src/main/java/com/twine/tango/integration/IMachineIdentityProvider.java10
-rw-r--r--Software/Android_Studio/Tango.Integration/src/main/java/com/twine/tango/integration/MachineIdentityProvider.java14
-rw-r--r--Software/Android_Studio/Tango.Integration/src/main/java/com/twine/tango/integration/adapters/SerialAdapter.java20
-rw-r--r--Software/Android_Studio/Tango.Integration/src/main/java/com/twine/tango/integration/adapters/TcpAdapter.java92
-rw-r--r--Software/Android_Studio/Tango.Integration/src/main/java/com/twine/tango/integration/machine/MachineOperator.java244
-rw-r--r--Software/Android_Studio/Tango.Integration/src/main/java/com/twine/tango/integration/machine/MachineOperatorInterface.java19
-rw-r--r--Software/Android_Studio/Tango.Integration/src/main/java/com/twine/tango/integration/machine/MessageBase.java24
-rw-r--r--Software/Android_Studio/Tango.Integration/src/main/java/com/twine/tango/integration/machine/RequestMessage.java59
-rw-r--r--Software/Android_Studio/Tango.Integration/src/main/java/com/twine/tango/integration/machine/ResponseMessage.java37
-rw-r--r--Software/Android_Studio/Tango.PMR/src/main/java/com/twine/tango/pmr/synchronization/SynchronizeDBRequestOuterClass.java646
-rw-r--r--Software/Android_Studio/Tango.PMR/src/main/java/com/twine/tango/pmr/synchronization/SynchronizeDBResponseOuterClass.java508
-rw-r--r--Software/Android_Studio/Tango.PMR/src/main/res/raw/packages.txt1
-rw-r--r--Software/Android_Studio/Tango.SharedUI/build.gradle9
-rw-r--r--Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/AppInitializer.java58
-rw-r--r--Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/App.java32
-rw-r--r--Software/Android_Studio/Tango.Synchronization/.gitignore1
-rw-r--r--Software/Android_Studio/Tango.Synchronization/build.gradle49
-rw-r--r--Software/Android_Studio/Tango.Synchronization/proguard-rules.pro25
-rw-r--r--Software/Android_Studio/Tango.Synchronization/src/androidTest/java/com/twine/tango/synchronization/ExampleInstrumentedTest.java32
-rw-r--r--Software/Android_Studio/Tango.Synchronization/src/main/AndroidManifest.xml2
-rw-r--r--Software/Android_Studio/Tango.Synchronization/src/main/java/com/twine/tango/synchronization/ITangoSynchronizer.java12
-rw-r--r--Software/Android_Studio/Tango.Synchronization/src/main/java/com/twine/tango/synchronization/TangoSynchronizer.java65
-rw-r--r--Software/Android_Studio/Tango.Synchronization/src/main/res/values/strings.xml3
-rw-r--r--Software/Android_Studio/Tango.Synchronization/src/test/java/com/twine/tango/synchronization/ExampleUnitTest.java19
-rw-r--r--Software/Android_Studio/Tango.UnitTesting/.gitignore1
-rw-r--r--Software/Android_Studio/Tango.UnitTesting/build.gradle48
-rw-r--r--Software/Android_Studio/Tango.UnitTesting/proguard-rules.pro25
-rw-r--r--Software/Android_Studio/Tango.UnitTesting/src/androidTest/java/com/twine/tango/unittesting/Synchronization_TST.java71
-rw-r--r--Software/Android_Studio/Tango.UnitTesting/src/main/AndroidManifest.xml24
-rw-r--r--Software/Android_Studio/Tango.UnitTesting/src/main/java/com/twine/tango/unittesting/App.java20
-rw-r--r--Software/Android_Studio/Tango.UnitTesting/src/main/java/com/twine/tango/unittesting/MainActivity.java15
-rw-r--r--Software/Android_Studio/Tango.UnitTesting/src/main/res/drawable/ic_launcher_background.xml113
-rw-r--r--Software/Android_Studio/Tango.UnitTesting/src/main/res/layout/activity_main.xml18
-rw-r--r--Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-anydpi-v26/ic_launcher.xml5
-rw-r--r--Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml5
-rw-r--r--Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-hdpi/ic_launcher.pngbin0 -> 3358 bytes
-rw-r--r--Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-hdpi/ic_launcher_foreground.pngbin0 -> 5117 bytes
-rw-r--r--Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-hdpi/ic_launcher_round.pngbin0 -> 5084 bytes
-rw-r--r--Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-mdpi/ic_launcher.pngbin0 -> 2386 bytes
-rw-r--r--Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-mdpi/ic_launcher_foreground.pngbin0 -> 2652 bytes
-rw-r--r--Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-mdpi/ic_launcher_round.pngbin0 -> 3179 bytes
-rw-r--r--Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-xhdpi/ic_launcher.pngbin0 -> 4648 bytes
-rw-r--r--Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-xhdpi/ic_launcher_foreground.pngbin0 -> 7011 bytes
-rw-r--r--Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-xhdpi/ic_launcher_round.pngbin0 -> 7381 bytes
-rw-r--r--Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-xxhdpi/ic_launcher.pngbin0 -> 7008 bytes
-rw-r--r--Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.pngbin0 -> 14578 bytes
-rw-r--r--Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-xxhdpi/ic_launcher_round.pngbin0 -> 11545 bytes
-rw-r--r--Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-xxxhdpi/ic_launcher.pngbin0 -> 9442 bytes
-rw-r--r--Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.pngbin0 -> 21908 bytes
-rw-r--r--Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-xxxhdpi/ic_launcher_round.pngbin0 -> 16109 bytes
-rw-r--r--Software/Android_Studio/Tango.UnitTesting/src/main/res/values/colors.xml6
-rw-r--r--Software/Android_Studio/Tango.UnitTesting/src/main/res/values/strings.xml3
-rw-r--r--Software/Android_Studio/Tango.UnitTesting/src/main/res/values/styles.xml11
-rw-r--r--Software/Android_Studio/Tango.UnitTesting/src/test/java/com/twine/tango/unittesting/ExampleUnitTest.java19
-rw-r--r--Software/Android_Studio/Tango.UnitTests/build/intermediates/incremental/compileDebugAidl/dependency.storebin0 -> 5 bytes
-rw-r--r--Software/Android_Studio/Tango.Web/.gitignore1
-rw-r--r--Software/Android_Studio/Tango.Web/build.gradle43
-rw-r--r--Software/Android_Studio/Tango.Web/proguard-rules.pro25
-rw-r--r--Software/Android_Studio/Tango.Web/src/androidTest/java/com/twine/tango/web/ExampleInstrumentedTest.java31
-rw-r--r--Software/Android_Studio/Tango.Web/src/main/AndroidManifest.xml6
-rw-r--r--Software/Android_Studio/Tango.Web/src/main/java/com/twine/tango/web/APIFactory.java39
-rw-r--r--Software/Android_Studio/Tango.Web/src/main/java/com/twine/tango/web/ISynchronizationAPI.java20
-rw-r--r--Software/Android_Studio/Tango.Web/src/main/res/values/strings.xml3
-rw-r--r--Software/Android_Studio/Tango.Web/src/test/java/com/twine/tango/web/ExampleUnitTest.java19
-rw-r--r--Software/Android_Studio/build.gradle5
-rw-r--r--Software/Android_Studio/settings.gradle2
-rw-r--r--Software/DB/Tango.mdfbin8388608 -> 8388608 bytes
-rw-r--r--Software/DB/Tango_log.ldfbin8388608 -> 8388608 bytes
-rw-r--r--Software/PMR/Messages/Synchronization/SynchronizeDBRequest.proto10
-rw-r--r--Software/PMR/Messages/Synchronization/SynchronizeDBResponse.proto9
-rw-r--r--Software/Visual_Studio/Installers/Keyoti.Conveyor.vsixbin0 -> 838452 bytes
-rw-r--r--Software/Visual_Studio/Tango.Core/Helpers/PathHelper.cs4
-rw-r--r--Software/Visual_Studio/Tango.PMR/Synchronization/SynchronizeDBRequest.cs188
-rw-r--r--Software/Visual_Studio/Tango.PMR/Synchronization/SynchronizeDBResponse.cs160
-rw-r--r--Software/Visual_Studio/Tango.PMR/Tango.PMR.csproj2
-rw-r--r--Software/Visual_Studio/Tango.Synchronization/Local/LocalDBSynchronizer.cs28
-rw-r--r--Software/Visual_Studio/Tango.Synchronization/Local/SqliteDataBase.cs19
-rw-r--r--Software/Visual_Studio/Tango.Synchronization/Remote/RemoteDBSynchronizer.cs41
-rw-r--r--Software/Visual_Studio/Tango.Synchronization/Tango.Synchronization.csproj2
-rw-r--r--Software/Visual_Studio/Tango.UnitTesting/Synchronization_TST.cs17
-rw-r--r--Software/Visual_Studio/Web/Tango.MachineService/App_Data/Tango.db (renamed from Software/Android_Studio/Tango.DAL/src/main/assets/Tango.db)bin516096 -> 516096 bytes
-rw-r--r--Software/Visual_Studio/Web/Tango.MachineService/App_Start/WebApiConfig.cs2
-rw-r--r--Software/Visual_Studio/Web/Tango.MachineService/Controllers/SynchronizationController.cs47
-rw-r--r--Software/Visual_Studio/Web/Tango.MachineService/Global.asax.cs23
-rw-r--r--Software/Visual_Studio/Web/Tango.MachineService/ProtoBufFormatter.cs72
-rw-r--r--Software/Visual_Studio/Web/Tango.MachineService/Tango.MachineService.csproj48
-rw-r--r--Software/Visual_Studio/Web/Tango.MachineService/Web.config79
-rw-r--r--Software/Visual_Studio/Web/Tango.MachineService/packages.config6
93 files changed, 2860 insertions, 588 deletions
diff --git a/Software/Android_Studio/Tango.DAL/build.gradle b/Software/Android_Studio/Tango.DAL/build.gradle
index c237ba6e4..efd90c7c5 100644
--- a/Software/Android_Studio/Tango.DAL/build.gradle
+++ b/Software/Android_Studio/Tango.DAL/build.gradle
@@ -21,13 +21,9 @@ android {
}
}
-
- sourceCompatibility = 1.7
- targetCompatibility = 1.7
-
compileOptions {
- sourceCompatibility JavaVersion.VERSION_1_7
- targetCompatibility JavaVersion.VERSION_1_7
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
}
}
@@ -53,12 +49,15 @@ dependencies {
compile globalDependencies.logging
compile globalDependencies.storage
+
+ compile group: 'commons-io', name: 'commons-io', version: '2.4'
}
//Copy data base to assets folder.
task copyFiles(type: Copy) {
from "$projectDir\\..\\..\\DB\\Tango.db"
- into "$projectDir/src\\main\\assets\\"
+ into "$projectDir/src\\main\\res\\raw"
+ rename ('Tango.db', 'tangodb')
}
preBuild.dependsOn(copyFiles) \ No newline at end of file
diff --git a/Software/Android_Studio/Tango.DAL/src/main/java/com/twine/tango/dal/MyOpenHelper.java b/Software/Android_Studio/Tango.DAL/src/main/java/com/twine/tango/dal/MyOpenHelper.java
new file mode 100644
index 000000000..1a73883d3
--- /dev/null
+++ b/Software/Android_Studio/Tango.DAL/src/main/java/com/twine/tango/dal/MyOpenHelper.java
@@ -0,0 +1,28 @@
+package com.twine.tango.dal;
+
+import android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+
+/**
+ * Created by Roy on 12/3/2017.
+ */
+
+public class MyOpenHelper extends SQLiteOpenHelper
+{
+ MyOpenHelper(Context context,String database_path) {
+ super(context, database_path, null, 1);
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase sqLiteDatabase)
+ {
+
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1)
+ {
+
+ }
+}
diff --git a/Software/Android_Studio/Tango.DAL/src/main/java/com/twine/tango/dal/TangoDB.java b/Software/Android_Studio/Tango.DAL/src/main/java/com/twine/tango/dal/TangoDB.java
index d878e72b2..4f81cc74d 100644
--- a/Software/Android_Studio/Tango.DAL/src/main/java/com/twine/tango/dal/TangoDB.java
+++ b/Software/Android_Studio/Tango.DAL/src/main/java/com/twine/tango/dal/TangoDB.java
@@ -1,6 +1,6 @@
package com.twine.tango.dal;
-import android.content.Context;
+import android.content.res.Resources;
import android.os.Environment;
import com.elvishew.xlog.XLog;
@@ -17,7 +17,12 @@ import com.snatik.storage.Storage;
import com.twine.tango.core.ContextFactory;
import com.twine.tango.dal.entities.Organization;
+import org.apache.commons.io.IOUtils;
+
+import java.io.ByteArrayOutputStream;
import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
import java.util.List;
/**
@@ -29,23 +34,28 @@ public class TangoDB
{
private static DatabaseDefinition database;
private static String database_path;
+ private static String database_name;
public static void init()
{
+ database_name = "Tango.db";
+ database_path = Environment.getExternalStorageDirectory() + "/" + database_name;
+
+ createIfNotFound();
+
FlowManager.init(FlowConfig.builder(ContextFactory.getApplicationContext())
.addDatabaseConfig(
DatabaseConfig.builder(
TangoDB.class)
- .databaseName("Tango")
+ .databaseName(database_name)
.build())
.build());
database = FlowManager.getDatabase(TangoDB.class);
- //Test
- List<Organization> results = SQLite.select().from(Organization.class).queryList();
+ List<Organization> orgs = SQLite.select().from(Organization.class).queryList();
- for (Organization org : results)
+ for (Organization org : orgs)
{
XLog.i(org.getName());
}
@@ -53,15 +63,20 @@ public class TangoDB
backup();
}
- public static File getDataBasePath(String name)
+ public static String getDataBasePath()
+ {
+ return database_path;
+ }
+
+ public static String getDataBasePath(String name)
{
- database_path = Environment.getExternalStorageDirectory() + "/" + name;
- return new File(database_path);
+ return Environment.getExternalStorageDirectory() + "/" + name;
}
public static void close()
{
database.close();
+ FlowManager.close();
}
public static void backup()
@@ -69,4 +84,46 @@ public class TangoDB
Storage storage = new Storage(ContextFactory.getApplicationContext());
storage.copy(database_path,storage.getExternalStorageDirectory() + "/" + "backup.db");
}
+
+ public static void replace(byte[] data)
+ {
+ close();
+ Storage storage = new Storage(ContextFactory.getApplicationContext());
+ storage.createFile(database_path,data);
+ init();
+ }
+
+ private static void createIfNotFound()
+ {
+ Storage storage = new Storage(ContextFactory.getApplicationContext());
+ if (!storage.isFileExist(database_path))
+ {
+ try
+ {
+ InputStream inputStream = ContextFactory.getApplicationContext().getResources().openRawResource(R.raw.tangodb);
+ boolean b = storage.createFile(database_path,IOUtils.toByteArray(inputStream));
+ if (b)
+ {
+ XLog.i("success");
+ }
+ inputStream.close();
+
+ } catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public static byte[] convertStreamToByteArray(InputStream is) throws IOException
+ {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ byte[] buff = new byte[10240];
+ int i = Integer.MAX_VALUE;
+ while ((i = is.read(buff, 0, buff.length)) > 0) {
+ baos.write(buff, 0, i);
+ }
+
+ return baos.toByteArray(); // be sure to close InputStream in calling function
+ }
}
diff --git a/Software/Android_Studio/Tango.DAL/src/main/java/com/twine/tango/dal/dao/OrganizationsDAO.java b/Software/Android_Studio/Tango.DAL/src/main/java/com/twine/tango/dal/dao/OrganizationsDAO.java
new file mode 100644
index 000000000..2fb669bbb
--- /dev/null
+++ b/Software/Android_Studio/Tango.DAL/src/main/java/com/twine/tango/dal/dao/OrganizationsDAO.java
@@ -0,0 +1,18 @@
+package com.twine.tango.dal.dao;
+
+import com.raizlabs.android.dbflow.sql.language.SQLite;
+import com.twine.tango.dal.entities.Organization;
+
+import java.util.List;
+
+/**
+ * Created by Roy on 12/2/2017.
+ */
+
+public class OrganizationsDAO
+{
+ public static List<Organization> getAllOrganizations()
+ {
+ return SQLite.select().from(Organization.class).queryList();
+ }
+}
diff --git a/Software/Android_Studio/Tango.DAL/src/main/res/raw/tangodb b/Software/Android_Studio/Tango.DAL/src/main/res/raw/tangodb
new file mode 100644
index 000000000..f162394c0
--- /dev/null
+++ b/Software/Android_Studio/Tango.DAL/src/main/res/raw/tangodb
Binary files differ
diff --git a/Software/Android_Studio/Tango.Integration/src/main/java/com/twine/tango/integration/IMachineIdentityProvider.java b/Software/Android_Studio/Tango.Integration/src/main/java/com/twine/tango/integration/IMachineIdentityProvider.java
new file mode 100644
index 000000000..e4b033eb6
--- /dev/null
+++ b/Software/Android_Studio/Tango.Integration/src/main/java/com/twine/tango/integration/IMachineIdentityProvider.java
@@ -0,0 +1,10 @@
+package com.twine.tango.integration;
+
+/**
+ * Created by Roy on 12/2/2017.
+ */
+
+public interface IMachineIdentityProvider
+{
+ String getSerialNumber();
+}
diff --git a/Software/Android_Studio/Tango.Integration/src/main/java/com/twine/tango/integration/MachineIdentityProvider.java b/Software/Android_Studio/Tango.Integration/src/main/java/com/twine/tango/integration/MachineIdentityProvider.java
new file mode 100644
index 000000000..7490908c6
--- /dev/null
+++ b/Software/Android_Studio/Tango.Integration/src/main/java/com/twine/tango/integration/MachineIdentityProvider.java
@@ -0,0 +1,14 @@
+package com.twine.tango.integration;
+
+/**
+ * Created by Roy on 12/2/2017.
+ */
+
+public class MachineIdentityProvider implements IMachineIdentityProvider
+{
+ @Override
+ public String getSerialNumber()
+ {
+ return "1234";
+ }
+}
diff --git a/Software/Android_Studio/Tango.Integration/src/main/java/com/twine/tango/integration/adapters/SerialAdapter.java b/Software/Android_Studio/Tango.Integration/src/main/java/com/twine/tango/integration/adapters/SerialAdapter.java
deleted file mode 100644
index 5224a0729..000000000
--- a/Software/Android_Studio/Tango.Integration/src/main/java/com/twine/tango/integration/adapters/SerialAdapter.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package com.twine.tango.integration.adapters;
-
-import java.io.IOException;
-
-import io.reactivex.Observable;
-
-/**
- * Created by Roy on 11/8/2017.
- */
-
-public interface SerialAdapter {
-
- void setAddress(String address);
- String getAddress();
- void open() throws IOException;
- void close() throws IOException;
- void write(byte[] data) throws IOException;
- Observable<byte[]> registerReceiveListener();
- boolean getIsOpen();
-}
diff --git a/Software/Android_Studio/Tango.Integration/src/main/java/com/twine/tango/integration/adapters/TcpAdapter.java b/Software/Android_Studio/Tango.Integration/src/main/java/com/twine/tango/integration/adapters/TcpAdapter.java
deleted file mode 100644
index 3858b2c5f..000000000
--- a/Software/Android_Studio/Tango.Integration/src/main/java/com/twine/tango/integration/adapters/TcpAdapter.java
+++ /dev/null
@@ -1,92 +0,0 @@
-package com.twine.tango.integration.adapters;
-
-import android.os.SystemClock;
-import com.elvishew.xlog.XLog;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.Socket;
-import io.reactivex.Observable;
-import io.reactivex.schedulers.Schedulers;
-import io.reactivex.subjects.PublishSubject;
-
-/**
- * Created by Roy on 11/8/2017.
- */
-
-public class TcpAdapter implements SerialAdapter {
-
- private Socket socket;
- private String address;
- private boolean isOpen;
- private static final int port = 9999;
- private Thread receiveThread;
- private PublishSubject<byte[]> subject;
-
- public TcpAdapter(String address) {
- this.address = address;
- }
-
- @Override
- public void setAddress(String address) {
- this.address = address;
- }
-
- @Override
- public String getAddress() {
- return this.address;
- }
-
- @Override
- public void open() throws IOException {
- socket = new Socket(address, port);
- isOpen = true;
- receiveThread = new Thread(this::receiveThreadMethod);
- receiveThread.start();
- }
-
- @Override
- public void close() throws IOException {
- socket.close();
- isOpen = false;
- }
-
- @Override
- public void write(byte[] data) throws IOException {
- socket.getOutputStream().write(data);
- }
-
- @Override
- public Observable<byte[]> registerReceiveListener() {
- subject = PublishSubject.create();
- return subject.observeOn(Schedulers.io());
- }
-
- @Override
- public boolean getIsOpen() {
- return isOpen;
- }
-
- private void receiveThreadMethod() {
- while (isOpen) {
-
- try {
-
- InputStream stream = socket.getInputStream();
-
- if (stream.available() > 0)
- {
- byte[] data = new byte[stream.available()];
- int read = stream.read(data);
- if (subject != null && read > 0) subject.onNext(data);
- }
-
- } catch (Exception e) {
- isOpen = false;
- XLog.e(e);
- if (subject != null) subject.onError(e);
- }
-
- SystemClock.sleep(10);
- }
- }
-}
diff --git a/Software/Android_Studio/Tango.Integration/src/main/java/com/twine/tango/integration/machine/MachineOperator.java b/Software/Android_Studio/Tango.Integration/src/main/java/com/twine/tango/integration/machine/MachineOperator.java
deleted file mode 100644
index 33a7d40ff..000000000
--- a/Software/Android_Studio/Tango.Integration/src/main/java/com/twine/tango/integration/machine/MachineOperator.java
+++ /dev/null
@@ -1,244 +0,0 @@
-package com.twine.tango.integration.machine;
-
-import android.os.SystemClock;
-import com.elvishew.xlog.XLog;
-import com.google.protobuf.GeneratedMessageV3;
-import com.google.protobuf.InvalidProtocolBufferException;
-import com.twine.tango.integration.adapters.SerialAdapter;
-import com.twine.tango.pmr.MessageFactory;
-import com.twine.tango.pmr.TangoMessage;
-import com.twine.tango.pmr.common.MessageContainerOuterClass.MessageContainer;
-import java.io.IOException;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.List;
-import java.util.Locale;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentLinkedQueue;
-
-import javax.inject.Inject;
-
-import io.reactivex.Observable;
-import io.reactivex.Scheduler;
-import io.reactivex.android.schedulers.AndroidSchedulers;
-import io.reactivex.schedulers.Schedulers;
-import io.reactivex.subjects.PublishSubject;
-
-/**
- * Created by Roy on 11/8/2017.
- */
-
-public class MachineOperator implements MachineOperatorInterface {
-
- private SerialAdapter channel;
- private Calendar calendar;
- private DateFormat dateFormatter;
- private ConcurrentLinkedQueue<RequestMessage> requestsQueue;
- private List<RequestMessage> pendingRequests;
- private ConcurrentLinkedQueue<ResponseMessage> responsesQueue;
- private PublishSubject<byte[]> receiveDataSubject;
- private Thread pushThread;
- private Thread pullThread;
- private boolean isConnected;
- private Scheduler ioScheduler;
- private Scheduler uiScheduler;
-
- @Inject
- public MachineOperator(SerialAdapter channel) {
-
- ioScheduler = Schedulers.io();
- uiScheduler = AndroidSchedulers.mainThread();
- calendar = Calendar.getInstance();
- dateFormatter = new SimpleDateFormat("HH:mm:ss.SSS", Locale.US);
- requestsQueue = new ConcurrentLinkedQueue<>();
- pendingRequests = new ArrayList<>();
- responsesQueue = new ConcurrentLinkedQueue<>();
-
- setCommunicationChannel(channel);
-
- connect().subscribe();
- }
-
- private void setCommunicationChannel(SerialAdapter channel) {
- if (channel.getIsOpen()) {
- try {
- channel.close();
- } catch (IOException e) {
- XLog.e(e);
- }
- }
-
- boolean reconnect = false;
-
- if (isConnected) {
- reconnect = true;
- disconnect();
- }
-
- this.channel = channel;
- this.channel.registerReceiveListener().subscribe((data) ->
- {
-
- try {
- MessageContainer container = MessageContainer.parseFrom(data);
-
- RequestMessage pendingRequest = Observable.fromIterable(pendingRequests).filter(x -> x.getToken().equals(container.getToken())).blockingFirst(null);
-
- if (pendingRequest != null) {
- pendingRequests.remove(pendingRequest);
- responsesQueue.add(new ResponseMessage(pendingRequest.getSubject(), pendingRequest.getResponseClass(), data));
- } else {
- XLog.w("Could not find matching request for response: %s", container.getType().toString());
- }
- } catch (InvalidProtocolBufferException e) {
- XLog.e(e);
- }
-
- if (receiveDataSubject != null)
- {
- receiveDataSubject.onNext(data);
- }
-
- });
-
- if (reconnect) {
- connect();
- }
- }
-
- public <Request extends GeneratedMessageV3, Response extends GeneratedMessageV3> Observable<Response> send(TangoMessage<Request> message, Class<Response> className) {
-
- PublishSubject<Response> subject = PublishSubject.create();
- requestsQueue.add(new RequestMessage<>(subject, message, className, UUID.randomUUID().toString(), calendar.getTime()));
- return subject.subscribeOn(ioScheduler).observeOn(uiScheduler);
- }
-
-
- @Override
- public Observable connect() {
-
- return Observable.create((x) ->
- {
- try {
- channel.open();
- isConnected = true;
- startThreads();
- x.onComplete();
- } catch (Exception e) {
- XLog.e("Could not connect to Tango machine.", e);
- x.onError(e);
- }
-
- }).subscribeOn(ioScheduler).observeOn(uiScheduler);
-
- }
-
- @Override
- public Observable disconnect() {
-
- return Observable.create((x) ->
- {
- try {
- channel.close();
- isConnected = false;
- x.onComplete();
- stopThreads();
- } catch (Exception e) {
- XLog.e("Could not disconnect from Tango machine.", e);
- x.onError(e);
- }
-
- }).subscribeOn(ioScheduler).observeOn(uiScheduler);
-
- }
-
- private void startThreads() {
- pushThread = new Thread(this::pushThreadMethod, "Push Thread");
- pushThread.start();
-
- pullThread = new Thread(this::pullThreadMethod, "Pull Thread");
- pullThread.start();
- }
-
- private void stopThreads() {
- isConnected = false;
- pullThread.interrupt();
- pushThread.interrupt();
- }
-
- public void writeData(byte[] data)
- {
- try {
- channel.write(data);
- } catch (IOException e) {
- XLog.e(e);
- }
- }
-
- @Override
- public Observable<byte[]> receiveData() {
- receiveDataSubject = PublishSubject.create();
- return receiveDataSubject.observeOn(uiScheduler).subscribeOn(ioScheduler);
- }
-
- private void pushThreadMethod() {
-
- while (isConnected) {
-
- if (requestsQueue.size() > 0) {
- RequestMessage request = requestsQueue.poll();
- if (request != null) {
- pendingRequests.add(request);
- try {
- channel.write(request.getMessage().toBytes());
- } catch (IOException e) {
- isConnected = false;
- XLog.e(e);
- }
- }
- }
-
- SystemClock.sleep(10);
- }
- }
-
- private void pullThreadMethod() {
- while (isConnected) {
-
- if (responsesQueue.size() > 0) {
- ResponseMessage response = responsesQueue.poll();
- if (response != null) {
-
- try {
- TangoMessage message = MessageFactory.parseTangoMessage(response.getData());
- response.getSubject().onNext(message);
- response.getSubject().onComplete();
- } catch (Exception e) {
- response.getSubject().onError(e);
- XLog.e("Could not parse response.", e);
- }
-
- }
- }
-
- SystemClock.sleep(10);
- }
- }
-
- private void postRequest(RequestMessage request) {
-
-// SystemClock.sleep(5000);
-//
-// TangoMessage<Job> jobTangoMessage = MessageFactory.createTangoMessage(Job.class);
-//
-// jobTangoMessage.setMessage(Job.newBuilder().setName("Result Job").build());
-//
-// XLog.d("Posting result for request: %s TIME: %s", request.token, dateFormatter.format(request.dateTime));
-//
-// request.subject.onNext(jobTangoMessage.getMessage());
-//
-// request.subject.onComplete();
- }
-}
diff --git a/Software/Android_Studio/Tango.Integration/src/main/java/com/twine/tango/integration/machine/MachineOperatorInterface.java b/Software/Android_Studio/Tango.Integration/src/main/java/com/twine/tango/integration/machine/MachineOperatorInterface.java
deleted file mode 100644
index 39e7e31d7..000000000
--- a/Software/Android_Studio/Tango.Integration/src/main/java/com/twine/tango/integration/machine/MachineOperatorInterface.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.twine.tango.integration.machine;
-
-import com.google.protobuf.GeneratedMessageV3;
-import com.twine.tango.pmr.TangoMessage;
-
-import io.reactivex.Observable;
-
-/**
- * Created by Roy on 11/8/2017.
- */
-
-public interface MachineOperatorInterface {
-
- <Request extends GeneratedMessageV3, Response extends GeneratedMessageV3> Observable<Response> send(TangoMessage<Request> message,Class<Response> className);
- Observable connect();
- Observable disconnect();
- void writeData(byte[] data);
- Observable<byte[]> receiveData();
-}
diff --git a/Software/Android_Studio/Tango.Integration/src/main/java/com/twine/tango/integration/machine/MessageBase.java b/Software/Android_Studio/Tango.Integration/src/main/java/com/twine/tango/integration/machine/MessageBase.java
deleted file mode 100644
index c34e3653a..000000000
--- a/Software/Android_Studio/Tango.Integration/src/main/java/com/twine/tango/integration/machine/MessageBase.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.twine.tango.integration.machine;
-
-import io.reactivex.subjects.PublishSubject;
-
-/**
- * Created by Roy on 11/8/2017.
- */
-
-public class MessageBase {
-
- private PublishSubject subject;
-
- public PublishSubject getSubject() {
- return subject;
- }
-
- public void setSubject(PublishSubject subject) {
- this.subject = subject;
- }
-
- public MessageBase(PublishSubject subject) {
- this.subject = subject;
- }
-}
diff --git a/Software/Android_Studio/Tango.Integration/src/main/java/com/twine/tango/integration/machine/RequestMessage.java b/Software/Android_Studio/Tango.Integration/src/main/java/com/twine/tango/integration/machine/RequestMessage.java
deleted file mode 100644
index dde1ff765..000000000
--- a/Software/Android_Studio/Tango.Integration/src/main/java/com/twine/tango/integration/machine/RequestMessage.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package com.twine.tango.integration.machine;
-
-import com.google.protobuf.GeneratedMessageV3;
-import com.twine.tango.pmr.TangoMessage;
-
-import java.util.Date;
-
-import io.reactivex.subjects.PublishSubject;
-
-/**
- * Created by Roy on 11/8/2017.
- */
-public class RequestMessage<T extends GeneratedMessageV3,Response extends GeneratedMessageV3> extends MessageBase {
-
- private String token;
- private Date dateTime;
- private TangoMessage<T> message;
- private Class<Response> responseClass;
-
- public String getToken() {
- return token;
- }
-
- public void setToken(String token) {
- this.token = token;
- }
-
- public Date getDateTime() {
- return dateTime;
- }
-
- public void setDateTime(Date dateTime) {
- this.dateTime = dateTime;
- }
-
- public TangoMessage<T> getMessage() {
- return message;
- }
-
- public void setMessage(TangoMessage<T> message) {
- this.message = message;
- }
-
- public Class<Response> getResponseClass() {
- return responseClass;
- }
-
- public void setResponseClass(Class<Response> responseClass) {
- this.responseClass = responseClass;
- }
-
- public RequestMessage(PublishSubject subject, TangoMessage<T> message, Class<Response> responseClass, String token, Date time) {
- super(subject);
- this.message = message;
- this.token = token;
- this.dateTime = time;
- this.responseClass = responseClass;
- }
-}
diff --git a/Software/Android_Studio/Tango.Integration/src/main/java/com/twine/tango/integration/machine/ResponseMessage.java b/Software/Android_Studio/Tango.Integration/src/main/java/com/twine/tango/integration/machine/ResponseMessage.java
deleted file mode 100644
index 13de24286..000000000
--- a/Software/Android_Studio/Tango.Integration/src/main/java/com/twine/tango/integration/machine/ResponseMessage.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package com.twine.tango.integration.machine;
-
-import com.twine.tango.pmr.TangoMessage;
-
-import io.reactivex.subjects.PublishSubject;
-
-/**
- * Created by Roy on 11/8/2017.
- */
-
-public class ResponseMessage extends MessageBase {
-
- private byte[] data;
- private Class<?> responseClass;
-
- public byte[] getData() {
- return data;
- }
-
- public void setData(byte[] data) {
- this.data = data;
- }
-
- public Class<?> getResponseClass() {
- return responseClass;
- }
-
- public void setResponseClass(Class<?> responseClass) {
- this.responseClass = responseClass;
- }
-
- public ResponseMessage(PublishSubject subject, Class<?> responseClass, byte[] data) {
- super(subject);
- this.data = data;
- this.responseClass = responseClass;
- }
-}
diff --git a/Software/Android_Studio/Tango.PMR/src/main/java/com/twine/tango/pmr/synchronization/SynchronizeDBRequestOuterClass.java b/Software/Android_Studio/Tango.PMR/src/main/java/com/twine/tango/pmr/synchronization/SynchronizeDBRequestOuterClass.java
new file mode 100644
index 000000000..d9dfa19e4
--- /dev/null
+++ b/Software/Android_Studio/Tango.PMR/src/main/java/com/twine/tango/pmr/synchronization/SynchronizeDBRequestOuterClass.java
@@ -0,0 +1,646 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: SynchronizeDBRequest.proto
+
+package com.twine.tango.pmr.synchronization;
+
+public final class SynchronizeDBRequestOuterClass {
+ private SynchronizeDBRequestOuterClass() {}
+ public static void registerAllExtensions(
+ com.google.protobuf.ExtensionRegistryLite registry) {
+ }
+
+ public static void registerAllExtensions(
+ com.google.protobuf.ExtensionRegistry registry) {
+ registerAllExtensions(
+ (com.google.protobuf.ExtensionRegistryLite) registry);
+ }
+ public interface SynchronizeDBRequestOrBuilder extends
+ // @@protoc_insertion_point(interface_extends:Tango.PMR.Synchronization.SynchronizeDBRequest)
+ com.google.protobuf.MessageOrBuilder {
+
+ /**
+ * <code>string SerialNumber = 1;</code>
+ */
+ java.lang.String getSerialNumber();
+ /**
+ * <code>string SerialNumber = 1;</code>
+ */
+ com.google.protobuf.ByteString
+ getSerialNumberBytes();
+
+ /**
+ * <code>bytes LocalDB = 2;</code>
+ */
+ com.google.protobuf.ByteString getLocalDB();
+ }
+ /**
+ * Protobuf type {@code Tango.PMR.Synchronization.SynchronizeDBRequest}
+ */
+ public static final class SynchronizeDBRequest extends
+ com.google.protobuf.GeneratedMessageV3 implements
+ // @@protoc_insertion_point(message_implements:Tango.PMR.Synchronization.SynchronizeDBRequest)
+ SynchronizeDBRequestOrBuilder {
+ private static final long serialVersionUID = 0L;
+ // Use SynchronizeDBRequest.newBuilder() to construct.
+ private SynchronizeDBRequest(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+ super(builder);
+ }
+ private SynchronizeDBRequest() {
+ serialNumber_ = "";
+ localDB_ = com.google.protobuf.ByteString.EMPTY;
+ }
+
+ @java.lang.Override
+ public final com.google.protobuf.UnknownFieldSet
+ getUnknownFields() {
+ return this.unknownFields;
+ }
+ private SynchronizeDBRequest(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ this();
+ int mutable_bitField0_ = 0;
+ com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+ com.google.protobuf.UnknownFieldSet.newBuilder();
+ try {
+ boolean done = false;
+ while (!done) {
+ int tag = input.readTag();
+ switch (tag) {
+ case 0:
+ done = true;
+ break;
+ default: {
+ if (!parseUnknownFieldProto3(
+ input, unknownFields, extensionRegistry, tag)) {
+ done = true;
+ }
+ break;
+ }
+ case 10: {
+ java.lang.String s = input.readStringRequireUtf8();
+
+ serialNumber_ = s;
+ break;
+ }
+ case 18: {
+
+ localDB_ = input.readBytes();
+ break;
+ }
+ }
+ }
+ } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+ throw e.setUnfinishedMessage(this);
+ } catch (java.io.IOException e) {
+ throw new com.google.protobuf.InvalidProtocolBufferException(
+ e).setUnfinishedMessage(this);
+ } finally {
+ this.unknownFields = unknownFields.build();
+ makeExtensionsImmutable();
+ }
+ }
+ public static final com.google.protobuf.Descriptors.Descriptor
+ getDescriptor() {
+ return com.twine.tango.pmr.synchronization.SynchronizeDBRequestOuterClass.internal_static_Tango_PMR_Synchronization_SynchronizeDBRequest_descriptor;
+ }
+
+ protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+ internalGetFieldAccessorTable() {
+ return com.twine.tango.pmr.synchronization.SynchronizeDBRequestOuterClass.internal_static_Tango_PMR_Synchronization_SynchronizeDBRequest_fieldAccessorTable
+ .ensureFieldAccessorsInitialized(
+ com.twine.tango.pmr.synchronization.SynchronizeDBRequestOuterClass.SynchronizeDBRequest.class, com.twine.tango.pmr.synchronization.SynchronizeDBRequestOuterClass.SynchronizeDBRequest.Builder.class);
+ }
+
+ public static final int SERIALNUMBER_FIELD_NUMBER = 1;
+ private volatile java.lang.Object serialNumber_;
+ /**
+ * <code>string SerialNumber = 1;</code>
+ */
+ public java.lang.String getSerialNumber() {
+ java.lang.Object ref = serialNumber_;
+ if (ref instanceof java.lang.String) {
+ return (java.lang.String) ref;
+ } else {
+ com.google.protobuf.ByteString bs =
+ (com.google.protobuf.ByteString) ref;
+ java.lang.String s = bs.toStringUtf8();
+ serialNumber_ = s;
+ return s;
+ }
+ }
+ /**
+ * <code>string SerialNumber = 1;</code>
+ */
+ public com.google.protobuf.ByteString
+ getSerialNumberBytes() {
+ java.lang.Object ref = serialNumber_;
+ if (ref instanceof java.lang.String) {
+ com.google.protobuf.ByteString b =
+ com.google.protobuf.ByteString.copyFromUtf8(
+ (java.lang.String) ref);
+ serialNumber_ = b;
+ return b;
+ } else {
+ return (com.google.protobuf.ByteString) ref;
+ }
+ }
+
+ public static final int LOCALDB_FIELD_NUMBER = 2;
+ private com.google.protobuf.ByteString localDB_;
+ /**
+ * <code>bytes LocalDB = 2;</code>
+ */
+ public com.google.protobuf.ByteString getLocalDB() {
+ return localDB_;
+ }
+
+ private byte memoizedIsInitialized = -1;
+ public final boolean isInitialized() {
+ byte isInitialized = memoizedIsInitialized;
+ if (isInitialized == 1) return true;
+ if (isInitialized == 0) return false;
+
+ memoizedIsInitialized = 1;
+ return true;
+ }
+
+ public void writeTo(com.google.protobuf.CodedOutputStream output)
+ throws java.io.IOException {
+ if (!getSerialNumberBytes().isEmpty()) {
+ com.google.protobuf.GeneratedMessageV3.writeString(output, 1, serialNumber_);
+ }
+ if (!localDB_.isEmpty()) {
+ output.writeBytes(2, localDB_);
+ }
+ unknownFields.writeTo(output);
+ }
+
+ public int getSerializedSize() {
+ int size = memoizedSize;
+ if (size != -1) return size;
+
+ size = 0;
+ if (!getSerialNumberBytes().isEmpty()) {
+ size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, serialNumber_);
+ }
+ if (!localDB_.isEmpty()) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBytesSize(2, localDB_);
+ }
+ size += unknownFields.getSerializedSize();
+ memoizedSize = size;
+ return size;
+ }
+
+ @java.lang.Override
+ public boolean equals(final java.lang.Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof com.twine.tango.pmr.synchronization.SynchronizeDBRequestOuterClass.SynchronizeDBRequest)) {
+ return super.equals(obj);
+ }
+ com.twine.tango.pmr.synchronization.SynchronizeDBRequestOuterClass.SynchronizeDBRequest other = (com.twine.tango.pmr.synchronization.SynchronizeDBRequestOuterClass.SynchronizeDBRequest) obj;
+
+ boolean result = true;
+ result = result && getSerialNumber()
+ .equals(other.getSerialNumber());
+ result = result && getLocalDB()
+ .equals(other.getLocalDB());
+ result = result && unknownFields.equals(other.unknownFields);
+ return result;
+ }
+
+ @java.lang.Override
+ public int hashCode() {
+ if (memoizedHashCode != 0) {
+ return memoizedHashCode;
+ }
+ int hash = 41;
+ hash = (19 * hash) + getDescriptor().hashCode();
+ hash = (37 * hash) + SERIALNUMBER_FIELD_NUMBER;
+ hash = (53 * hash) + getSerialNumber().hashCode();
+ hash = (37 * hash) + LOCALDB_FIELD_NUMBER;
+ hash = (53 * hash) + getLocalDB().hashCode();
+ hash = (29 * hash) + unknownFields.hashCode();
+ memoizedHashCode = hash;
+ return hash;
+ }
+
+ public static com.twine.tango.pmr.synchronization.SynchronizeDBRequestOuterClass.SynchronizeDBRequest parseFrom(
+ java.nio.ByteBuffer data)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data);
+ }
+ public static com.twine.tango.pmr.synchronization.SynchronizeDBRequestOuterClass.SynchronizeDBRequest parseFrom(
+ java.nio.ByteBuffer data,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data, extensionRegistry);
+ }
+ public static com.twine.tango.pmr.synchronization.SynchronizeDBRequestOuterClass.SynchronizeDBRequest parseFrom(
+ com.google.protobuf.ByteString data)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data);
+ }
+ public static com.twine.tango.pmr.synchronization.SynchronizeDBRequestOuterClass.SynchronizeDBRequest parseFrom(
+ com.google.protobuf.ByteString data,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data, extensionRegistry);
+ }
+ public static com.twine.tango.pmr.synchronization.SynchronizeDBRequestOuterClass.SynchronizeDBRequest parseFrom(byte[] data)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data);
+ }
+ public static com.twine.tango.pmr.synchronization.SynchronizeDBRequestOuterClass.SynchronizeDBRequest parseFrom(
+ byte[] data,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data, extensionRegistry);
+ }
+ public static com.twine.tango.pmr.synchronization.SynchronizeDBRequestOuterClass.SynchronizeDBRequest parseFrom(java.io.InputStream input)
+ throws java.io.IOException {
+ return com.google.protobuf.GeneratedMessageV3
+ .parseWithIOException(PARSER, input);
+ }
+ public static com.twine.tango.pmr.synchronization.SynchronizeDBRequestOuterClass.SynchronizeDBRequest parseFrom(
+ java.io.InputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return com.google.protobuf.GeneratedMessageV3
+ .parseWithIOException(PARSER, input, extensionRegistry);
+ }
+ public static com.twine.tango.pmr.synchronization.SynchronizeDBRequestOuterClass.SynchronizeDBRequest parseDelimitedFrom(java.io.InputStream input)
+ throws java.io.IOException {
+ return com.google.protobuf.GeneratedMessageV3
+ .parseDelimitedWithIOException(PARSER, input);
+ }
+ public static com.twine.tango.pmr.synchronization.SynchronizeDBRequestOuterClass.SynchronizeDBRequest parseDelimitedFrom(
+ java.io.InputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return com.google.protobuf.GeneratedMessageV3
+ .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+ }
+ public static com.twine.tango.pmr.synchronization.SynchronizeDBRequestOuterClass.SynchronizeDBRequest parseFrom(
+ com.google.protobuf.CodedInputStream input)
+ throws java.io.IOException {
+ return com.google.protobuf.GeneratedMessageV3
+ .parseWithIOException(PARSER, input);
+ }
+ public static com.twine.tango.pmr.synchronization.SynchronizeDBRequestOuterClass.SynchronizeDBRequest parseFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return com.google.protobuf.GeneratedMessageV3
+ .parseWithIOException(PARSER, input, extensionRegistry);
+ }
+
+ public Builder newBuilderForType() { return newBuilder(); }
+ public static Builder newBuilder() {
+ return DEFAULT_INSTANCE.toBuilder();
+ }
+ public static Builder newBuilder(com.twine.tango.pmr.synchronization.SynchronizeDBRequestOuterClass.SynchronizeDBRequest prototype) {
+ return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+ }
+ public Builder toBuilder() {
+ return this == DEFAULT_INSTANCE
+ ? new Builder() : new Builder().mergeFrom(this);
+ }
+
+ @java.lang.Override
+ protected Builder newBuilderForType(
+ com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+ Builder builder = new Builder(parent);
+ return builder;
+ }
+ /**
+ * Protobuf type {@code Tango.PMR.Synchronization.SynchronizeDBRequest}
+ */
+ public static final class Builder extends
+ com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+ // @@protoc_insertion_point(builder_implements:Tango.PMR.Synchronization.SynchronizeDBRequest)
+ com.twine.tango.pmr.synchronization.SynchronizeDBRequestOuterClass.SynchronizeDBRequestOrBuilder {
+ public static final com.google.protobuf.Descriptors.Descriptor
+ getDescriptor() {
+ return com.twine.tango.pmr.synchronization.SynchronizeDBRequestOuterClass.internal_static_Tango_PMR_Synchronization_SynchronizeDBRequest_descriptor;
+ }
+
+ protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+ internalGetFieldAccessorTable() {
+ return com.twine.tango.pmr.synchronization.SynchronizeDBRequestOuterClass.internal_static_Tango_PMR_Synchronization_SynchronizeDBRequest_fieldAccessorTable
+ .ensureFieldAccessorsInitialized(
+ com.twine.tango.pmr.synchronization.SynchronizeDBRequestOuterClass.SynchronizeDBRequest.class, com.twine.tango.pmr.synchronization.SynchronizeDBRequestOuterClass.SynchronizeDBRequest.Builder.class);
+ }
+
+ // Construct using com.twine.tango.pmr.synchronization.SynchronizeDBRequestOuterClass.SynchronizeDBRequest.newBuilder()
+ private Builder() {
+ maybeForceBuilderInitialization();
+ }
+
+ private Builder(
+ com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+ super(parent);
+ maybeForceBuilderInitialization();
+ }
+ private void maybeForceBuilderInitialization() {
+ if (com.google.protobuf.GeneratedMessageV3
+ .alwaysUseFieldBuilders) {
+ }
+ }
+ public Builder clear() {
+ super.clear();
+ serialNumber_ = "";
+
+ localDB_ = com.google.protobuf.ByteString.EMPTY;
+
+ return this;
+ }
+
+ public com.google.protobuf.Descriptors.Descriptor
+ getDescriptorForType() {
+ return com.twine.tango.pmr.synchronization.SynchronizeDBRequestOuterClass.internal_static_Tango_PMR_Synchronization_SynchronizeDBRequest_descriptor;
+ }
+
+ public com.twine.tango.pmr.synchronization.SynchronizeDBRequestOuterClass.SynchronizeDBRequest getDefaultInstanceForType() {
+ return com.twine.tango.pmr.synchronization.SynchronizeDBRequestOuterClass.SynchronizeDBRequest.getDefaultInstance();
+ }
+
+ public com.twine.tango.pmr.synchronization.SynchronizeDBRequestOuterClass.SynchronizeDBRequest build() {
+ com.twine.tango.pmr.synchronization.SynchronizeDBRequestOuterClass.SynchronizeDBRequest result = buildPartial();
+ if (!result.isInitialized()) {
+ throw newUninitializedMessageException(result);
+ }
+ return result;
+ }
+
+ public com.twine.tango.pmr.synchronization.SynchronizeDBRequestOuterClass.SynchronizeDBRequest buildPartial() {
+ com.twine.tango.pmr.synchronization.SynchronizeDBRequestOuterClass.SynchronizeDBRequest result = new com.twine.tango.pmr.synchronization.SynchronizeDBRequestOuterClass.SynchronizeDBRequest(this);
+ result.serialNumber_ = serialNumber_;
+ result.localDB_ = localDB_;
+ onBuilt();
+ return result;
+ }
+
+ public Builder clone() {
+ return (Builder) super.clone();
+ }
+ public Builder setField(
+ com.google.protobuf.Descriptors.FieldDescriptor field,
+ java.lang.Object value) {
+ return (Builder) super.setField(field, value);
+ }
+ public Builder clearField(
+ com.google.protobuf.Descriptors.FieldDescriptor field) {
+ return (Builder) super.clearField(field);
+ }
+ public Builder clearOneof(
+ com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+ return (Builder) super.clearOneof(oneof);
+ }
+ public Builder setRepeatedField(
+ com.google.protobuf.Descriptors.FieldDescriptor field,
+ int index, java.lang.Object value) {
+ return (Builder) super.setRepeatedField(field, index, value);
+ }
+ public Builder addRepeatedField(
+ com.google.protobuf.Descriptors.FieldDescriptor field,
+ java.lang.Object value) {
+ return (Builder) super.addRepeatedField(field, value);
+ }
+ public Builder mergeFrom(com.google.protobuf.Message other) {
+ if (other instanceof com.twine.tango.pmr.synchronization.SynchronizeDBRequestOuterClass.SynchronizeDBRequest) {
+ return mergeFrom((com.twine.tango.pmr.synchronization.SynchronizeDBRequestOuterClass.SynchronizeDBRequest)other);
+ } else {
+ super.mergeFrom(other);
+ return this;
+ }
+ }
+
+ public Builder mergeFrom(com.twine.tango.pmr.synchronization.SynchronizeDBRequestOuterClass.SynchronizeDBRequest other) {
+ if (other == com.twine.tango.pmr.synchronization.SynchronizeDBRequestOuterClass.SynchronizeDBRequest.getDefaultInstance()) return this;
+ if (!other.getSerialNumber().isEmpty()) {
+ serialNumber_ = other.serialNumber_;
+ onChanged();
+ }
+ if (other.getLocalDB() != com.google.protobuf.ByteString.EMPTY) {
+ setLocalDB(other.getLocalDB());
+ }
+ this.mergeUnknownFields(other.unknownFields);
+ onChanged();
+ return this;
+ }
+
+ public final boolean isInitialized() {
+ return true;
+ }
+
+ public Builder mergeFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ com.twine.tango.pmr.synchronization.SynchronizeDBRequestOuterClass.SynchronizeDBRequest parsedMessage = null;
+ try {
+ parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+ } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+ parsedMessage = (com.twine.tango.pmr.synchronization.SynchronizeDBRequestOuterClass.SynchronizeDBRequest) e.getUnfinishedMessage();
+ throw e.unwrapIOException();
+ } finally {
+ if (parsedMessage != null) {
+ mergeFrom(parsedMessage);
+ }
+ }
+ return this;
+ }
+
+ private java.lang.Object serialNumber_ = "";
+ /**
+ * <code>string SerialNumber = 1;</code>
+ */
+ public java.lang.String getSerialNumber() {
+ java.lang.Object ref = serialNumber_;
+ if (!(ref instanceof java.lang.String)) {
+ com.google.protobuf.ByteString bs =
+ (com.google.protobuf.ByteString) ref;
+ java.lang.String s = bs.toStringUtf8();
+ serialNumber_ = s;
+ return s;
+ } else {
+ return (java.lang.String) ref;
+ }
+ }
+ /**
+ * <code>string SerialNumber = 1;</code>
+ */
+ public com.google.protobuf.ByteString
+ getSerialNumberBytes() {
+ java.lang.Object ref = serialNumber_;
+ if (ref instanceof String) {
+ com.google.protobuf.ByteString b =
+ com.google.protobuf.ByteString.copyFromUtf8(
+ (java.lang.String) ref);
+ serialNumber_ = b;
+ return b;
+ } else {
+ return (com.google.protobuf.ByteString) ref;
+ }
+ }
+ /**
+ * <code>string SerialNumber = 1;</code>
+ */
+ public Builder setSerialNumber(
+ java.lang.String value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+
+ serialNumber_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>string SerialNumber = 1;</code>
+ */
+ public Builder clearSerialNumber() {
+
+ serialNumber_ = getDefaultInstance().getSerialNumber();
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>string SerialNumber = 1;</code>
+ */
+ public Builder setSerialNumberBytes(
+ com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ checkByteStringIsUtf8(value);
+
+ serialNumber_ = value;
+ onChanged();
+ return this;
+ }
+
+ private com.google.protobuf.ByteString localDB_ = com.google.protobuf.ByteString.EMPTY;
+ /**
+ * <code>bytes LocalDB = 2;</code>
+ */
+ public com.google.protobuf.ByteString getLocalDB() {
+ return localDB_;
+ }
+ /**
+ * <code>bytes LocalDB = 2;</code>
+ */
+ public Builder setLocalDB(com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+
+ localDB_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>bytes LocalDB = 2;</code>
+ */
+ public Builder clearLocalDB() {
+
+ localDB_ = getDefaultInstance().getLocalDB();
+ onChanged();
+ return this;
+ }
+ public final Builder setUnknownFields(
+ final com.google.protobuf.UnknownFieldSet unknownFields) {
+ return super.setUnknownFieldsProto3(unknownFields);
+ }
+
+ public final Builder mergeUnknownFields(
+ final com.google.protobuf.UnknownFieldSet unknownFields) {
+ return super.mergeUnknownFields(unknownFields);
+ }
+
+
+ // @@protoc_insertion_point(builder_scope:Tango.PMR.Synchronization.SynchronizeDBRequest)
+ }
+
+ // @@protoc_insertion_point(class_scope:Tango.PMR.Synchronization.SynchronizeDBRequest)
+ private static final com.twine.tango.pmr.synchronization.SynchronizeDBRequestOuterClass.SynchronizeDBRequest DEFAULT_INSTANCE;
+ static {
+ DEFAULT_INSTANCE = new com.twine.tango.pmr.synchronization.SynchronizeDBRequestOuterClass.SynchronizeDBRequest();
+ }
+
+ public static com.twine.tango.pmr.synchronization.SynchronizeDBRequestOuterClass.SynchronizeDBRequest getDefaultInstance() {
+ return DEFAULT_INSTANCE;
+ }
+
+ private static final com.google.protobuf.Parser<SynchronizeDBRequest>
+ PARSER = new com.google.protobuf.AbstractParser<SynchronizeDBRequest>() {
+ public SynchronizeDBRequest parsePartialFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return new SynchronizeDBRequest(input, extensionRegistry);
+ }
+ };
+
+ public static com.google.protobuf.Parser<SynchronizeDBRequest> parser() {
+ return PARSER;
+ }
+
+ @java.lang.Override
+ public com.google.protobuf.Parser<SynchronizeDBRequest> getParserForType() {
+ return PARSER;
+ }
+
+ public com.twine.tango.pmr.synchronization.SynchronizeDBRequestOuterClass.SynchronizeDBRequest getDefaultInstanceForType() {
+ return DEFAULT_INSTANCE;
+ }
+
+ }
+
+ private static final com.google.protobuf.Descriptors.Descriptor
+ internal_static_Tango_PMR_Synchronization_SynchronizeDBRequest_descriptor;
+ private static final
+ com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+ internal_static_Tango_PMR_Synchronization_SynchronizeDBRequest_fieldAccessorTable;
+
+ public static com.google.protobuf.Descriptors.FileDescriptor
+ getDescriptor() {
+ return descriptor;
+ }
+ private static com.google.protobuf.Descriptors.FileDescriptor
+ descriptor;
+ static {
+ java.lang.String[] descriptorData = {
+ "\n\032SynchronizeDBRequest.proto\022\031Tango.PMR." +
+ "Synchronization\"=\n\024SynchronizeDBRequest\022" +
+ "\024\n\014SerialNumber\030\001 \001(\t\022\017\n\007LocalDB\030\002 \001(\014B%" +
+ "\n#com.twine.tango.pmr.synchronizationb\006p" +
+ "roto3"
+ };
+ com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+ new com.google.protobuf.Descriptors.FileDescriptor. InternalDescriptorAssigner() {
+ public com.google.protobuf.ExtensionRegistry assignDescriptors(
+ com.google.protobuf.Descriptors.FileDescriptor root) {
+ descriptor = root;
+ return null;
+ }
+ };
+ com.google.protobuf.Descriptors.FileDescriptor
+ .internalBuildGeneratedFileFrom(descriptorData,
+ new com.google.protobuf.Descriptors.FileDescriptor[] {
+ }, assigner);
+ internal_static_Tango_PMR_Synchronization_SynchronizeDBRequest_descriptor =
+ getDescriptor().getMessageTypes().get(0);
+ internal_static_Tango_PMR_Synchronization_SynchronizeDBRequest_fieldAccessorTable = new
+ com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+ internal_static_Tango_PMR_Synchronization_SynchronizeDBRequest_descriptor,
+ new java.lang.String[] { "SerialNumber", "LocalDB", });
+ }
+
+ // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/Software/Android_Studio/Tango.PMR/src/main/java/com/twine/tango/pmr/synchronization/SynchronizeDBResponseOuterClass.java b/Software/Android_Studio/Tango.PMR/src/main/java/com/twine/tango/pmr/synchronization/SynchronizeDBResponseOuterClass.java
new file mode 100644
index 000000000..653befd01
--- /dev/null
+++ b/Software/Android_Studio/Tango.PMR/src/main/java/com/twine/tango/pmr/synchronization/SynchronizeDBResponseOuterClass.java
@@ -0,0 +1,508 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: SynchronizeDBResponse.proto
+
+package com.twine.tango.pmr.synchronization;
+
+public final class SynchronizeDBResponseOuterClass {
+ private SynchronizeDBResponseOuterClass() {}
+ public static void registerAllExtensions(
+ com.google.protobuf.ExtensionRegistryLite registry) {
+ }
+
+ public static void registerAllExtensions(
+ com.google.protobuf.ExtensionRegistry registry) {
+ registerAllExtensions(
+ (com.google.protobuf.ExtensionRegistryLite) registry);
+ }
+ public interface SynchronizeDBResponseOrBuilder extends
+ // @@protoc_insertion_point(interface_extends:Tango.PMR.Synchronization.SynchronizeDBResponse)
+ com.google.protobuf.MessageOrBuilder {
+
+ /**
+ * <code>bytes RemoteDB = 1;</code>
+ */
+ com.google.protobuf.ByteString getRemoteDB();
+ }
+ /**
+ * Protobuf type {@code Tango.PMR.Synchronization.SynchronizeDBResponse}
+ */
+ public static final class SynchronizeDBResponse extends
+ com.google.protobuf.GeneratedMessageV3 implements
+ // @@protoc_insertion_point(message_implements:Tango.PMR.Synchronization.SynchronizeDBResponse)
+ SynchronizeDBResponseOrBuilder {
+ private static final long serialVersionUID = 0L;
+ // Use SynchronizeDBResponse.newBuilder() to construct.
+ private SynchronizeDBResponse(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+ super(builder);
+ }
+ private SynchronizeDBResponse() {
+ remoteDB_ = com.google.protobuf.ByteString.EMPTY;
+ }
+
+ @java.lang.Override
+ public final com.google.protobuf.UnknownFieldSet
+ getUnknownFields() {
+ return this.unknownFields;
+ }
+ private SynchronizeDBResponse(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ this();
+ int mutable_bitField0_ = 0;
+ com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+ com.google.protobuf.UnknownFieldSet.newBuilder();
+ try {
+ boolean done = false;
+ while (!done) {
+ int tag = input.readTag();
+ switch (tag) {
+ case 0:
+ done = true;
+ break;
+ default: {
+ if (!parseUnknownFieldProto3(
+ input, unknownFields, extensionRegistry, tag)) {
+ done = true;
+ }
+ break;
+ }
+ case 10: {
+
+ remoteDB_ = input.readBytes();
+ break;
+ }
+ }
+ }
+ } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+ throw e.setUnfinishedMessage(this);
+ } catch (java.io.IOException e) {
+ throw new com.google.protobuf.InvalidProtocolBufferException(
+ e).setUnfinishedMessage(this);
+ } finally {
+ this.unknownFields = unknownFields.build();
+ makeExtensionsImmutable();
+ }
+ }
+ public static final com.google.protobuf.Descriptors.Descriptor
+ getDescriptor() {
+ return com.twine.tango.pmr.synchronization.SynchronizeDBResponseOuterClass.internal_static_Tango_PMR_Synchronization_SynchronizeDBResponse_descriptor;
+ }
+
+ protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+ internalGetFieldAccessorTable() {
+ return com.twine.tango.pmr.synchronization.SynchronizeDBResponseOuterClass.internal_static_Tango_PMR_Synchronization_SynchronizeDBResponse_fieldAccessorTable
+ .ensureFieldAccessorsInitialized(
+ com.twine.tango.pmr.synchronization.SynchronizeDBResponseOuterClass.SynchronizeDBResponse.class, com.twine.tango.pmr.synchronization.SynchronizeDBResponseOuterClass.SynchronizeDBResponse.Builder.class);
+ }
+
+ public static final int REMOTEDB_FIELD_NUMBER = 1;
+ private com.google.protobuf.ByteString remoteDB_;
+ /**
+ * <code>bytes RemoteDB = 1;</code>
+ */
+ public com.google.protobuf.ByteString getRemoteDB() {
+ return remoteDB_;
+ }
+
+ private byte memoizedIsInitialized = -1;
+ public final boolean isInitialized() {
+ byte isInitialized = memoizedIsInitialized;
+ if (isInitialized == 1) return true;
+ if (isInitialized == 0) return false;
+
+ memoizedIsInitialized = 1;
+ return true;
+ }
+
+ public void writeTo(com.google.protobuf.CodedOutputStream output)
+ throws java.io.IOException {
+ if (!remoteDB_.isEmpty()) {
+ output.writeBytes(1, remoteDB_);
+ }
+ unknownFields.writeTo(output);
+ }
+
+ public int getSerializedSize() {
+ int size = memoizedSize;
+ if (size != -1) return size;
+
+ size = 0;
+ if (!remoteDB_.isEmpty()) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBytesSize(1, remoteDB_);
+ }
+ size += unknownFields.getSerializedSize();
+ memoizedSize = size;
+ return size;
+ }
+
+ @java.lang.Override
+ public boolean equals(final java.lang.Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof com.twine.tango.pmr.synchronization.SynchronizeDBResponseOuterClass.SynchronizeDBResponse)) {
+ return super.equals(obj);
+ }
+ com.twine.tango.pmr.synchronization.SynchronizeDBResponseOuterClass.SynchronizeDBResponse other = (com.twine.tango.pmr.synchronization.SynchronizeDBResponseOuterClass.SynchronizeDBResponse) obj;
+
+ boolean result = true;
+ result = result && getRemoteDB()
+ .equals(other.getRemoteDB());
+ result = result && unknownFields.equals(other.unknownFields);
+ return result;
+ }
+
+ @java.lang.Override
+ public int hashCode() {
+ if (memoizedHashCode != 0) {
+ return memoizedHashCode;
+ }
+ int hash = 41;
+ hash = (19 * hash) + getDescriptor().hashCode();
+ hash = (37 * hash) + REMOTEDB_FIELD_NUMBER;
+ hash = (53 * hash) + getRemoteDB().hashCode();
+ hash = (29 * hash) + unknownFields.hashCode();
+ memoizedHashCode = hash;
+ return hash;
+ }
+
+ public static com.twine.tango.pmr.synchronization.SynchronizeDBResponseOuterClass.SynchronizeDBResponse parseFrom(
+ java.nio.ByteBuffer data)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data);
+ }
+ public static com.twine.tango.pmr.synchronization.SynchronizeDBResponseOuterClass.SynchronizeDBResponse parseFrom(
+ java.nio.ByteBuffer data,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data, extensionRegistry);
+ }
+ public static com.twine.tango.pmr.synchronization.SynchronizeDBResponseOuterClass.SynchronizeDBResponse parseFrom(
+ com.google.protobuf.ByteString data)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data);
+ }
+ public static com.twine.tango.pmr.synchronization.SynchronizeDBResponseOuterClass.SynchronizeDBResponse parseFrom(
+ com.google.protobuf.ByteString data,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data, extensionRegistry);
+ }
+ public static com.twine.tango.pmr.synchronization.SynchronizeDBResponseOuterClass.SynchronizeDBResponse parseFrom(byte[] data)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data);
+ }
+ public static com.twine.tango.pmr.synchronization.SynchronizeDBResponseOuterClass.SynchronizeDBResponse parseFrom(
+ byte[] data,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data, extensionRegistry);
+ }
+ public static com.twine.tango.pmr.synchronization.SynchronizeDBResponseOuterClass.SynchronizeDBResponse parseFrom(java.io.InputStream input)
+ throws java.io.IOException {
+ return com.google.protobuf.GeneratedMessageV3
+ .parseWithIOException(PARSER, input);
+ }
+ public static com.twine.tango.pmr.synchronization.SynchronizeDBResponseOuterClass.SynchronizeDBResponse parseFrom(
+ java.io.InputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return com.google.protobuf.GeneratedMessageV3
+ .parseWithIOException(PARSER, input, extensionRegistry);
+ }
+ public static com.twine.tango.pmr.synchronization.SynchronizeDBResponseOuterClass.SynchronizeDBResponse parseDelimitedFrom(java.io.InputStream input)
+ throws java.io.IOException {
+ return com.google.protobuf.GeneratedMessageV3
+ .parseDelimitedWithIOException(PARSER, input);
+ }
+ public static com.twine.tango.pmr.synchronization.SynchronizeDBResponseOuterClass.SynchronizeDBResponse parseDelimitedFrom(
+ java.io.InputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return com.google.protobuf.GeneratedMessageV3
+ .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+ }
+ public static com.twine.tango.pmr.synchronization.SynchronizeDBResponseOuterClass.SynchronizeDBResponse parseFrom(
+ com.google.protobuf.CodedInputStream input)
+ throws java.io.IOException {
+ return com.google.protobuf.GeneratedMessageV3
+ .parseWithIOException(PARSER, input);
+ }
+ public static com.twine.tango.pmr.synchronization.SynchronizeDBResponseOuterClass.SynchronizeDBResponse parseFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return com.google.protobuf.GeneratedMessageV3
+ .parseWithIOException(PARSER, input, extensionRegistry);
+ }
+
+ public Builder newBuilderForType() { return newBuilder(); }
+ public static Builder newBuilder() {
+ return DEFAULT_INSTANCE.toBuilder();
+ }
+ public static Builder newBuilder(com.twine.tango.pmr.synchronization.SynchronizeDBResponseOuterClass.SynchronizeDBResponse prototype) {
+ return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+ }
+ public Builder toBuilder() {
+ return this == DEFAULT_INSTANCE
+ ? new Builder() : new Builder().mergeFrom(this);
+ }
+
+ @java.lang.Override
+ protected Builder newBuilderForType(
+ com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+ Builder builder = new Builder(parent);
+ return builder;
+ }
+ /**
+ * Protobuf type {@code Tango.PMR.Synchronization.SynchronizeDBResponse}
+ */
+ public static final class Builder extends
+ com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+ // @@protoc_insertion_point(builder_implements:Tango.PMR.Synchronization.SynchronizeDBResponse)
+ com.twine.tango.pmr.synchronization.SynchronizeDBResponseOuterClass.SynchronizeDBResponseOrBuilder {
+ public static final com.google.protobuf.Descriptors.Descriptor
+ getDescriptor() {
+ return com.twine.tango.pmr.synchronization.SynchronizeDBResponseOuterClass.internal_static_Tango_PMR_Synchronization_SynchronizeDBResponse_descriptor;
+ }
+
+ protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+ internalGetFieldAccessorTable() {
+ return com.twine.tango.pmr.synchronization.SynchronizeDBResponseOuterClass.internal_static_Tango_PMR_Synchronization_SynchronizeDBResponse_fieldAccessorTable
+ .ensureFieldAccessorsInitialized(
+ com.twine.tango.pmr.synchronization.SynchronizeDBResponseOuterClass.SynchronizeDBResponse.class, com.twine.tango.pmr.synchronization.SynchronizeDBResponseOuterClass.SynchronizeDBResponse.Builder.class);
+ }
+
+ // Construct using com.twine.tango.pmr.synchronization.SynchronizeDBResponseOuterClass.SynchronizeDBResponse.newBuilder()
+ private Builder() {
+ maybeForceBuilderInitialization();
+ }
+
+ private Builder(
+ com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+ super(parent);
+ maybeForceBuilderInitialization();
+ }
+ private void maybeForceBuilderInitialization() {
+ if (com.google.protobuf.GeneratedMessageV3
+ .alwaysUseFieldBuilders) {
+ }
+ }
+ public Builder clear() {
+ super.clear();
+ remoteDB_ = com.google.protobuf.ByteString.EMPTY;
+
+ return this;
+ }
+
+ public com.google.protobuf.Descriptors.Descriptor
+ getDescriptorForType() {
+ return com.twine.tango.pmr.synchronization.SynchronizeDBResponseOuterClass.internal_static_Tango_PMR_Synchronization_SynchronizeDBResponse_descriptor;
+ }
+
+ public com.twine.tango.pmr.synchronization.SynchronizeDBResponseOuterClass.SynchronizeDBResponse getDefaultInstanceForType() {
+ return com.twine.tango.pmr.synchronization.SynchronizeDBResponseOuterClass.SynchronizeDBResponse.getDefaultInstance();
+ }
+
+ public com.twine.tango.pmr.synchronization.SynchronizeDBResponseOuterClass.SynchronizeDBResponse build() {
+ com.twine.tango.pmr.synchronization.SynchronizeDBResponseOuterClass.SynchronizeDBResponse result = buildPartial();
+ if (!result.isInitialized()) {
+ throw newUninitializedMessageException(result);
+ }
+ return result;
+ }
+
+ public com.twine.tango.pmr.synchronization.SynchronizeDBResponseOuterClass.SynchronizeDBResponse buildPartial() {
+ com.twine.tango.pmr.synchronization.SynchronizeDBResponseOuterClass.SynchronizeDBResponse result = new com.twine.tango.pmr.synchronization.SynchronizeDBResponseOuterClass.SynchronizeDBResponse(this);
+ result.remoteDB_ = remoteDB_;
+ onBuilt();
+ return result;
+ }
+
+ public Builder clone() {
+ return (Builder) super.clone();
+ }
+ public Builder setField(
+ com.google.protobuf.Descriptors.FieldDescriptor field,
+ java.lang.Object value) {
+ return (Builder) super.setField(field, value);
+ }
+ public Builder clearField(
+ com.google.protobuf.Descriptors.FieldDescriptor field) {
+ return (Builder) super.clearField(field);
+ }
+ public Builder clearOneof(
+ com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+ return (Builder) super.clearOneof(oneof);
+ }
+ public Builder setRepeatedField(
+ com.google.protobuf.Descriptors.FieldDescriptor field,
+ int index, java.lang.Object value) {
+ return (Builder) super.setRepeatedField(field, index, value);
+ }
+ public Builder addRepeatedField(
+ com.google.protobuf.Descriptors.FieldDescriptor field,
+ java.lang.Object value) {
+ return (Builder) super.addRepeatedField(field, value);
+ }
+ public Builder mergeFrom(com.google.protobuf.Message other) {
+ if (other instanceof com.twine.tango.pmr.synchronization.SynchronizeDBResponseOuterClass.SynchronizeDBResponse) {
+ return mergeFrom((com.twine.tango.pmr.synchronization.SynchronizeDBResponseOuterClass.SynchronizeDBResponse)other);
+ } else {
+ super.mergeFrom(other);
+ return this;
+ }
+ }
+
+ public Builder mergeFrom(com.twine.tango.pmr.synchronization.SynchronizeDBResponseOuterClass.SynchronizeDBResponse other) {
+ if (other == com.twine.tango.pmr.synchronization.SynchronizeDBResponseOuterClass.SynchronizeDBResponse.getDefaultInstance()) return this;
+ if (other.getRemoteDB() != com.google.protobuf.ByteString.EMPTY) {
+ setRemoteDB(other.getRemoteDB());
+ }
+ this.mergeUnknownFields(other.unknownFields);
+ onChanged();
+ return this;
+ }
+
+ public final boolean isInitialized() {
+ return true;
+ }
+
+ public Builder mergeFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ com.twine.tango.pmr.synchronization.SynchronizeDBResponseOuterClass.SynchronizeDBResponse parsedMessage = null;
+ try {
+ parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+ } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+ parsedMessage = (com.twine.tango.pmr.synchronization.SynchronizeDBResponseOuterClass.SynchronizeDBResponse) e.getUnfinishedMessage();
+ throw e.unwrapIOException();
+ } finally {
+ if (parsedMessage != null) {
+ mergeFrom(parsedMessage);
+ }
+ }
+ return this;
+ }
+
+ private com.google.protobuf.ByteString remoteDB_ = com.google.protobuf.ByteString.EMPTY;
+ /**
+ * <code>bytes RemoteDB = 1;</code>
+ */
+ public com.google.protobuf.ByteString getRemoteDB() {
+ return remoteDB_;
+ }
+ /**
+ * <code>bytes RemoteDB = 1;</code>
+ */
+ public Builder setRemoteDB(com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+
+ remoteDB_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>bytes RemoteDB = 1;</code>
+ */
+ public Builder clearRemoteDB() {
+
+ remoteDB_ = getDefaultInstance().getRemoteDB();
+ onChanged();
+ return this;
+ }
+ public final Builder setUnknownFields(
+ final com.google.protobuf.UnknownFieldSet unknownFields) {
+ return super.setUnknownFieldsProto3(unknownFields);
+ }
+
+ public final Builder mergeUnknownFields(
+ final com.google.protobuf.UnknownFieldSet unknownFields) {
+ return super.mergeUnknownFields(unknownFields);
+ }
+
+
+ // @@protoc_insertion_point(builder_scope:Tango.PMR.Synchronization.SynchronizeDBResponse)
+ }
+
+ // @@protoc_insertion_point(class_scope:Tango.PMR.Synchronization.SynchronizeDBResponse)
+ private static final com.twine.tango.pmr.synchronization.SynchronizeDBResponseOuterClass.SynchronizeDBResponse DEFAULT_INSTANCE;
+ static {
+ DEFAULT_INSTANCE = new com.twine.tango.pmr.synchronization.SynchronizeDBResponseOuterClass.SynchronizeDBResponse();
+ }
+
+ public static com.twine.tango.pmr.synchronization.SynchronizeDBResponseOuterClass.SynchronizeDBResponse getDefaultInstance() {
+ return DEFAULT_INSTANCE;
+ }
+
+ private static final com.google.protobuf.Parser<SynchronizeDBResponse>
+ PARSER = new com.google.protobuf.AbstractParser<SynchronizeDBResponse>() {
+ public SynchronizeDBResponse parsePartialFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return new SynchronizeDBResponse(input, extensionRegistry);
+ }
+ };
+
+ public static com.google.protobuf.Parser<SynchronizeDBResponse> parser() {
+ return PARSER;
+ }
+
+ @java.lang.Override
+ public com.google.protobuf.Parser<SynchronizeDBResponse> getParserForType() {
+ return PARSER;
+ }
+
+ public com.twine.tango.pmr.synchronization.SynchronizeDBResponseOuterClass.SynchronizeDBResponse getDefaultInstanceForType() {
+ return DEFAULT_INSTANCE;
+ }
+
+ }
+
+ private static final com.google.protobuf.Descriptors.Descriptor
+ internal_static_Tango_PMR_Synchronization_SynchronizeDBResponse_descriptor;
+ private static final
+ com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+ internal_static_Tango_PMR_Synchronization_SynchronizeDBResponse_fieldAccessorTable;
+
+ public static com.google.protobuf.Descriptors.FileDescriptor
+ getDescriptor() {
+ return descriptor;
+ }
+ private static com.google.protobuf.Descriptors.FileDescriptor
+ descriptor;
+ static {
+ java.lang.String[] descriptorData = {
+ "\n\033SynchronizeDBResponse.proto\022\031Tango.PMR" +
+ ".Synchronization\")\n\025SynchronizeDBRespons" +
+ "e\022\020\n\010RemoteDB\030\001 \001(\014B%\n#com.twine.tango.p" +
+ "mr.synchronizationb\006proto3"
+ };
+ com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+ new com.google.protobuf.Descriptors.FileDescriptor. InternalDescriptorAssigner() {
+ public com.google.protobuf.ExtensionRegistry assignDescriptors(
+ com.google.protobuf.Descriptors.FileDescriptor root) {
+ descriptor = root;
+ return null;
+ }
+ };
+ com.google.protobuf.Descriptors.FileDescriptor
+ .internalBuildGeneratedFileFrom(descriptorData,
+ new com.google.protobuf.Descriptors.FileDescriptor[] {
+ }, assigner);
+ internal_static_Tango_PMR_Synchronization_SynchronizeDBResponse_descriptor =
+ getDescriptor().getMessageTypes().get(0);
+ internal_static_Tango_PMR_Synchronization_SynchronizeDBResponse_fieldAccessorTable = new
+ com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+ internal_static_Tango_PMR_Synchronization_SynchronizeDBResponse_descriptor,
+ new java.lang.String[] { "RemoteDB", });
+ }
+
+ // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/Software/Android_Studio/Tango.PMR/src/main/res/raw/packages.txt b/Software/Android_Studio/Tango.PMR/src/main/res/raw/packages.txt
index f332c1ed6..803095d92 100644
--- a/Software/Android_Studio/Tango.PMR/src/main/res/raw/packages.txt
+++ b/Software/Android_Studio/Tango.PMR/src/main/res/raw/packages.txt
@@ -1,3 +1,4 @@
common
jobs
stubs
+synchronization
diff --git a/Software/Android_Studio/Tango.SharedUI/build.gradle b/Software/Android_Studio/Tango.SharedUI/build.gradle
index f86545f9b..7eadccff2 100644
--- a/Software/Android_Studio/Tango.SharedUI/build.gradle
+++ b/Software/Android_Studio/Tango.SharedUI/build.gradle
@@ -49,6 +49,13 @@ dependencies {
annotationProcessor 'com.jakewharton:butterknife-compiler:8.7.0'
implementation globalDependencies.logging
implementation project(':Tango.Core')
-
compile 'com.hrules:horizontalnumberpicker:1.1.1'
+ //Extensions
+ compile 'me.tatarka.bindingcollectionadapter2:bindingcollectionadapter:2.2.0'
+ compile 'me.tatarka.bindingcollectionadapter2:bindingcollectionadapter-recyclerview:2.2.0'
+ compile globalDependencies.joda
+ implementation project(':Tango.Core')
+ implementation project(':Tango.DAL')
+ compile globalDependencies.protobuf
+ implementation project(':Tango.PMR')
}
diff --git a/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/AppInitializer.java b/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/AppInitializer.java
new file mode 100644
index 000000000..a177517db
--- /dev/null
+++ b/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/AppInitializer.java
@@ -0,0 +1,58 @@
+package com.twine.tango.sharedui;
+
+import android.content.Context;
+
+import com.elvishew.xlog.LogConfiguration;
+import com.elvishew.xlog.LogLevel;
+import com.elvishew.xlog.XLog;
+import com.elvishew.xlog.printer.AndroidPrinter;
+import com.elvishew.xlog.printer.Printer;
+import com.elvishew.xlog.printer.file.FilePrinter;
+import com.elvishew.xlog.printer.file.backup.FileSizeBackupStrategy;
+import com.elvishew.xlog.printer.file.naming.DateFileNameGenerator;
+import com.google.protobuf.GeneratedMessageV3;
+import com.twine.tango.core.ContextFactory;
+import com.twine.tango.dal.TangoDB;
+import com.twine.tango.pmr.MessageFactory;
+
+import net.danlew.android.joda.JodaTimeAndroid;
+
+import java.io.File;
+
+/**
+ * Created by Roy on 12/2/2017.
+ */
+
+public class AppInitializer
+{
+ public static void init(Context context)
+ {
+ JodaTimeAndroid.init(context);
+ ContextFactory.init(context);
+
+ LogConfiguration config = new LogConfiguration.Builder()
+ .logLevel(LogLevel.ALL)
+ .tag("Tango")
+ .t()
+ .st(1)
+// .b()
+ .addObjectFormatter(GeneratedMessageV3.class, msg -> msg.toString()).build();
+
+ File sdcard = context.getFilesDir();
+ File dir = new File(sdcard.getAbsolutePath() + "/logs");
+ boolean b = dir.mkdirs();
+
+ Printer androidPrinter = new AndroidPrinter();
+ Printer filePrinter = new FilePrinter.Builder(dir.getPath())
+ .fileNameGenerator(new DateFileNameGenerator())
+ .backupStrategy(new FileSizeBackupStrategy(1024 * 1024))
+ .build();
+
+ XLog.init(config, androidPrinter, filePrinter);
+ XLog.i("Logger Initialized. logs will be saved to: " + dir.getAbsolutePath());
+
+
+ TangoDB.init();
+ MessageFactory.init();
+ }
+}
diff --git a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/App.java b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/App.java
index 3937735cf..69e4c7b22 100644
--- a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/App.java
+++ b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/App.java
@@ -15,6 +15,7 @@ import com.elvishew.xlog.printer.file.naming.DateFileNameGenerator;
import com.google.protobuf.GeneratedMessageV3;
import com.twine.tango.core.ContextFactory;
import com.twine.tango.dal.TangoDB;
+import com.twine.tango.sharedui.AppInitializer;
import com.twine.tango.stubs.ui.dagger.ApplicationComponent;
import com.twine.tango.stubs.ui.dagger.ApplicationModule;
import com.twine.tango.stubs.ui.dagger.DaggerApplicationComponent;
@@ -43,42 +44,17 @@ public class App extends Application {
@Override
public File getDatabasePath(String name)
{
- return TangoDB.getDataBasePath(name);
+ return new File(TangoDB.getDataBasePath());
}
@Override
public void onCreate() {
super.onCreate();
-
- JodaTimeAndroid.init(this);
-
+
appComponent = initDagger(this);
context = getApplicationContext();
- ContextFactory.init(context);
-
- LogConfiguration config = new LogConfiguration.Builder()
- .logLevel(LogLevel.ALL)
- .tag("Tango")
- .t()
- .st(1)
-// .b()
- .addObjectFormatter(GeneratedMessageV3.class, msg -> msg.toString()).build();
-
- File sdcard = context.getFilesDir();
- File dir = new File(sdcard.getAbsolutePath() + "/logs");
- boolean b = dir.mkdirs();
-
- Printer androidPrinter = new AndroidPrinter();
- Printer filePrinter = new FilePrinter.Builder(dir.getPath())
- .fileNameGenerator(new DateFileNameGenerator())
- .backupStrategy(new FileSizeBackupStrategy(1024 * 1024))
- .build();
-
- XLog.init(config, androidPrinter, filePrinter);
- XLog.i("Logger Initialized. logs will be saved to: " + dir.getAbsolutePath());
-
- TangoDB.init();
+ AppInitializer.init(context);
Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> {
diff --git a/Software/Android_Studio/Tango.Synchronization/.gitignore b/Software/Android_Studio/Tango.Synchronization/.gitignore
new file mode 100644
index 000000000..796b96d1c
--- /dev/null
+++ b/Software/Android_Studio/Tango.Synchronization/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/Software/Android_Studio/Tango.Synchronization/build.gradle b/Software/Android_Studio/Tango.Synchronization/build.gradle
new file mode 100644
index 000000000..7134933aa
--- /dev/null
+++ b/Software/Android_Studio/Tango.Synchronization/build.gradle
@@ -0,0 +1,49 @@
+apply plugin: 'com.android.library'
+
+android {
+ compileSdkVersion 26
+ buildToolsVersion "26.0.1"
+
+
+ defaultConfig {
+ minSdkVersion 22
+ targetSdkVersion 26
+ versionCode 1
+ versionName "1.0"
+
+ testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+
+ multiDexEnabled true
+
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+}
+
+dependencies {
+ implementation fileTree(include: ['*.jar'], dir: 'libs')
+ implementation 'com.android.support:appcompat-v7:26.1.0'
+ testImplementation 'junit:junit:4.12'
+ androidTestImplementation 'com.android.support.test:runner:1.0.1'
+ androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
+ implementation project(':Tango.PMR')
+ implementation project(':Tango.Web')
+ compile globalDependencies.logging
+ compile globalDependencies.storage
+ compile globalDependencies.dagger
+ compile globalDependencies.daggerAndroid
+ implementation project(':Tango.DAL')
+ implementation project(':Tango.Integration')
+
+ compile globalDependencies.rxJava
+ compile globalDependencies.rxJavaAndroid
+}
diff --git a/Software/Android_Studio/Tango.Synchronization/proguard-rules.pro b/Software/Android_Studio/Tango.Synchronization/proguard-rules.pro
new file mode 100644
index 000000000..a0eef131a
--- /dev/null
+++ b/Software/Android_Studio/Tango.Synchronization/proguard-rules.pro
@@ -0,0 +1,25 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in C:\Users\Roy\AppData\Local\Android\Sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/Software/Android_Studio/Tango.Synchronization/src/androidTest/java/com/twine/tango/synchronization/ExampleInstrumentedTest.java b/Software/Android_Studio/Tango.Synchronization/src/androidTest/java/com/twine/tango/synchronization/ExampleInstrumentedTest.java
new file mode 100644
index 000000000..4ecda40dd
--- /dev/null
+++ b/Software/Android_Studio/Tango.Synchronization/src/androidTest/java/com/twine/tango/synchronization/ExampleInstrumentedTest.java
@@ -0,0 +1,32 @@
+package com.twine.tango.synchronization;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.twine.tango.core.ContextFactory;
+import com.twine.tango.integration.MachineIdentityProvider;
+import com.twine.tango.web.APIFactory;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest
+{
+ @Test
+ public void useAppContext() throws Exception
+ {
+ // Context of the app under test.
+ Context appContext = InstrumentationRegistry.getTargetContext();
+
+ assertEquals("com.twine.tango.synchronization.test", appContext.getPackageName());
+ }
+}
diff --git a/Software/Android_Studio/Tango.Synchronization/src/main/AndroidManifest.xml b/Software/Android_Studio/Tango.Synchronization/src/main/AndroidManifest.xml
new file mode 100644
index 000000000..0f9821a96
--- /dev/null
+++ b/Software/Android_Studio/Tango.Synchronization/src/main/AndroidManifest.xml
@@ -0,0 +1,2 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.twine.tango.synchronization" />
diff --git a/Software/Android_Studio/Tango.Synchronization/src/main/java/com/twine/tango/synchronization/ITangoSynchronizer.java b/Software/Android_Studio/Tango.Synchronization/src/main/java/com/twine/tango/synchronization/ITangoSynchronizer.java
new file mode 100644
index 000000000..1b61a29aa
--- /dev/null
+++ b/Software/Android_Studio/Tango.Synchronization/src/main/java/com/twine/tango/synchronization/ITangoSynchronizer.java
@@ -0,0 +1,12 @@
+package com.twine.tango.synchronization;
+
+import com.twine.tango.pmr.synchronization.SynchronizeDBResponseOuterClass.SynchronizeDBResponse;
+
+import io.reactivex.Completable;
+import io.reactivex.Single;
+
+
+public interface ITangoSynchronizer
+{
+ Completable synchronize();
+}
diff --git a/Software/Android_Studio/Tango.Synchronization/src/main/java/com/twine/tango/synchronization/TangoSynchronizer.java b/Software/Android_Studio/Tango.Synchronization/src/main/java/com/twine/tango/synchronization/TangoSynchronizer.java
new file mode 100644
index 000000000..555e4f01c
--- /dev/null
+++ b/Software/Android_Studio/Tango.Synchronization/src/main/java/com/twine/tango/synchronization/TangoSynchronizer.java
@@ -0,0 +1,65 @@
+package com.twine.tango.synchronization;
+
+import com.elvishew.xlog.XLog;
+import com.google.protobuf.ByteString;
+import com.snatik.storage.Storage;
+import com.twine.tango.core.ContextFactory;
+import com.twine.tango.dal.TangoDB;
+import com.twine.tango.integration.IMachineIdentityProvider;
+import com.twine.tango.pmr.synchronization.SynchronizeDBRequestOuterClass.SynchronizeDBRequest;
+import com.twine.tango.pmr.synchronization.SynchronizeDBResponseOuterClass.SynchronizeDBResponse;
+import com.twine.tango.web.APIFactory;
+import com.twine.tango.web.ISynchronizationAPI;
+
+import io.reactivex.Completable;
+import io.reactivex.Single;
+
+public class TangoSynchronizer implements ITangoSynchronizer
+{
+ private APIFactory api;
+ private IMachineIdentityProvider machineIdentityProvider;
+
+ public TangoSynchronizer(APIFactory api, IMachineIdentityProvider machineIdentityProvider)
+ {
+ this.api = api;
+ this.machineIdentityProvider = machineIdentityProvider;
+ }
+
+ @Override
+ public Completable synchronize()
+ {
+ return Completable.create((emitter) ->
+ {
+
+ //Backup DataBase.
+ TangoDB.backup();
+
+ Storage storage = new Storage(ContextFactory.getApplicationContext());
+
+ //Read current DB file bytes.
+ byte[] data = storage.readFile(TangoDB.getDataBasePath());
+
+ //Create synchronization web api.
+ ISynchronizationAPI synchAPI = api.getSynchronizationAPI();
+
+ //Create synchronization response.
+ SynchronizeDBRequest request = SynchronizeDBRequest.newBuilder()
+ .setSerialNumber(machineIdentityProvider.getSerialNumber())
+ .setLocalDB(ByteString.copyFrom(data))
+ .build();
+
+ synchAPI.synchronize(request).singleOrError().subscribe((response) ->
+ {
+
+ TangoDB.replace(response.getRemoteDB().toByteArray());
+ emitter.onComplete();
+
+ },(ex) ->
+ {
+ XLog.e(ex);
+ emitter.onError(ex);
+ });
+
+ });
+ }
+}
diff --git a/Software/Android_Studio/Tango.Synchronization/src/main/res/values/strings.xml b/Software/Android_Studio/Tango.Synchronization/src/main/res/values/strings.xml
new file mode 100644
index 000000000..f4a346f34
--- /dev/null
+++ b/Software/Android_Studio/Tango.Synchronization/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+<resources>
+ <string name="app_name">Tango.Synchronization</string>
+</resources>
diff --git a/Software/Android_Studio/Tango.Synchronization/src/test/java/com/twine/tango/synchronization/ExampleUnitTest.java b/Software/Android_Studio/Tango.Synchronization/src/test/java/com/twine/tango/synchronization/ExampleUnitTest.java
new file mode 100644
index 000000000..f7e3d9bad
--- /dev/null
+++ b/Software/Android_Studio/Tango.Synchronization/src/test/java/com/twine/tango/synchronization/ExampleUnitTest.java
@@ -0,0 +1,19 @@
+package com.twine.tango.synchronization;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
+ */
+public class ExampleUnitTest
+{
+ @Test
+ public void addition_isCorrect() throws Exception
+ {
+ assertEquals(4, 2 + 2);
+ }
+} \ No newline at end of file
diff --git a/Software/Android_Studio/Tango.UnitTesting/.gitignore b/Software/Android_Studio/Tango.UnitTesting/.gitignore
new file mode 100644
index 000000000..796b96d1c
--- /dev/null
+++ b/Software/Android_Studio/Tango.UnitTesting/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/Software/Android_Studio/Tango.UnitTesting/build.gradle b/Software/Android_Studio/Tango.UnitTesting/build.gradle
new file mode 100644
index 000000000..f1b2b0ab3
--- /dev/null
+++ b/Software/Android_Studio/Tango.UnitTesting/build.gradle
@@ -0,0 +1,48 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 26
+ buildToolsVersion "26.0.1"
+
+
+ defaultConfig {
+ applicationId "com.twine.tango.unittesting"
+ minSdkVersion 22
+ targetSdkVersion 26
+ versionCode 1
+ versionName "1.0"
+
+ testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+
+ multiDexEnabled true
+
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+}
+
+dependencies {
+ implementation fileTree(include: ['*.jar'], dir: 'libs')
+ implementation 'com.android.support:appcompat-v7:26.1.0'
+ implementation 'com.android.support.constraint:constraint-layout:1.0.2'
+ testImplementation 'junit:junit:4.12'
+ androidTestImplementation 'com.android.support.test:runner:1.0.1'
+ androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
+ implementation project(':Tango.Core')
+ implementation project(':Tango.DAL')
+ implementation project(':Tango.Integration')
+ implementation project(':Tango.SharedUI')
+ implementation project(':Tango.Stubs')
+ implementation project(':Tango.Synchronization')
+ implementation project(':Tango.Transport')
+ implementation project(':Tango.Web')
+}
diff --git a/Software/Android_Studio/Tango.UnitTesting/proguard-rules.pro b/Software/Android_Studio/Tango.UnitTesting/proguard-rules.pro
new file mode 100644
index 000000000..a0eef131a
--- /dev/null
+++ b/Software/Android_Studio/Tango.UnitTesting/proguard-rules.pro
@@ -0,0 +1,25 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in C:\Users\Roy\AppData\Local\Android\Sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/Software/Android_Studio/Tango.UnitTesting/src/androidTest/java/com/twine/tango/unittesting/Synchronization_TST.java b/Software/Android_Studio/Tango.UnitTesting/src/androidTest/java/com/twine/tango/unittesting/Synchronization_TST.java
new file mode 100644
index 000000000..7353fd0d4
--- /dev/null
+++ b/Software/Android_Studio/Tango.UnitTesting/src/androidTest/java/com/twine/tango/unittesting/Synchronization_TST.java
@@ -0,0 +1,71 @@
+package com.twine.tango.unittesting;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.elvishew.xlog.XLog;
+import com.raizlabs.android.dbflow.config.FlowManager;
+import com.raizlabs.android.dbflow.sql.language.SQLite;
+import com.twine.tango.dal.TangoDB;
+import com.twine.tango.dal.dao.OrganizationsDAO;
+import com.twine.tango.dal.entities.Organization;
+import com.twine.tango.integration.MachineIdentityProvider;
+import com.twine.tango.sharedui.AppInitializer;
+import com.twine.tango.synchronization.ITangoSynchronizer;
+import com.twine.tango.synchronization.TangoSynchronizer;
+import com.twine.tango.web.APIFactory;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
+ */
+@RunWith(AndroidJUnit4.class)
+public class Synchronization_TST
+{
+ @Test
+ public void useAppContext() throws Exception
+ {
+ // Context of the app under test.
+ Context appContext = InstrumentationRegistry.getTargetContext();
+
+ assertEquals("com.twine.tango.unittesting", appContext.getPackageName());
+ }
+
+ @Test
+ public void performSynchronization()
+ {
+ // Context of the app under test.
+ Context appContext = InstrumentationRegistry.getTargetContext();
+
+ AppInitializer.init(appContext);
+
+
+
+ for (Organization org : OrganizationsDAO.getAllOrganizations())
+ {
+ XLog.i(org.getName());
+ }
+
+
+ ITangoSynchronizer synchronizer = new TangoSynchronizer(new APIFactory("http://10.0.2.2:45455/api/"), new MachineIdentityProvider());
+
+ synchronizer.synchronize().subscribe(() ->
+ {
+ for (Organization org : OrganizationsDAO.getAllOrganizations())
+ {
+ XLog.i(org.getName());
+ }
+
+ }, (ex) ->
+ {
+ ex.printStackTrace();
+ });
+ }
+}
diff --git a/Software/Android_Studio/Tango.UnitTesting/src/main/AndroidManifest.xml b/Software/Android_Studio/Tango.UnitTesting/src/main/AndroidManifest.xml
new file mode 100644
index 000000000..89fc2427a
--- /dev/null
+++ b/Software/Android_Studio/Tango.UnitTesting/src/main/AndroidManifest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.twine.tango.unittesting">
+
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
+ <application
+ android:name=".App"
+ android:allowBackup="true"
+ android:icon="@mipmap/ic_launcher"
+ android:label="@string/app_name"
+ android:roundIcon="@mipmap/ic_launcher_round"
+ android:supportsRtl="true"
+ android:theme="@style/AppTheme">
+ <activity android:name=".MainActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest> \ No newline at end of file
diff --git a/Software/Android_Studio/Tango.UnitTesting/src/main/java/com/twine/tango/unittesting/App.java b/Software/Android_Studio/Tango.UnitTesting/src/main/java/com/twine/tango/unittesting/App.java
new file mode 100644
index 000000000..51ba62de8
--- /dev/null
+++ b/Software/Android_Studio/Tango.UnitTesting/src/main/java/com/twine/tango/unittesting/App.java
@@ -0,0 +1,20 @@
+package com.twine.tango.unittesting;
+
+import android.app.Application;
+
+import com.twine.tango.dal.TangoDB;
+
+import java.io.File;
+
+/**
+ * Created by Roy on 12/2/2017.
+ */
+
+public class App extends Application
+{
+ @Override
+ public File getDatabasePath(String name)
+ {
+ return new File(TangoDB.getDataBasePath(name));
+ }
+}
diff --git a/Software/Android_Studio/Tango.UnitTesting/src/main/java/com/twine/tango/unittesting/MainActivity.java b/Software/Android_Studio/Tango.UnitTesting/src/main/java/com/twine/tango/unittesting/MainActivity.java
new file mode 100644
index 000000000..4be88237d
--- /dev/null
+++ b/Software/Android_Studio/Tango.UnitTesting/src/main/java/com/twine/tango/unittesting/MainActivity.java
@@ -0,0 +1,15 @@
+package com.twine.tango.unittesting;
+
+import android.support.v7.app.AppCompatActivity;
+import android.os.Bundle;
+
+public class MainActivity extends AppCompatActivity
+{
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ }
+}
diff --git a/Software/Android_Studio/Tango.UnitTesting/src/main/res/drawable/ic_launcher_background.xml b/Software/Android_Studio/Tango.UnitTesting/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 000000000..1cd2a3665
--- /dev/null
+++ b/Software/Android_Studio/Tango.UnitTesting/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportHeight="108.0"
+ android:viewportWidth="108.0">
+ <path
+ android:fillColor="#26A69A"
+ android:pathData="M0,0h108v108h-108z"
+ android:strokeColor="#66FFFFFF"
+ android:strokeWidth="0.8" />
+ <path
+ android:fillColor="#00000000"
+ android:pathData="M19,0L19,108"
+ android:strokeColor="#33FFFFFF"
+ android:strokeWidth="0.8" />
+ <path
+ android:fillColor="#00000000"
+ android:pathData="M9,0L9,108"
+ android:strokeColor="#66FFFFFF"
+ android:strokeWidth="0.8" />
+ <path
+ android:fillColor="#00000000"
+ android:pathData="M39,0L39,108"
+ android:strokeColor="#66FFFFFF"
+ android:strokeWidth="0.8" />
+ <path
+ android:fillColor="#00000000"
+ android:pathData="M29,0L29,108"
+ android:strokeColor="#66FFFFFF"
+ android:strokeWidth="0.8" />
+ <path
+ android:fillColor="#00000000"
+ android:pathData="M59,0L59,108"
+ android:strokeColor="#66FFFFFF"
+ android:strokeWidth="0.8" />
+ <path
+ android:fillColor="#00000000"
+ android:pathData="M49,0L49,108"
+ android:strokeColor="#66FFFFFF"
+ android:strokeWidth="0.8" />
+ <path
+ android:fillColor="#00000000"
+ android:pathData="M79,0L79,108"
+ android:strokeColor="#66FFFFFF"
+ android:strokeWidth="0.8" />
+ <path
+ android:fillColor="#00000000"
+ android:pathData="M69,0L69,108"
+ android:strokeColor="#66FFFFFF"
+ android:strokeWidth="0.8" />
+ <path
+ android:fillColor="#00000000"
+ android:pathData="M89,0L89,108"
+ android:strokeColor="#33FFFFFF"
+ android:strokeWidth="0.8" />
+ <path
+ android:fillColor="#00000000"
+ android:pathData="M99,0L99,108"
+ android:strokeColor="#66FFFFFF"
+ android:strokeWidth="0.8" />
+ <path
+ android:fillColor="#00000000"
+ android:pathData="M0,89L108,89"
+ android:strokeColor="#33FFFFFF"
+ android:strokeWidth="0.8" />
+ <path
+ android:fillColor="#00000000"
+ android:pathData="M0,99L108,99"
+ android:strokeColor="#66FFFFFF"
+ android:strokeWidth="0.8" />
+ <path
+ android:fillColor="#00000000"
+ android:pathData="M0,69L108,69"
+ android:strokeColor="#66FFFFFF"
+ android:strokeWidth="0.8" />
+ <path
+ android:fillColor="#00000000"
+ android:pathData="M0,79L108,79"
+ android:strokeColor="#66FFFFFF"
+ android:strokeWidth="0.8" />
+ <path
+ android:fillColor="#00000000"
+ android:pathData="M0,49L108,49"
+ android:strokeColor="#66FFFFFF"
+ android:strokeWidth="0.8" />
+ <path
+ android:fillColor="#00000000"
+ android:pathData="M0,59L108,59"
+ android:strokeColor="#66FFFFFF"
+ android:strokeWidth="0.8" />
+ <path
+ android:fillColor="#00000000"
+ android:pathData="M0,29L108,29"
+ android:strokeColor="#66FFFFFF"
+ android:strokeWidth="0.8" />
+ <path
+ android:fillColor="#00000000"
+ android:pathData="M0,39L108,39"
+ android:strokeColor="#66FFFFFF"
+ android:strokeWidth="0.8" />
+ <path
+ android:fillColor="#00000000"
+ android:pathData="M0,19L108,19"
+ android:strokeColor="#33FFFFFF"
+ android:strokeWidth="0.8" />
+ <path
+ android:fillColor="#00000000"
+ android:pathData="M0,9L108,9"
+ android:strokeColor="#66FFFFFF"
+ android:strokeWidth="0.8" />
+</vector>
+
diff --git a/Software/Android_Studio/Tango.UnitTesting/src/main/res/layout/activity_main.xml b/Software/Android_Studio/Tango.UnitTesting/src/main/res/layout/activity_main.xml
new file mode 100644
index 000000000..22c2d005c
--- /dev/null
+++ b/Software/Android_Studio/Tango.UnitTesting/src/main/res/layout/activity_main.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ tools:context="com.twine.tango.unittesting.MainActivity">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Hello World!"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintLeft_toLeftOf="parent"
+ app:layout_constraintRight_toRightOf="parent"
+ app:layout_constraintTop_toTopOf="parent" />
+
+</android.support.constraint.ConstraintLayout>
diff --git a/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 000000000..00f9eaaf3
--- /dev/null
+++ b/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+ <background android:drawable="@drawable/ic_launcher_background" />
+ <foreground android:drawable="@mipmap/ic_launcher_foreground" />
+</adaptive-icon> \ No newline at end of file
diff --git a/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 000000000..00f9eaaf3
--- /dev/null
+++ b/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+ <background android:drawable="@drawable/ic_launcher_background" />
+ <foreground android:drawable="@mipmap/ic_launcher_foreground" />
+</adaptive-icon> \ No newline at end of file
diff --git a/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-hdpi/ic_launcher.png b/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 000000000..550730310
--- /dev/null
+++ b/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-hdpi/ic_launcher.png
Binary files differ
diff --git a/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-hdpi/ic_launcher_foreground.png b/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-hdpi/ic_launcher_foreground.png
new file mode 100644
index 000000000..4e526c95b
--- /dev/null
+++ b/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-hdpi/ic_launcher_foreground.png
Binary files differ
diff --git a/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-hdpi/ic_launcher_round.png b/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 000000000..8fab6a3a5
--- /dev/null
+++ b/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-hdpi/ic_launcher_round.png
Binary files differ
diff --git a/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-mdpi/ic_launcher.png b/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 000000000..6bc7fcd6f
--- /dev/null
+++ b/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-mdpi/ic_launcher.png
Binary files differ
diff --git a/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-mdpi/ic_launcher_foreground.png b/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-mdpi/ic_launcher_foreground.png
new file mode 100644
index 000000000..2c38c7190
--- /dev/null
+++ b/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-mdpi/ic_launcher_foreground.png
Binary files differ
diff --git a/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-mdpi/ic_launcher_round.png b/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 000000000..1eecc0e7d
--- /dev/null
+++ b/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-mdpi/ic_launcher_round.png
Binary files differ
diff --git a/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-xhdpi/ic_launcher.png b/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 000000000..ec87dcebe
--- /dev/null
+++ b/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-xhdpi/ic_launcher.png
Binary files differ
diff --git a/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png b/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png
new file mode 100644
index 000000000..072467eaa
--- /dev/null
+++ b/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png
Binary files differ
diff --git a/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 000000000..05ca079ca
--- /dev/null
+++ b/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-xhdpi/ic_launcher_round.png
Binary files differ
diff --git a/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-xxhdpi/ic_launcher.png b/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 000000000..6f67f21ba
--- /dev/null
+++ b/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png b/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png
new file mode 100644
index 000000000..78a6b7a34
--- /dev/null
+++ b/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png
Binary files differ
diff --git a/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 000000000..8bac0f274
--- /dev/null
+++ b/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
Binary files differ
diff --git a/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 000000000..0327e13fa
--- /dev/null
+++ b/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Binary files differ
diff --git a/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png b/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png
new file mode 100644
index 000000000..68ebe33fe
--- /dev/null
+++ b/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png
Binary files differ
diff --git a/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 000000000..bacd3e758
--- /dev/null
+++ b/Software/Android_Studio/Tango.UnitTesting/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
Binary files differ
diff --git a/Software/Android_Studio/Tango.UnitTesting/src/main/res/values/colors.xml b/Software/Android_Studio/Tango.UnitTesting/src/main/res/values/colors.xml
new file mode 100644
index 000000000..3ab3e9cbc
--- /dev/null
+++ b/Software/Android_Studio/Tango.UnitTesting/src/main/res/values/colors.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <color name="colorPrimary">#3F51B5</color>
+ <color name="colorPrimaryDark">#303F9F</color>
+ <color name="colorAccent">#FF4081</color>
+</resources>
diff --git a/Software/Android_Studio/Tango.UnitTesting/src/main/res/values/strings.xml b/Software/Android_Studio/Tango.UnitTesting/src/main/res/values/strings.xml
new file mode 100644
index 000000000..76b425acf
--- /dev/null
+++ b/Software/Android_Studio/Tango.UnitTesting/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+<resources>
+ <string name="app_name">Tango.UnitTesting</string>
+</resources>
diff --git a/Software/Android_Studio/Tango.UnitTesting/src/main/res/values/styles.xml b/Software/Android_Studio/Tango.UnitTesting/src/main/res/values/styles.xml
new file mode 100644
index 000000000..5885930df
--- /dev/null
+++ b/Software/Android_Studio/Tango.UnitTesting/src/main/res/values/styles.xml
@@ -0,0 +1,11 @@
+<resources>
+
+ <!-- Base application theme. -->
+ <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
+ <!-- Customize your theme here. -->
+ <item name="colorPrimary">@color/colorPrimary</item>
+ <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
+ <item name="colorAccent">@color/colorAccent</item>
+ </style>
+
+</resources>
diff --git a/Software/Android_Studio/Tango.UnitTesting/src/test/java/com/twine/tango/unittesting/ExampleUnitTest.java b/Software/Android_Studio/Tango.UnitTesting/src/test/java/com/twine/tango/unittesting/ExampleUnitTest.java
new file mode 100644
index 000000000..9c8cf8626
--- /dev/null
+++ b/Software/Android_Studio/Tango.UnitTesting/src/test/java/com/twine/tango/unittesting/ExampleUnitTest.java
@@ -0,0 +1,19 @@
+package com.twine.tango.unittesting;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
+ */
+public class ExampleUnitTest
+{
+ @Test
+ public void addition_isCorrect() throws Exception
+ {
+ assertEquals(4, 2 + 2);
+ }
+} \ No newline at end of file
diff --git a/Software/Android_Studio/Tango.UnitTests/build/intermediates/incremental/compileDebugAidl/dependency.store b/Software/Android_Studio/Tango.UnitTests/build/intermediates/incremental/compileDebugAidl/dependency.store
new file mode 100644
index 000000000..8b8400dcf
--- /dev/null
+++ b/Software/Android_Studio/Tango.UnitTests/build/intermediates/incremental/compileDebugAidl/dependency.store
Binary files differ
diff --git a/Software/Android_Studio/Tango.Web/.gitignore b/Software/Android_Studio/Tango.Web/.gitignore
new file mode 100644
index 000000000..796b96d1c
--- /dev/null
+++ b/Software/Android_Studio/Tango.Web/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/Software/Android_Studio/Tango.Web/build.gradle b/Software/Android_Studio/Tango.Web/build.gradle
new file mode 100644
index 000000000..f064794e1
--- /dev/null
+++ b/Software/Android_Studio/Tango.Web/build.gradle
@@ -0,0 +1,43 @@
+apply plugin: 'com.android.library'
+
+android {
+ compileSdkVersion 26
+ buildToolsVersion "26.0.1"
+
+
+ defaultConfig {
+ minSdkVersion 22
+ targetSdkVersion 26
+ versionCode 1
+ versionName "1.0"
+
+ testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+
+ multiDexEnabled true
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+}
+
+dependencies {
+ implementation fileTree(include: ['*.jar'], dir: 'libs')
+ implementation 'com.android.support:appcompat-v7:26.1.0'
+ testImplementation 'junit:junit:4.12'
+ androidTestImplementation 'com.android.support.test:runner:1.0.1'
+ androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
+ compile globalDependencies.rxJava
+ compile globalDependencies.rxJavaAndroid
+ compile globalDependencies.retrofit
+ compile globalDependencies.retrofit_protobuf
+ compile globalDependencies.retrofit_rxJava
+ implementation project(':Tango.PMR')
+}
diff --git a/Software/Android_Studio/Tango.Web/proguard-rules.pro b/Software/Android_Studio/Tango.Web/proguard-rules.pro
new file mode 100644
index 000000000..a0eef131a
--- /dev/null
+++ b/Software/Android_Studio/Tango.Web/proguard-rules.pro
@@ -0,0 +1,25 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in C:\Users\Roy\AppData\Local\Android\Sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/Software/Android_Studio/Tango.Web/src/androidTest/java/com/twine/tango/web/ExampleInstrumentedTest.java b/Software/Android_Studio/Tango.Web/src/androidTest/java/com/twine/tango/web/ExampleInstrumentedTest.java
new file mode 100644
index 000000000..8551911d6
--- /dev/null
+++ b/Software/Android_Studio/Tango.Web/src/androidTest/java/com/twine/tango/web/ExampleInstrumentedTest.java
@@ -0,0 +1,31 @@
+package com.twine.tango.web;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.Log;
+
+import com.twine.tango.pmr.stubs.CalculateRequestOuterClass.CalculateRequest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest
+{
+ @Test
+ public void useAppContext() throws Exception
+ {
+ // Context of the app under test.
+ Context appContext = InstrumentationRegistry.getTargetContext();
+
+ assertEquals("com.twine.tango.web.test", appContext.getPackageName());
+ }
+}
diff --git a/Software/Android_Studio/Tango.Web/src/main/AndroidManifest.xml b/Software/Android_Studio/Tango.Web/src/main/AndroidManifest.xml
new file mode 100644
index 000000000..8978fcb47
--- /dev/null
+++ b/Software/Android_Studio/Tango.Web/src/main/AndroidManifest.xml
@@ -0,0 +1,6 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.twine.tango.web">
+
+ <uses-permission android:name="android.permission.INTERNET" />
+
+</manifest>
diff --git a/Software/Android_Studio/Tango.Web/src/main/java/com/twine/tango/web/APIFactory.java b/Software/Android_Studio/Tango.Web/src/main/java/com/twine/tango/web/APIFactory.java
new file mode 100644
index 000000000..d244a99c8
--- /dev/null
+++ b/Software/Android_Studio/Tango.Web/src/main/java/com/twine/tango/web/APIFactory.java
@@ -0,0 +1,39 @@
+package com.twine.tango.web;
+
+import java.util.concurrent.TimeUnit;
+
+import okhttp3.OkHttpClient;
+import retrofit2.Retrofit;
+import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
+import retrofit2.converter.protobuf.ProtoConverterFactory;
+
+
+public class APIFactory
+{
+ private String base_url;
+
+ public APIFactory(String base_url)
+ {
+ this.base_url = base_url;
+ }
+
+ public ISynchronizationAPI getSynchronizationAPI()
+ {
+ return createAPI(ISynchronizationAPI.class, 60);
+ }
+
+ private <T> T createAPI(Class<?> cls, int timeout)
+ {
+ Retrofit retrofit = new Retrofit.Builder()
+ .baseUrl(base_url)
+ .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
+ .addConverterFactory(ProtoConverterFactory.create())
+ .client(new OkHttpClient.Builder()
+ .readTimeout(timeout, TimeUnit.SECONDS)
+ .writeTimeout(timeout, TimeUnit.SECONDS)
+ .build())
+ .build();
+
+ return (T) retrofit.create(cls);
+ }
+}
diff --git a/Software/Android_Studio/Tango.Web/src/main/java/com/twine/tango/web/ISynchronizationAPI.java b/Software/Android_Studio/Tango.Web/src/main/java/com/twine/tango/web/ISynchronizationAPI.java
new file mode 100644
index 000000000..3a3d34c3a
--- /dev/null
+++ b/Software/Android_Studio/Tango.Web/src/main/java/com/twine/tango/web/ISynchronizationAPI.java
@@ -0,0 +1,20 @@
+package com.twine.tango.web;
+
+import com.twine.tango.pmr.stubs.CalculateRequestOuterClass.CalculateRequest;
+import com.twine.tango.pmr.stubs.CalculateResponseOuterClass.CalculateResponse;
+import com.twine.tango.pmr.synchronization.SynchronizeDBRequestOuterClass.SynchronizeDBRequest;
+import com.twine.tango.pmr.synchronization.SynchronizeDBResponseOuterClass.SynchronizeDBResponse;
+
+import io.reactivex.Observable;
+import retrofit2.http.Body;
+import retrofit2.http.POST;
+
+/**
+ * Created by Roy on 11/30/2017.
+ */
+
+public interface ISynchronizationAPI
+{
+ @POST("Synchronization/Synchronize")
+ Observable<SynchronizeDBResponse> synchronize(@Body SynchronizeDBRequest request);
+}
diff --git a/Software/Android_Studio/Tango.Web/src/main/res/values/strings.xml b/Software/Android_Studio/Tango.Web/src/main/res/values/strings.xml
new file mode 100644
index 000000000..5ca3432a7
--- /dev/null
+++ b/Software/Android_Studio/Tango.Web/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+<resources>
+ <string name="app_name">Tango.Web</string>
+</resources>
diff --git a/Software/Android_Studio/Tango.Web/src/test/java/com/twine/tango/web/ExampleUnitTest.java b/Software/Android_Studio/Tango.Web/src/test/java/com/twine/tango/web/ExampleUnitTest.java
new file mode 100644
index 000000000..1b13bdc8e
--- /dev/null
+++ b/Software/Android_Studio/Tango.Web/src/test/java/com/twine/tango/web/ExampleUnitTest.java
@@ -0,0 +1,19 @@
+package com.twine.tango.web;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
+ */
+public class ExampleUnitTest
+{
+ @Test
+ public void addition_isCorrect() throws Exception
+ {
+ assertEquals(4, 2 + 2);
+ }
+} \ No newline at end of file
diff --git a/Software/Android_Studio/build.gradle b/Software/Android_Studio/build.gradle
index 37278df02..73b52173e 100644
--- a/Software/Android_Studio/build.gradle
+++ b/Software/Android_Studio/build.gradle
@@ -39,7 +39,10 @@ ext {
joda: 'net.danlew:android.joda:2.9.9.1',
stream: 'net.sourceforge.streamsupport:streamsupport:1.5.6',
linq: 'br.com.zbra:android-linq:1.1.0',
- storage: 'com.snatik:storage:2.1.0'
+ storage: 'com.snatik:storage:2.1.0',
+ retrofit: 'com.squareup.retrofit2:retrofit:2.3.0',
+ retrofit_protobuf: 'com.squareup.retrofit2:converter-protobuf:2.3.0',
+ retrofit_rxJava: 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
]
}
diff --git a/Software/Android_Studio/settings.gradle b/Software/Android_Studio/settings.gradle
index 8c9325ba4..9c10194eb 100644
--- a/Software/Android_Studio/settings.gradle
+++ b/Software/Android_Studio/settings.gradle
@@ -1 +1 @@
-include ':app', ':Tango.BL', ':Tango.Stubs.UI', ':Tango.SharedUI', ':Tango.Models', ':Tango.Stubs', ':Tango.Integration', ':Tango.Transport', ':Tango.Core', ':Tango.PMR', ':Tango.DAL'
+include ':app', ':Tango.BL', ':Tango.Stubs.UI', ':Tango.SharedUI', ':Tango.Models', ':Tango.Stubs', ':Tango.Integration', ':Tango.Transport', ':Tango.Core', ':Tango.PMR', ':Tango.DAL', ':Tango.Web', ':Tango.Synchronization', ':Tango.UnitTesting'
diff --git a/Software/DB/Tango.mdf b/Software/DB/Tango.mdf
index 0a414f667..c4394c69e 100644
--- a/Software/DB/Tango.mdf
+++ b/Software/DB/Tango.mdf
Binary files differ
diff --git a/Software/DB/Tango_log.ldf b/Software/DB/Tango_log.ldf
index 61af9018e..10a9a767d 100644
--- a/Software/DB/Tango_log.ldf
+++ b/Software/DB/Tango_log.ldf
Binary files differ
diff --git a/Software/PMR/Messages/Synchronization/SynchronizeDBRequest.proto b/Software/PMR/Messages/Synchronization/SynchronizeDBRequest.proto
new file mode 100644
index 000000000..b3b6d542f
--- /dev/null
+++ b/Software/PMR/Messages/Synchronization/SynchronizeDBRequest.proto
@@ -0,0 +1,10 @@
+syntax = "proto3";
+
+package Tango.PMR.Synchronization;
+option java_package = "com.twine.tango.pmr.synchronization";
+
+message SynchronizeDBRequest
+{
+ string SerialNumber = 1;
+ bytes LocalDB = 2;
+} \ No newline at end of file
diff --git a/Software/PMR/Messages/Synchronization/SynchronizeDBResponse.proto b/Software/PMR/Messages/Synchronization/SynchronizeDBResponse.proto
new file mode 100644
index 000000000..091934027
--- /dev/null
+++ b/Software/PMR/Messages/Synchronization/SynchronizeDBResponse.proto
@@ -0,0 +1,9 @@
+syntax = "proto3";
+
+package Tango.PMR.Synchronization;
+option java_package = "com.twine.tango.pmr.synchronization";
+
+message SynchronizeDBResponse
+{
+ bytes RemoteDB = 1;
+} \ No newline at end of file
diff --git a/Software/Visual_Studio/Installers/Keyoti.Conveyor.vsix b/Software/Visual_Studio/Installers/Keyoti.Conveyor.vsix
new file mode 100644
index 000000000..2a0b7a89a
--- /dev/null
+++ b/Software/Visual_Studio/Installers/Keyoti.Conveyor.vsix
Binary files differ
diff --git a/Software/Visual_Studio/Tango.Core/Helpers/PathHelper.cs b/Software/Visual_Studio/Tango.Core/Helpers/PathHelper.cs
index dd613ac5e..146dbbade 100644
--- a/Software/Visual_Studio/Tango.Core/Helpers/PathHelper.cs
+++ b/Software/Visual_Studio/Tango.Core/Helpers/PathHelper.cs
@@ -9,6 +9,10 @@ namespace Tango.Core.Helpers
{
public static class PathHelper
{
+ /// <summary>
+ /// Creates a temporary folder in %temp%\Twine\{Random} and returns the path to that folder.
+ /// </summary>
+ /// <returns></returns>
public static String GetTempFolderPath()
{
String tempDirectory = Path.Combine(Path.GetTempPath(), "Twine", Path.GetRandomFileName());
diff --git a/Software/Visual_Studio/Tango.PMR/Synchronization/SynchronizeDBRequest.cs b/Software/Visual_Studio/Tango.PMR/Synchronization/SynchronizeDBRequest.cs
new file mode 100644
index 000000000..54efa1062
--- /dev/null
+++ b/Software/Visual_Studio/Tango.PMR/Synchronization/SynchronizeDBRequest.cs
@@ -0,0 +1,188 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: SynchronizeDBRequest.proto
+#pragma warning disable 1591, 0612, 3021
+#region Designer generated code
+
+using pb = global::Google.Protobuf;
+using pbc = global::Google.Protobuf.Collections;
+using pbr = global::Google.Protobuf.Reflection;
+using scg = global::System.Collections.Generic;
+namespace Tango.PMR.Synchronization {
+
+ /// <summary>Holder for reflection information generated from SynchronizeDBRequest.proto</summary>
+ public static partial class SynchronizeDBRequestReflection {
+
+ #region Descriptor
+ /// <summary>File descriptor for SynchronizeDBRequest.proto</summary>
+ public static pbr::FileDescriptor Descriptor {
+ get { return descriptor; }
+ }
+ private static pbr::FileDescriptor descriptor;
+
+ static SynchronizeDBRequestReflection() {
+ byte[] descriptorData = global::System.Convert.FromBase64String(
+ string.Concat(
+ "ChpTeW5jaHJvbml6ZURCUmVxdWVzdC5wcm90bxIZVGFuZ28uUE1SLlN5bmNo",
+ "cm9uaXphdGlvbiI9ChRTeW5jaHJvbml6ZURCUmVxdWVzdBIUCgxTZXJpYWxO",
+ "dW1iZXIYASABKAkSDwoHTG9jYWxEQhgCIAEoDEIlCiNjb20udHdpbmUudGFu",
+ "Z28ucG1yLnN5bmNocm9uaXphdGlvbmIGcHJvdG8z"));
+ descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+ new pbr::FileDescriptor[] { },
+ new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.Synchronization.SynchronizeDBRequest), global::Tango.PMR.Synchronization.SynchronizeDBRequest.Parser, new[]{ "SerialNumber", "LocalDB" }, null, null, null)
+ }));
+ }
+ #endregion
+
+ }
+ #region Messages
+ public sealed partial class SynchronizeDBRequest : pb::IMessage<SynchronizeDBRequest> {
+ private static readonly pb::MessageParser<SynchronizeDBRequest> _parser = new pb::MessageParser<SynchronizeDBRequest>(() => new SynchronizeDBRequest());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pb::MessageParser<SynchronizeDBRequest> Parser { get { return _parser; } }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pbr::MessageDescriptor Descriptor {
+ get { return global::Tango.PMR.Synchronization.SynchronizeDBRequestReflection.Descriptor.MessageTypes[0]; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ pbr::MessageDescriptor pb::IMessage.Descriptor {
+ get { return Descriptor; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public SynchronizeDBRequest() {
+ OnConstruction();
+ }
+
+ partial void OnConstruction();
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public SynchronizeDBRequest(SynchronizeDBRequest other) : this() {
+ serialNumber_ = other.serialNumber_;
+ localDB_ = other.localDB_;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public SynchronizeDBRequest Clone() {
+ return new SynchronizeDBRequest(this);
+ }
+
+ /// <summary>Field number for the "SerialNumber" field.</summary>
+ public const int SerialNumberFieldNumber = 1;
+ private string serialNumber_ = "";
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public string SerialNumber {
+ get { return serialNumber_; }
+ set {
+ serialNumber_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ }
+ }
+
+ /// <summary>Field number for the "LocalDB" field.</summary>
+ public const int LocalDBFieldNumber = 2;
+ private pb::ByteString localDB_ = pb::ByteString.Empty;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public pb::ByteString LocalDB {
+ get { return localDB_; }
+ set {
+ localDB_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override bool Equals(object other) {
+ return Equals(other as SynchronizeDBRequest);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool Equals(SynchronizeDBRequest other) {
+ if (ReferenceEquals(other, null)) {
+ return false;
+ }
+ if (ReferenceEquals(other, this)) {
+ return true;
+ }
+ if (SerialNumber != other.SerialNumber) return false;
+ if (LocalDB != other.LocalDB) return false;
+ return true;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override int GetHashCode() {
+ int hash = 1;
+ if (SerialNumber.Length != 0) hash ^= SerialNumber.GetHashCode();
+ if (LocalDB.Length != 0) hash ^= LocalDB.GetHashCode();
+ return hash;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override string ToString() {
+ return pb::JsonFormatter.ToDiagnosticString(this);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void WriteTo(pb::CodedOutputStream output) {
+ if (SerialNumber.Length != 0) {
+ output.WriteRawTag(10);
+ output.WriteString(SerialNumber);
+ }
+ if (LocalDB.Length != 0) {
+ output.WriteRawTag(18);
+ output.WriteBytes(LocalDB);
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int CalculateSize() {
+ int size = 0;
+ if (SerialNumber.Length != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeStringSize(SerialNumber);
+ }
+ if (LocalDB.Length != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeBytesSize(LocalDB);
+ }
+ return size;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(SynchronizeDBRequest other) {
+ if (other == null) {
+ return;
+ }
+ if (other.SerialNumber.Length != 0) {
+ SerialNumber = other.SerialNumber;
+ }
+ if (other.LocalDB.Length != 0) {
+ LocalDB = other.LocalDB;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(pb::CodedInputStream input) {
+ uint tag;
+ while ((tag = input.ReadTag()) != 0) {
+ switch(tag) {
+ default:
+ input.SkipLastField();
+ break;
+ case 10: {
+ SerialNumber = input.ReadString();
+ break;
+ }
+ case 18: {
+ LocalDB = input.ReadBytes();
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
+ #endregion
+
+}
+
+#endregion Designer generated code
diff --git a/Software/Visual_Studio/Tango.PMR/Synchronization/SynchronizeDBResponse.cs b/Software/Visual_Studio/Tango.PMR/Synchronization/SynchronizeDBResponse.cs
new file mode 100644
index 000000000..e25a903b9
--- /dev/null
+++ b/Software/Visual_Studio/Tango.PMR/Synchronization/SynchronizeDBResponse.cs
@@ -0,0 +1,160 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: SynchronizeDBResponse.proto
+#pragma warning disable 1591, 0612, 3021
+#region Designer generated code
+
+using pb = global::Google.Protobuf;
+using pbc = global::Google.Protobuf.Collections;
+using pbr = global::Google.Protobuf.Reflection;
+using scg = global::System.Collections.Generic;
+namespace Tango.PMR.Synchronization {
+
+ /// <summary>Holder for reflection information generated from SynchronizeDBResponse.proto</summary>
+ public static partial class SynchronizeDBResponseReflection {
+
+ #region Descriptor
+ /// <summary>File descriptor for SynchronizeDBResponse.proto</summary>
+ public static pbr::FileDescriptor Descriptor {
+ get { return descriptor; }
+ }
+ private static pbr::FileDescriptor descriptor;
+
+ static SynchronizeDBResponseReflection() {
+ byte[] descriptorData = global::System.Convert.FromBase64String(
+ string.Concat(
+ "ChtTeW5jaHJvbml6ZURCUmVzcG9uc2UucHJvdG8SGVRhbmdvLlBNUi5TeW5j",
+ "aHJvbml6YXRpb24iKQoVU3luY2hyb25pemVEQlJlc3BvbnNlEhAKCFJlbW90",
+ "ZURCGAEgASgMQiUKI2NvbS50d2luZS50YW5nby5wbXIuc3luY2hyb25pemF0",
+ "aW9uYgZwcm90bzM="));
+ descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+ new pbr::FileDescriptor[] { },
+ new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.Synchronization.SynchronizeDBResponse), global::Tango.PMR.Synchronization.SynchronizeDBResponse.Parser, new[]{ "RemoteDB" }, null, null, null)
+ }));
+ }
+ #endregion
+
+ }
+ #region Messages
+ public sealed partial class SynchronizeDBResponse : pb::IMessage<SynchronizeDBResponse> {
+ private static readonly pb::MessageParser<SynchronizeDBResponse> _parser = new pb::MessageParser<SynchronizeDBResponse>(() => new SynchronizeDBResponse());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pb::MessageParser<SynchronizeDBResponse> Parser { get { return _parser; } }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pbr::MessageDescriptor Descriptor {
+ get { return global::Tango.PMR.Synchronization.SynchronizeDBResponseReflection.Descriptor.MessageTypes[0]; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ pbr::MessageDescriptor pb::IMessage.Descriptor {
+ get { return Descriptor; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public SynchronizeDBResponse() {
+ OnConstruction();
+ }
+
+ partial void OnConstruction();
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public SynchronizeDBResponse(SynchronizeDBResponse other) : this() {
+ remoteDB_ = other.remoteDB_;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public SynchronizeDBResponse Clone() {
+ return new SynchronizeDBResponse(this);
+ }
+
+ /// <summary>Field number for the "RemoteDB" field.</summary>
+ public const int RemoteDBFieldNumber = 1;
+ private pb::ByteString remoteDB_ = pb::ByteString.Empty;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public pb::ByteString RemoteDB {
+ get { return remoteDB_; }
+ set {
+ remoteDB_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override bool Equals(object other) {
+ return Equals(other as SynchronizeDBResponse);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool Equals(SynchronizeDBResponse other) {
+ if (ReferenceEquals(other, null)) {
+ return false;
+ }
+ if (ReferenceEquals(other, this)) {
+ return true;
+ }
+ if (RemoteDB != other.RemoteDB) return false;
+ return true;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override int GetHashCode() {
+ int hash = 1;
+ if (RemoteDB.Length != 0) hash ^= RemoteDB.GetHashCode();
+ return hash;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override string ToString() {
+ return pb::JsonFormatter.ToDiagnosticString(this);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void WriteTo(pb::CodedOutputStream output) {
+ if (RemoteDB.Length != 0) {
+ output.WriteRawTag(10);
+ output.WriteBytes(RemoteDB);
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int CalculateSize() {
+ int size = 0;
+ if (RemoteDB.Length != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeBytesSize(RemoteDB);
+ }
+ return size;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(SynchronizeDBResponse other) {
+ if (other == null) {
+ return;
+ }
+ if (other.RemoteDB.Length != 0) {
+ RemoteDB = other.RemoteDB;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(pb::CodedInputStream input) {
+ uint tag;
+ while ((tag = input.ReadTag()) != 0) {
+ switch(tag) {
+ default:
+ input.SkipLastField();
+ break;
+ case 10: {
+ RemoteDB = input.ReadBytes();
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
+ #endregion
+
+}
+
+#endregion Designer generated code
diff --git a/Software/Visual_Studio/Tango.PMR/Tango.PMR.csproj b/Software/Visual_Studio/Tango.PMR/Tango.PMR.csproj
index 7fd2a734f..e58d76ef2 100644
--- a/Software/Visual_Studio/Tango.PMR/Tango.PMR.csproj
+++ b/Software/Visual_Studio/Tango.PMR/Tango.PMR.csproj
@@ -59,6 +59,8 @@
<Compile Include="Stubs\CalculateResponse.cs" />
<Compile Include="Stubs\ProgressRequest.cs" />
<Compile Include="Stubs\ProgressResponse.cs" />
+ <Compile Include="Synchronization\SynchronizeDBRequest.cs" />
+ <Compile Include="Synchronization\SynchronizeDBResponse.cs" />
<Compile Include="TangoMessage.cs" />
</ItemGroup>
<ItemGroup>
diff --git a/Software/Visual_Studio/Tango.Synchronization/Local/LocalDBSynchronizer.cs b/Software/Visual_Studio/Tango.Synchronization/Local/LocalDBSynchronizer.cs
new file mode 100644
index 000000000..ca58686f3
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Synchronization/Local/LocalDBSynchronizer.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Synchronization.Local
+{
+ public class LocalDBSynchronizer
+ {
+ public static void Synchronize(String masterSQLiteFile, String slaveSQLiteFile)
+ {
+ using (LocalDBComparer comparer = new LocalDBComparer(new SQLiteDataBase(masterSQLiteFile), new SQLiteDataBase(slaveSQLiteFile)))
+ {
+ var diffs = comparer.Compare();
+ foreach (var diff in diffs)
+ {
+ diff.Commit();
+ }
+ }
+ }
+
+ public static Task SynchronizeAsync(String masterSQLiteFile, String slaveSQLiteFile)
+ {
+ return Task.Factory.StartNew(() => Synchronize(masterSQLiteFile, slaveSQLiteFile));
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Synchronization/Local/SqliteDataBase.cs b/Software/Visual_Studio/Tango.Synchronization/Local/SqliteDataBase.cs
index 83a14b493..b3d259e8c 100644
--- a/Software/Visual_Studio/Tango.Synchronization/Local/SqliteDataBase.cs
+++ b/Software/Visual_Studio/Tango.Synchronization/Local/SqliteDataBase.cs
@@ -8,6 +8,7 @@ using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using System.Threading;
namespace Tango.Synchronization.Local
{
@@ -487,6 +488,24 @@ namespace Tango.Synchronization.Local
public void Dispose()
{
_connection.Close();
+ _connection.Dispose();
+ GC.Collect();
+
+ while (true)
+ {
+ try
+ {
+ using (FileStream stream = File.Open(Source, FileMode.Open, FileAccess.Read))
+ {
+ return;
+ }
+ }
+ catch (IOException)
+ {
+ GC.Collect();
+ Thread.Sleep(200);
+ }
+ }
}
}
}
diff --git a/Software/Visual_Studio/Tango.Synchronization/Remote/RemoteDBSynchronizer.cs b/Software/Visual_Studio/Tango.Synchronization/Remote/RemoteDBSynchronizer.cs
new file mode 100644
index 000000000..2cd9e2d41
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Synchronization/Remote/RemoteDBSynchronizer.cs
@@ -0,0 +1,41 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using remote = Tango.DAL.Remote.DB;
+using local = Tango.DAL.Local.DB;
+
+namespace Tango.Synchronization.Remote
+{
+ public class RemoteDBSynchronizer
+ {
+ public static void Synchronize(String sqliteDbFile, String serialNumber)
+ {
+ using (var remoteDB = new remote.RemoteDB("LOCALHOST\\SQLEXPRESS", false))
+ {
+ using (var localDB = new local.LocalDB(sqliteDbFile))
+ {
+ RemoteDBComparer comparer = new RemoteDBComparer(remoteDB, localDB, serialNumber);
+ var diffs = comparer.Compare();
+
+ foreach (var diff in diffs)
+ {
+ diff.Commit();
+ }
+
+ remoteDB.SaveChanges();
+ localDB.SaveChanges();
+ }
+ }
+ }
+
+ public static Task SynchronizeAsync(String sqliteDBFile, String serialNumber)
+ {
+ return Task.Factory.StartNew(() =>
+ {
+ Synchronize(sqliteDBFile, serialNumber);
+ });
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Synchronization/Tango.Synchronization.csproj b/Software/Visual_Studio/Tango.Synchronization/Tango.Synchronization.csproj
index 36719516a..30208539c 100644
--- a/Software/Visual_Studio/Tango.Synchronization/Tango.Synchronization.csproj
+++ b/Software/Visual_Studio/Tango.Synchronization/Tango.Synchronization.csproj
@@ -69,12 +69,14 @@
<Compile Include="Local\Constants.cs" />
<Compile Include="Local\ExtensionMethods.cs" />
<Compile Include="Local\ILocalDataBase.cs" />
+ <Compile Include="Local\LocalDBSynchronizer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Local\LocalDBComparer.cs" />
<Compile Include="Diff.cs" />
<Compile Include="DiffAction.cs" />
<Compile Include="Local\SQLiteDataBase.cs" />
<Compile Include="Remote\RemoteDBComparer.cs" />
+ <Compile Include="Remote\RemoteDBSynchronizer.cs" />
<Compile Include="SyncConfiguration.cs" />
</ItemGroup>
<ItemGroup>
diff --git a/Software/Visual_Studio/Tango.UnitTesting/Synchronization_TST.cs b/Software/Visual_Studio/Tango.UnitTesting/Synchronization_TST.cs
index a5b29b413..26d197bcf 100644
--- a/Software/Visual_Studio/Tango.UnitTesting/Synchronization_TST.cs
+++ b/Software/Visual_Studio/Tango.UnitTesting/Synchronization_TST.cs
@@ -19,22 +19,7 @@ namespace Tango.UnitTesting
{
var console = Helper.InitializeLogging(true);
- using (var remoteDB = new remote.RemoteDB("LOCALHOST\\SQLEXPRESS", false))
- {
- using (var localDB = new local.LocalDB(Helper.GetSQLiteFilePath()))
- {
- RemoteDBComparer comparer = new RemoteDBComparer(remoteDB, localDB, "1234");
- var diffs = comparer.Compare();
-
- foreach (var diff in diffs)
- {
- diff.Commit();
- }
-
- remoteDB.SaveChanges();
- localDB.SaveChanges();
- }
- }
+ RemoteDBSynchronizer.Synchronize(Helper.GetSQLiteFilePath(), "1234");
console.WaitForConsoleExit().Wait();
}
diff --git a/Software/Android_Studio/Tango.DAL/src/main/assets/Tango.db b/Software/Visual_Studio/Web/Tango.MachineService/App_Data/Tango.db
index 68ca3633d..293ca63e0 100644
--- a/Software/Android_Studio/Tango.DAL/src/main/assets/Tango.db
+++ b/Software/Visual_Studio/Web/Tango.MachineService/App_Data/Tango.db
Binary files differ
diff --git a/Software/Visual_Studio/Web/Tango.MachineService/App_Start/WebApiConfig.cs b/Software/Visual_Studio/Web/Tango.MachineService/App_Start/WebApiConfig.cs
index 3cc7ae3c9..15f0e7afc 100644
--- a/Software/Visual_Studio/Web/Tango.MachineService/App_Start/WebApiConfig.cs
+++ b/Software/Visual_Studio/Web/Tango.MachineService/App_Start/WebApiConfig.cs
@@ -19,6 +19,8 @@ namespace Tango.MachineService
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
+
+ config.Formatters.Insert(0, new ProtoBufFormatter());
}
}
}
diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/SynchronizationController.cs b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/SynchronizationController.cs
new file mode 100644
index 000000000..fd87815c9
--- /dev/null
+++ b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/SynchronizationController.cs
@@ -0,0 +1,47 @@
+using Google.Protobuf;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Net.Http;
+using System.Threading.Tasks;
+using System.Web.Hosting;
+using System.Web.Http;
+using Tango.Core.Helpers;
+using Tango.PMR.Stubs;
+using Tango.PMR.Synchronization;
+using Tango.Synchronization.Local;
+using Tango.Synchronization.Remote;
+
+namespace Tango.MachineService.Controllers
+{
+ public class SynchronizationController : ApiController
+ {
+ [HttpPost]
+ public SynchronizeDBResponse Synchronize(SynchronizeDBRequest request)
+ {
+ String tempFolder = PathHelper.GetTempFolderPath();
+
+ String masterSQLiteFile = Path.Combine(tempFolder, "Remote.db");
+ String slaveSQLiteFile = Path.Combine(tempFolder, "Local.db");
+
+ File.WriteAllBytes(slaveSQLiteFile, request.LocalDB.ToByteArray());
+
+
+
+ File.Copy(HostingEnvironment.MapPath(@"~/App_Data/Tango.db"), masterSQLiteFile);
+
+ RemoteDBSynchronizer.Synchronize(masterSQLiteFile, request.SerialNumber);
+
+ LocalDBSynchronizer.Synchronize(masterSQLiteFile, slaveSQLiteFile);
+
+ SynchronizeDBResponse response = new SynchronizeDBResponse();
+ response.RemoteDB = ByteString.CopyFrom(File.ReadAllBytes(slaveSQLiteFile));
+
+ PathHelper.TryDeleteFolder(tempFolder);
+
+ return response;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Global.asax.cs b/Software/Visual_Studio/Web/Tango.MachineService/Global.asax.cs
index a96c7016e..ca2e5f00a 100644
--- a/Software/Visual_Studio/Web/Tango.MachineService/Global.asax.cs
+++ b/Software/Visual_Studio/Web/Tango.MachineService/Global.asax.cs
@@ -2,7 +2,9 @@
using System.Collections.Generic;
using System.Linq;
using System.Web;
+using System.Web.Hosting;
using System.Web.Http;
+using System.Web.Http.Filters;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
@@ -11,11 +13,32 @@ namespace Tango.MachineService
{
public class WebApiApplication : System.Web.HttpApplication
{
+ //Create filter
+ public class LogExceptionFilterAttribute : ExceptionFilterAttribute
+ {
+ public override void OnException(HttpActionExecutedContext context)
+ {
+ ErrorLogService.LogError(context.Exception);
+ }
+ }
+
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
+
+ //register your filter with Web API pipeline
+ GlobalConfiguration.Configuration.Filters.Add(new LogExceptionFilterAttribute());
+ }
+
+ //common service to be used for logging errors
+ public static class ErrorLogService
+ {
+ public static void LogError(Exception ex)
+ {
+ //Email developers, call fire department, log to database etc.
+ }
}
}
}
diff --git a/Software/Visual_Studio/Web/Tango.MachineService/ProtoBufFormatter.cs b/Software/Visual_Studio/Web/Tango.MachineService/ProtoBufFormatter.cs
new file mode 100644
index 000000000..1edf01acf
--- /dev/null
+++ b/Software/Visual_Studio/Web/Tango.MachineService/ProtoBufFormatter.cs
@@ -0,0 +1,72 @@
+using Google.Protobuf;
+using System;
+using System.IO;
+using System.Net;
+using System.Net.Http;
+using System.Net.Http.Formatting;
+using System.Net.Http.Headers;
+using System.Threading.Tasks;
+using Tango.PMR.Stubs;
+
+namespace Tango.MachineService
+{
+ public class ProtoBufFormatter : MediaTypeFormatter
+ {
+ private static readonly MediaTypeHeaderValue mediaType = new MediaTypeHeaderValue("application/x-protobuf");
+
+ public ProtoBufFormatter()
+ {
+ SupportedMediaTypes.Add(mediaType);
+ }
+
+ public static MediaTypeHeaderValue DefaultMediaType
+ {
+ get { return mediaType; }
+ }
+
+ public override bool CanReadType(Type type)
+ {
+ return true;
+ }
+
+ public override bool CanWriteType(Type type)
+ {
+ return true;
+ }
+
+ public override Task<object> ReadFromStreamAsync(Type type, Stream stream, HttpContent content, IFormatterLogger formatterLogger)
+ {
+ var tcs = new TaskCompletionSource<object>();
+
+ try
+ {
+ MessageParser parser = type.GetProperty("Parser").GetValue(null, null) as MessageParser;
+ IMessage req = parser.ParseFrom(stream);
+ tcs.SetResult(req);
+ }
+ catch (Exception ex)
+ {
+ tcs.SetException(ex);
+ }
+
+ return tcs.Task;
+ }
+
+ public override Task WriteToStreamAsync(Type type, object value, Stream stream, HttpContent content, TransportContext transportContext)
+ {
+ var tcs = new TaskCompletionSource<object>();
+
+ try
+ {
+ (value as IMessage).WriteTo(stream);
+ tcs.SetResult(null);
+ }
+ catch (Exception ex)
+ {
+ tcs.SetException(ex);
+ }
+
+ return tcs.Task;
+ }
+ }
+} \ No newline at end of file
diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Tango.MachineService.csproj b/Software/Visual_Studio/Web/Tango.MachineService/Tango.MachineService.csproj
index 698254b62..4875386c6 100644
--- a/Software/Visual_Studio/Web/Tango.MachineService/Tango.MachineService.csproj
+++ b/Software/Visual_Studio/Web/Tango.MachineService/Tango.MachineService.csproj
@@ -46,6 +46,15 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
+ <Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\EntityFramework.6.0.0\lib\net45\EntityFramework.dll</HintPath>
+ </Reference>
+ <Reference Include="EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\EntityFramework.6.0.0\lib\net45\EntityFramework.SqlServer.dll</HintPath>
+ </Reference>
+ <Reference Include="Google.Protobuf, Version=3.4.1.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Google.Protobuf.3.4.1\lib\net45\Google.Protobuf.dll</HintPath>
+ </Reference>
<Reference Include="Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.3\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll</HintPath>
</Reference>
@@ -53,6 +62,17 @@
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="System.Data.SQLite, Version=1.0.106.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\System.Data.SQLite.Core.1.0.106.0\lib\net46\System.Data.SQLite.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Data.SQLite.EF6, Version=1.0.106.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\System.Data.SQLite.EF6.1.0.106.0\lib\net46\System.Data.SQLite.EF6.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="System.Data.SQLite.Linq, Version=1.0.106.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\System.Data.SQLite.Linq.1.0.106.0\lib\net46\System.Data.SQLite.Linq.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
<Reference Include="System.Drawing" />
<Reference Include="System.Web.DynamicData" />
<Reference Include="System.Web.Entity" />
@@ -148,9 +168,11 @@
<ItemGroup>
<Compile Include="App_Start\BundleConfig.cs" />
<Compile Include="App_Start\FilterConfig.cs" />
+ <Compile Include="ProtoBufFormatter.cs" />
<Compile Include="App_Start\RouteConfig.cs" />
<Compile Include="App_Start\WebApiConfig.cs" />
<Compile Include="Controllers\HomeController.cs" />
+ <Compile Include="Controllers\SynchronizationController.cs" />
<Compile Include="Controllers\ValuesController.cs" />
<Compile Include="Global.asax.cs">
<DependentUpon>Global.asax</DependentUpon>
@@ -172,10 +194,27 @@
</Content>
</ItemGroup>
<ItemGroup>
- <Folder Include="App_Data\" />
+ <Content Include="packages.config" />
</ItemGroup>
<ItemGroup>
- <Content Include="packages.config" />
+ <ProjectReference Include="..\..\Tango.Core\Tango.Core.csproj">
+ <Project>{a34ee0f0-649d-41c8-8489-b6f1cc6924ee}</Project>
+ <Name>Tango.Core</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\Tango.PMR\Tango.PMR.csproj">
+ <Project>{e4927038-348d-4295-aaf4-861c58cb3943}</Project>
+ <Name>Tango.PMR</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\Tango.Synchronization\Tango.Synchronization.csproj">
+ <Project>{7ada4e86-cad7-4968-a210-3a8a9e5153ab}</Project>
+ <Name>Tango.Synchronization</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="..\..\..\DB\Tango.db">
+ <Link>App_Data\Tango.db</Link>
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
</ItemGroup>
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
@@ -211,7 +250,12 @@
</PropertyGroup>
<Error Condition="!Exists('..\..\packages\Microsoft.Net.Compilers.1.3.2\build\Microsoft.Net.Compilers.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.Net.Compilers.1.3.2\build\Microsoft.Net.Compilers.props'))" />
<Error Condition="!Exists('..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.3\build\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.3\build\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props'))" />
+ <Error Condition="!Exists('..\..\packages\System.Data.SQLite.Core.1.0.106.0\build\net46\System.Data.SQLite.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\System.Data.SQLite.Core.1.0.106.0\build\net46\System.Data.SQLite.Core.targets'))" />
</Target>
+ <Import Project="..\..\packages\System.Data.SQLite.Core.1.0.106.0\build\net46\System.Data.SQLite.Core.targets" Condition="Exists('..\..\packages\System.Data.SQLite.Core.1.0.106.0\build\net46\System.Data.SQLite.Core.targets')" />
+ <PropertyGroup>
+ <PreBuildEvent>copy /Y "$(SolutionDir)..\DB\Tango.db" "$(ProjectDir)App_Data\Tango.db"</PreBuildEvent>
+ </PropertyGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Web.config b/Software/Visual_Studio/Web/Tango.MachineService/Web.config
index dea42c025..53a9de5fd 100644
--- a/Software/Visual_Studio/Web/Tango.MachineService/Web.config
+++ b/Software/Visual_Studio/Web/Tango.MachineService/Web.config
@@ -1,14 +1,18 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="utf-8"?>
<!--
For more information on how to configure your ASP.NET application, please visit
https://go.microsoft.com/fwlink/?LinkId=301879
-->
<configuration>
+ <configSections>
+ <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
+ <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
+ </configSections>
<appSettings>
- <add key="webpages:Version" value="3.0.0.0"/>
- <add key="webpages:Enabled" value="false"/>
- <add key="ClientValidationEnabled" value="true"/>
- <add key="UnobtrusiveJavaScriptEnabled" value="true"/>
+ <add key="webpages:Version" value="3.0.0.0" />
+ <add key="webpages:Enabled" value="false" />
+ <add key="ClientValidationEnabled" value="true" />
+ <add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>
<!--
For a description of web.config changes see http://go.microsoft.com/fwlink/?LinkId=235367.
@@ -19,57 +23,74 @@
</system.Web>
-->
<system.web>
- <compilation debug="true" targetFramework="4.6"/>
- <httpRuntime targetFramework="4.5"/>
+ <compilation debug="true" targetFramework="4.6" />
+ <httpRuntime targetFramework="4.5" />
<httpModules>
- <add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web"/>
+ <add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" />
</httpModules>
</system.web>
<system.webServer>
<handlers>
- <remove name="ExtensionlessUrlHandler-Integrated-4.0"/>
- <remove name="OPTIONSVerbHandler"/>
- <remove name="TRACEVerbHandler"/>
- <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0"/>
+ <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
+ <remove name="OPTIONSVerbHandler" />
+ <remove name="TRACEVerbHandler" />
+ <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
- <validation validateIntegratedModeConfiguration="false"/>
+ <validation validateIntegratedModeConfiguration="false" />
<modules>
- <remove name="ApplicationInsightsWebTracking"/>
- <add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" preCondition="managedHandler"/>
+ <remove name="ApplicationInsightsWebTracking" />
+ <add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" preCondition="managedHandler" />
</modules>
</system.webServer>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
- <assemblyIdentity name="Newtonsoft.Json" culture="neutral" publicKeyToken="30ad4fe6b2a6aeed"/>
- <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0"/>
+ <assemblyIdentity name="Newtonsoft.Json" culture="neutral" publicKeyToken="30ad4fe6b2a6aeed" />
+ <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
<dependentAssembly>
- <assemblyIdentity name="System.Web.Optimization" publicKeyToken="31bf3856ad364e35"/>
- <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="1.1.0.0"/>
+ <assemblyIdentity name="System.Web.Optimization" publicKeyToken="31bf3856ad364e35" />
+ <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="1.1.0.0" />
</dependentAssembly>
<dependentAssembly>
- <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35"/>
- <bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234"/>
+ <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" />
+ <bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" />
</dependentAssembly>
<dependentAssembly>
- <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35"/>
- <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0"/>
+ <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
+ <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
- <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35"/>
- <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0"/>
+ <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
+ <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
- <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35"/>
- <bindingRedirect oldVersion="1.0.0.0-5.2.3.0" newVersion="5.2.3.0"/>
+ <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
+ <bindingRedirect oldVersion="1.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<system.codedom>
<compilers>
- <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:6 /nowarn:1659;1699;1701"/>
- <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:14 /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+"/>
+ <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:6 /nowarn:1659;1699;1701" />
+ <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:14 /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+" />
</compilers>
</system.codedom>
+ <entityFramework>
+ <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
+ <providers>
+ <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
+ <provider invariantName="System.Data.SQLite.EF6" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />
+ </providers>
+ </entityFramework>
+ <system.data>
+ <DbProviderFactories>
+ <remove invariant="System.Data.SQLite.EF6" />
+ <add name="SQLite Data Provider (Entity Framework 6)" invariant="System.Data.SQLite.EF6" description=".NET Framework Data Provider for SQLite (Entity Framework 6)" type="System.Data.SQLite.EF6.SQLiteProviderFactory, System.Data.SQLite.EF6" />
+ <remove invariant="System.Data.SQLite" /><add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".NET Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" /></DbProviderFactories>
+ </system.data>
</configuration> \ No newline at end of file
diff --git a/Software/Visual_Studio/Web/Tango.MachineService/packages.config b/Software/Visual_Studio/Web/Tango.MachineService/packages.config
index d842d5f8e..e73c5452b 100644
--- a/Software/Visual_Studio/Web/Tango.MachineService/packages.config
+++ b/Software/Visual_Studio/Web/Tango.MachineService/packages.config
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Antlr" version="3.4.1.9004" targetFramework="net45" />
+ <package id="EntityFramework" version="6.0.0" targetFramework="net46" />
+ <package id="Google.Protobuf" version="3.4.1" targetFramework="net46" />
<package id="Microsoft.ApplicationInsights" version="2.2.0" targetFramework="net45" requireReinstallation="true" />
<package id="Microsoft.ApplicationInsights.Agent.Intercept" version="2.0.6" targetFramework="net45" />
<package id="Microsoft.ApplicationInsights.DependencyCollector" version="2.2.0" targetFramework="net45" />
@@ -23,5 +25,9 @@
<package id="Modernizr" version="2.6.2" targetFramework="net45" />
<package id="Newtonsoft.Json" version="6.0.4" targetFramework="net45" />
<package id="Respond" version="1.2.0" targetFramework="net45" />
+ <package id="System.Data.SQLite" version="1.0.106.0" targetFramework="net46" />
+ <package id="System.Data.SQLite.Core" version="1.0.106.0" targetFramework="net46" />
+ <package id="System.Data.SQLite.EF6" version="1.0.106.0" targetFramework="net46" />
+ <package id="System.Data.SQLite.Linq" version="1.0.106.0" targetFramework="net46" />
<package id="WebGrease" version="1.5.2" targetFramework="net45" />
</packages> \ No newline at end of file