diff options
| author | Roy Ben-Shabat <Roy@Twine-s.com> | 2017-12-27 16:22:17 +0200 |
|---|---|---|
| committer | Roy Ben-Shabat <Roy@Twine-s.com> | 2017-12-27 16:22:17 +0200 |
| commit | 47d7120b81dd646ed9b18740c9cc87a7a33a7c58 (patch) | |
| tree | a40a87c00b514857d6ab817530950a70783a7590 /Software | |
| parent | af8530c50d90c12ebe60383e67101920760c314f (diff) | |
| download | Tango-47d7120b81dd646ed9b18740c9cc87a7a33a7c58.tar.gz Tango-47d7120b81dd646ed9b18740c9cc87a7a33a7c58.zip | |
Implemented KeepAlive Mechanism.
Direct Synchronization is now working good.
Diffstat (limited to 'Software')
22 files changed, 1575 insertions, 59 deletions
diff --git a/Software/Android_Studio/Tango.DAL/src/main/res/raw/tangodb b/Software/Android_Studio/Tango.DAL/src/main/res/raw/tangodb Binary files differindex f7af9b52f..d676fc8c3 100644 --- a/Software/Android_Studio/Tango.DAL/src/main/res/raw/tangodb +++ b/Software/Android_Studio/Tango.DAL/src/main/res/raw/tangodb diff --git a/Software/Android_Studio/Tango.PMR/src/main/java/com/twine/tango/pmr/common/KeepAliveRequestOuterClass.java b/Software/Android_Studio/Tango.PMR/src/main/java/com/twine/tango/pmr/common/KeepAliveRequestOuterClass.java new file mode 100644 index 000000000..e228e91c0 --- /dev/null +++ b/Software/Android_Studio/Tango.PMR/src/main/java/com/twine/tango/pmr/common/KeepAliveRequestOuterClass.java @@ -0,0 +1,440 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: KeepAliveRequest.proto + +package com.twine.tango.pmr.common; + +public final class KeepAliveRequestOuterClass { + private KeepAliveRequestOuterClass() {} + 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 KeepAliveRequestOrBuilder extends + // @@protoc_insertion_point(interface_extends:Tango.PMR.common.KeepAliveRequest) + com.google.protobuf.MessageOrBuilder { + } + /** + * Protobuf type {@code Tango.PMR.common.KeepAliveRequest} + */ + public static final class KeepAliveRequest extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:Tango.PMR.common.KeepAliveRequest) + KeepAliveRequestOrBuilder { + private static final long serialVersionUID = 0L; + // Use KeepAliveRequest.newBuilder() to construct. + private KeepAliveRequest(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) { + super(builder); + } + private KeepAliveRequest() { + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private KeepAliveRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + 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; + } + } + } + } 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.common.KeepAliveRequestOuterClass.internal_static_Tango_PMR_common_KeepAliveRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.twine.tango.pmr.common.KeepAliveRequestOuterClass.internal_static_Tango_PMR_common_KeepAliveRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.twine.tango.pmr.common.KeepAliveRequestOuterClass.KeepAliveRequest.class, com.twine.tango.pmr.common.KeepAliveRequestOuterClass.KeepAliveRequest.Builder.class); + } + + 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 { + unknownFields.writeTo(output); + } + + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + 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.common.KeepAliveRequestOuterClass.KeepAliveRequest)) { + return super.equals(obj); + } + com.twine.tango.pmr.common.KeepAliveRequestOuterClass.KeepAliveRequest other = (com.twine.tango.pmr.common.KeepAliveRequestOuterClass.KeepAliveRequest) obj; + + boolean result = true; + 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 = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static com.twine.tango.pmr.common.KeepAliveRequestOuterClass.KeepAliveRequest parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.twine.tango.pmr.common.KeepAliveRequestOuterClass.KeepAliveRequest 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.common.KeepAliveRequestOuterClass.KeepAliveRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.twine.tango.pmr.common.KeepAliveRequestOuterClass.KeepAliveRequest 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.common.KeepAliveRequestOuterClass.KeepAliveRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.twine.tango.pmr.common.KeepAliveRequestOuterClass.KeepAliveRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.twine.tango.pmr.common.KeepAliveRequestOuterClass.KeepAliveRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static com.twine.tango.pmr.common.KeepAliveRequestOuterClass.KeepAliveRequest 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.common.KeepAliveRequestOuterClass.KeepAliveRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static com.twine.tango.pmr.common.KeepAliveRequestOuterClass.KeepAliveRequest 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.common.KeepAliveRequestOuterClass.KeepAliveRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static com.twine.tango.pmr.common.KeepAliveRequestOuterClass.KeepAliveRequest 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.common.KeepAliveRequestOuterClass.KeepAliveRequest 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.common.KeepAliveRequest} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements + // @@protoc_insertion_point(builder_implements:Tango.PMR.common.KeepAliveRequest) + com.twine.tango.pmr.common.KeepAliveRequestOuterClass.KeepAliveRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.twine.tango.pmr.common.KeepAliveRequestOuterClass.internal_static_Tango_PMR_common_KeepAliveRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.twine.tango.pmr.common.KeepAliveRequestOuterClass.internal_static_Tango_PMR_common_KeepAliveRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.twine.tango.pmr.common.KeepAliveRequestOuterClass.KeepAliveRequest.class, com.twine.tango.pmr.common.KeepAliveRequestOuterClass.KeepAliveRequest.Builder.class); + } + + // Construct using com.twine.tango.pmr.common.KeepAliveRequestOuterClass.KeepAliveRequest.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(); + return this; + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return com.twine.tango.pmr.common.KeepAliveRequestOuterClass.internal_static_Tango_PMR_common_KeepAliveRequest_descriptor; + } + + public com.twine.tango.pmr.common.KeepAliveRequestOuterClass.KeepAliveRequest getDefaultInstanceForType() { + return com.twine.tango.pmr.common.KeepAliveRequestOuterClass.KeepAliveRequest.getDefaultInstance(); + } + + public com.twine.tango.pmr.common.KeepAliveRequestOuterClass.KeepAliveRequest build() { + com.twine.tango.pmr.common.KeepAliveRequestOuterClass.KeepAliveRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public com.twine.tango.pmr.common.KeepAliveRequestOuterClass.KeepAliveRequest buildPartial() { + com.twine.tango.pmr.common.KeepAliveRequestOuterClass.KeepAliveRequest result = new com.twine.tango.pmr.common.KeepAliveRequestOuterClass.KeepAliveRequest(this); + 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.common.KeepAliveRequestOuterClass.KeepAliveRequest) { + return mergeFrom((com.twine.tango.pmr.common.KeepAliveRequestOuterClass.KeepAliveRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(com.twine.tango.pmr.common.KeepAliveRequestOuterClass.KeepAliveRequest other) { + if (other == com.twine.tango.pmr.common.KeepAliveRequestOuterClass.KeepAliveRequest.getDefaultInstance()) return this; + 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.common.KeepAliveRequestOuterClass.KeepAliveRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (com.twine.tango.pmr.common.KeepAliveRequestOuterClass.KeepAliveRequest) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + 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.common.KeepAliveRequest) + } + + // @@protoc_insertion_point(class_scope:Tango.PMR.common.KeepAliveRequest) + private static final com.twine.tango.pmr.common.KeepAliveRequestOuterClass.KeepAliveRequest DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new com.twine.tango.pmr.common.KeepAliveRequestOuterClass.KeepAliveRequest(); + } + + public static com.twine.tango.pmr.common.KeepAliveRequestOuterClass.KeepAliveRequest getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser<KeepAliveRequest> + PARSER = new com.google.protobuf.AbstractParser<KeepAliveRequest>() { + public KeepAliveRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new KeepAliveRequest(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser<KeepAliveRequest> parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser<KeepAliveRequest> getParserForType() { + return PARSER; + } + + public com.twine.tango.pmr.common.KeepAliveRequestOuterClass.KeepAliveRequest getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_Tango_PMR_common_KeepAliveRequest_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_Tango_PMR_common_KeepAliveRequest_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\026KeepAliveRequest.proto\022\020Tango.PMR.comm" + + "on\"\022\n\020KeepAliveRequestB\034\n\032com.twine.tang" + + "o.pmr.commonb\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_common_KeepAliveRequest_descriptor = + getDescriptor().getMessageTypes().get(0); + internal_static_Tango_PMR_common_KeepAliveRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_Tango_PMR_common_KeepAliveRequest_descriptor, + new java.lang.String[] { }); + } + + // @@protoc_insertion_point(outer_class_scope) +} diff --git a/Software/Android_Studio/Tango.PMR/src/main/java/com/twine/tango/pmr/common/KeepAliveResponseOuterClass.java b/Software/Android_Studio/Tango.PMR/src/main/java/com/twine/tango/pmr/common/KeepAliveResponseOuterClass.java new file mode 100644 index 000000000..d46b86204 --- /dev/null +++ b/Software/Android_Studio/Tango.PMR/src/main/java/com/twine/tango/pmr/common/KeepAliveResponseOuterClass.java @@ -0,0 +1,440 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: KeepAliveResponse.proto + +package com.twine.tango.pmr.common; + +public final class KeepAliveResponseOuterClass { + private KeepAliveResponseOuterClass() {} + 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 KeepAliveResponseOrBuilder extends + // @@protoc_insertion_point(interface_extends:Tango.PMR.common.KeepAliveResponse) + com.google.protobuf.MessageOrBuilder { + } + /** + * Protobuf type {@code Tango.PMR.common.KeepAliveResponse} + */ + public static final class KeepAliveResponse extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:Tango.PMR.common.KeepAliveResponse) + KeepAliveResponseOrBuilder { + private static final long serialVersionUID = 0L; + // Use KeepAliveResponse.newBuilder() to construct. + private KeepAliveResponse(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) { + super(builder); + } + private KeepAliveResponse() { + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private KeepAliveResponse( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + 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; + } + } + } + } 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.common.KeepAliveResponseOuterClass.internal_static_Tango_PMR_common_KeepAliveResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.twine.tango.pmr.common.KeepAliveResponseOuterClass.internal_static_Tango_PMR_common_KeepAliveResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.twine.tango.pmr.common.KeepAliveResponseOuterClass.KeepAliveResponse.class, com.twine.tango.pmr.common.KeepAliveResponseOuterClass.KeepAliveResponse.Builder.class); + } + + 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 { + unknownFields.writeTo(output); + } + + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + 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.common.KeepAliveResponseOuterClass.KeepAliveResponse)) { + return super.equals(obj); + } + com.twine.tango.pmr.common.KeepAliveResponseOuterClass.KeepAliveResponse other = (com.twine.tango.pmr.common.KeepAliveResponseOuterClass.KeepAliveResponse) obj; + + boolean result = true; + 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 = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static com.twine.tango.pmr.common.KeepAliveResponseOuterClass.KeepAliveResponse parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.twine.tango.pmr.common.KeepAliveResponseOuterClass.KeepAliveResponse 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.common.KeepAliveResponseOuterClass.KeepAliveResponse parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.twine.tango.pmr.common.KeepAliveResponseOuterClass.KeepAliveResponse 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.common.KeepAliveResponseOuterClass.KeepAliveResponse parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.twine.tango.pmr.common.KeepAliveResponseOuterClass.KeepAliveResponse parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.twine.tango.pmr.common.KeepAliveResponseOuterClass.KeepAliveResponse parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static com.twine.tango.pmr.common.KeepAliveResponseOuterClass.KeepAliveResponse 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.common.KeepAliveResponseOuterClass.KeepAliveResponse parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static com.twine.tango.pmr.common.KeepAliveResponseOuterClass.KeepAliveResponse 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.common.KeepAliveResponseOuterClass.KeepAliveResponse parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static com.twine.tango.pmr.common.KeepAliveResponseOuterClass.KeepAliveResponse 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.common.KeepAliveResponseOuterClass.KeepAliveResponse 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.common.KeepAliveResponse} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements + // @@protoc_insertion_point(builder_implements:Tango.PMR.common.KeepAliveResponse) + com.twine.tango.pmr.common.KeepAliveResponseOuterClass.KeepAliveResponseOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.twine.tango.pmr.common.KeepAliveResponseOuterClass.internal_static_Tango_PMR_common_KeepAliveResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.twine.tango.pmr.common.KeepAliveResponseOuterClass.internal_static_Tango_PMR_common_KeepAliveResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.twine.tango.pmr.common.KeepAliveResponseOuterClass.KeepAliveResponse.class, com.twine.tango.pmr.common.KeepAliveResponseOuterClass.KeepAliveResponse.Builder.class); + } + + // Construct using com.twine.tango.pmr.common.KeepAliveResponseOuterClass.KeepAliveResponse.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(); + return this; + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return com.twine.tango.pmr.common.KeepAliveResponseOuterClass.internal_static_Tango_PMR_common_KeepAliveResponse_descriptor; + } + + public com.twine.tango.pmr.common.KeepAliveResponseOuterClass.KeepAliveResponse getDefaultInstanceForType() { + return com.twine.tango.pmr.common.KeepAliveResponseOuterClass.KeepAliveResponse.getDefaultInstance(); + } + + public com.twine.tango.pmr.common.KeepAliveResponseOuterClass.KeepAliveResponse build() { + com.twine.tango.pmr.common.KeepAliveResponseOuterClass.KeepAliveResponse result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public com.twine.tango.pmr.common.KeepAliveResponseOuterClass.KeepAliveResponse buildPartial() { + com.twine.tango.pmr.common.KeepAliveResponseOuterClass.KeepAliveResponse result = new com.twine.tango.pmr.common.KeepAliveResponseOuterClass.KeepAliveResponse(this); + 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.common.KeepAliveResponseOuterClass.KeepAliveResponse) { + return mergeFrom((com.twine.tango.pmr.common.KeepAliveResponseOuterClass.KeepAliveResponse)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(com.twine.tango.pmr.common.KeepAliveResponseOuterClass.KeepAliveResponse other) { + if (other == com.twine.tango.pmr.common.KeepAliveResponseOuterClass.KeepAliveResponse.getDefaultInstance()) return this; + 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.common.KeepAliveResponseOuterClass.KeepAliveResponse parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (com.twine.tango.pmr.common.KeepAliveResponseOuterClass.KeepAliveResponse) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + 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.common.KeepAliveResponse) + } + + // @@protoc_insertion_point(class_scope:Tango.PMR.common.KeepAliveResponse) + private static final com.twine.tango.pmr.common.KeepAliveResponseOuterClass.KeepAliveResponse DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new com.twine.tango.pmr.common.KeepAliveResponseOuterClass.KeepAliveResponse(); + } + + public static com.twine.tango.pmr.common.KeepAliveResponseOuterClass.KeepAliveResponse getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser<KeepAliveResponse> + PARSER = new com.google.protobuf.AbstractParser<KeepAliveResponse>() { + public KeepAliveResponse parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new KeepAliveResponse(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser<KeepAliveResponse> parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser<KeepAliveResponse> getParserForType() { + return PARSER; + } + + public com.twine.tango.pmr.common.KeepAliveResponseOuterClass.KeepAliveResponse getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_Tango_PMR_common_KeepAliveResponse_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_Tango_PMR_common_KeepAliveResponse_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\027KeepAliveResponse.proto\022\020Tango.PMR.com" + + "mon\"\023\n\021KeepAliveResponseB\034\n\032com.twine.ta" + + "ngo.pmr.commonb\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_common_KeepAliveResponse_descriptor = + getDescriptor().getMessageTypes().get(0); + internal_static_Tango_PMR_common_KeepAliveResponse_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_Tango_PMR_common_KeepAliveResponse_descriptor, + new java.lang.String[] { }); + } + + // @@protoc_insertion_point(outer_class_scope) +} diff --git a/Software/Android_Studio/Tango.PMR/src/main/java/com/twine/tango/pmr/common/MessageTypeOuterClass.java b/Software/Android_Studio/Tango.PMR/src/main/java/com/twine/tango/pmr/common/MessageTypeOuterClass.java index c6aaf8d17..f2d42989a 100644 --- a/Software/Android_Studio/Tango.PMR/src/main/java/com/twine/tango/pmr/common/MessageTypeOuterClass.java +++ b/Software/Android_Studio/Tango.PMR/src/main/java/com/twine/tango/pmr/common/MessageTypeOuterClass.java @@ -179,6 +179,14 @@ public final class MessageTypeOuterClass { * <code>OverrideDataBaseResponse = 39;</code> */ OverrideDataBaseResponse(39), + /** + * <code>KeepAliveRequest = 40;</code> + */ + KeepAliveRequest(40), + /** + * <code>KeepAliveResponse = 41;</code> + */ + KeepAliveResponse(41), UNRECOGNIZED(-1), ; @@ -342,6 +350,14 @@ public final class MessageTypeOuterClass { * <code>OverrideDataBaseResponse = 39;</code> */ public static final int OverrideDataBaseResponse_VALUE = 39; + /** + * <code>KeepAliveRequest = 40;</code> + */ + public static final int KeepAliveRequest_VALUE = 40; + /** + * <code>KeepAliveResponse = 41;</code> + */ + public static final int KeepAliveResponse_VALUE = 41; public final int getNumber() { @@ -402,6 +418,8 @@ public final class MessageTypeOuterClass { case 37: return DirectSynchronizationResponse; case 38: return OverrideDataBaseRequest; case 39: return OverrideDataBaseResponse; + case 40: return KeepAliveRequest; + case 41: return KeepAliveResponse; default: return null; } } @@ -463,7 +481,7 @@ public final class MessageTypeOuterClass { descriptor; static { java.lang.String[] descriptorData = { - "\n\021MessageType.proto\022\020Tango.PMR.Common*\326\010" + + "\n\021MessageType.proto\022\020Tango.PMR.Common*\203\t" + "\n\013MessageType\022\007\n\003RGB\020\000\022\007\n\003Job\020\001\022\013\n\007Segme" + "nt\020\002\022\024\n\020CalculateRequest\020\003\022\025\n\021CalculateR" + "esponse\020\004\022\023\n\017ProgressRequest\020\005\022\024\n\020Progre" + @@ -491,8 +509,9 @@ public final class MessageTypeOuterClass { "lClientLoginResponse\020#\022 \n\034DirectSynchron" + "izationRequest\020$\022!\n\035DirectSynchronizatio" + "nResponse\020%\022\033\n\027OverrideDataBaseRequest\020&" + - "\022\034\n\030OverrideDataBaseResponse\020\'B\034\n\032com.tw" + - "ine.tango.pmr.commonb\006proto3" + "\022\034\n\030OverrideDataBaseResponse\020\'\022\024\n\020KeepAl" + + "iveRequest\020(\022\025\n\021KeepAliveResponse\020)B\034\n\032c", + "om.twine.tango.pmr.commonb\006proto3" }; com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = new com.google.protobuf.Descriptors.FileDescriptor. InternalDescriptorAssigner() { diff --git a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/main/MainActivityVM.java b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/main/MainActivityVM.java index 64d69b0e6..0357fee18 100644 --- a/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/main/MainActivityVM.java +++ b/Software/Android_Studio/Tango.Stubs.UI/src/main/java/com/twine/tango/stubs/ui/views/main/MainActivityVM.java @@ -2,6 +2,9 @@ package com.twine.tango.stubs.ui.views.main; import com.squareup.otto.Bus; import com.squareup.otto.Subscribe; +import com.twine.tango.dal.dao.TangoDAO; +import com.twine.tango.dal.entities.ActionType; +import com.twine.tango.dal.entities.Contact; import com.twine.tango.integration.operators.IMachineOperator; import com.twine.tango.integration.services.IExternalBridgeService; import com.twine.tango.integration.services.ISynchronizationService; @@ -16,6 +19,7 @@ import com.twine.tango.stubs.ui.views.main.IMainActivity.Navigation; import com.twine.tango.transport.TransportComponentState; import java.io.IOException; +import java.util.Random; import javax.inject.Inject; @@ -38,7 +42,6 @@ public class MainActivityVM extends ViewModelBase<IMainActivity> public RelayCommand disconnectCommand; - @Inject public MainActivityVM(Bus eventBus, INotificationProvider notificationProvider, INavigationProvider navigationProvider, IMachineOperator machineOperator, IExternalBridgeService externalBridgeService, ISynchronizationService synchronizationService) { @@ -52,33 +55,38 @@ public class MainActivityVM extends ViewModelBase<IMainActivity> isConnected = new DependencyProperty<>(false); - connectCommand = new RelayCommand(this::connect,() -> this.machineOperator.getState() != TransportComponentState.Connected); - disconnectCommand = new RelayCommand(this::disconnect,() -> this.machineOperator.getState() == TransportComponentState.Connected); + connectCommand = new RelayCommand(this::connect, () -> this.machineOperator.getState() != TransportComponentState.Connected); + disconnectCommand = new RelayCommand(this::disconnect, () -> this.machineOperator.getState() == TransportComponentState.Connected); this.machineOperator.addStateChangedListener((sender, e) -> isConnected.set(this.machineOperator.getState() == TransportComponentState.Connected)); - + try { externalBridgeService.start(); - } catch (IOException e) + } + catch (IOException e) { e.printStackTrace(); } + + Contact a = TangoDAO.getAllMachines().get(0).getOrganization().getContact(); + a.setPhoneNumber(String.valueOf(new Random().nextInt(1000))); + a.save().subscribe(); } private void connect() { machineOperator.connect().observeOn(AndroidSchedulers.mainThread()).subscribe(() -> - invalidateCommands(),(ex) -> - notificationProvider.showMessage(view,"Could not connect the Transporter.")); + invalidateCommands(), (ex) -> + notificationProvider.showMessage(view, "Could not connect the Transporter.")); } private void disconnect() { machineOperator.disconnect().observeOn(AndroidSchedulers.mainThread()).subscribe(() -> - invalidateCommands(),(ex) -> - notificationProvider.showMessage(view,"Could not disconnect the Transporter.")); + invalidateCommands(), (ex) -> + notificationProvider.showMessage(view, "Could not disconnect the Transporter.")); } @Subscribe diff --git a/Software/Android_Studio/Tango.Transport/src/main/java/com/twine/tango/transport/ITransporter.java b/Software/Android_Studio/Tango.Transport/src/main/java/com/twine/tango/transport/ITransporter.java index 1ad704829..82328ef18 100644 --- a/Software/Android_Studio/Tango.Transport/src/main/java/com/twine/tango/transport/ITransporter.java +++ b/Software/Android_Studio/Tango.Transport/src/main/java/com/twine/tango/transport/ITransporter.java @@ -16,7 +16,8 @@ import io.reactivex.Single; /** * Represents a transport component capable of sending and receiving {@link TangoMessage} on a collection of {@link ITransportAdapter}. */ -public interface ITransporter extends ITransportComponent { +public interface ITransporter extends ITransportComponent +{ /** * Gets the collection of adapters. @@ -33,7 +34,7 @@ public interface ITransporter extends ITransportComponent { * @param request the request * @return the single */ - <Request extends GeneratedMessageV3,Response extends GeneratedMessageV3> Single<TangoMessage<Response>> sendRequest(TangoMessage<Request> request); + <Request extends GeneratedMessageV3, Response extends GeneratedMessageV3> Single<TangoMessage<Response>> sendRequest(TangoMessage<Request> request); /** * Sends a request on the specified adapter. @@ -44,7 +45,30 @@ public interface ITransporter extends ITransportComponent { * @param adapter the adapter * @return the single */ - <Request extends GeneratedMessageV3,Response extends GeneratedMessageV3> Single<TangoMessage<Response>> sendRequest(TangoMessage<Request> request,ITransportAdapter adapter); + <Request extends GeneratedMessageV3, Response extends GeneratedMessageV3> Single<TangoMessage<Response>> sendRequest(TangoMessage<Request> request, ITransportAdapter adapter); + + /** + * Send a request to all adapters. + * + * @param <Request> the type parameter + * @param <Response> the type parameter + * @param request the request + * @param timeout the timeout + * @return the single + */ + <Request extends GeneratedMessageV3, Response extends GeneratedMessageV3> Single<TangoMessage<Response>> sendRequest(TangoMessage<Request> request, Period timeout); + + /** + * Sends a request on the specified adapter. + * + * @param <Request> the type parameter + * @param <Response> the type parameter + * @param request the request + * @param adapter the adapter + * @param timeout the timeout + * @return the single + */ + <Request extends GeneratedMessageV3, Response extends GeneratedMessageV3> Single<TangoMessage<Response>> sendRequest(TangoMessage<Request> request, ITransportAdapter adapter, Period timeout); /** * Sends a continuous request on all adapters. @@ -54,7 +78,7 @@ public interface ITransporter extends ITransportComponent { * @param request the request * @return the observable */ - <Request extends GeneratedMessageV3,Response extends GeneratedMessageV3> Observable<TangoMessage<Response>> sendContinuousRequest(TangoMessage<Request> request); + <Request extends GeneratedMessageV3, Response extends GeneratedMessageV3> Observable<TangoMessage<Response>> sendContinuousRequest(TangoMessage<Request> request); /** * Sends a continuous request on the specified adapter. @@ -65,7 +89,7 @@ public interface ITransporter extends ITransportComponent { * @param adapter the adapter * @return the observable */ - <Request extends GeneratedMessageV3,Response extends GeneratedMessageV3> Observable<TangoMessage<Response>> sendContinuousRequest(TangoMessage<Request> request, ITransportAdapter adapter); + <Request extends GeneratedMessageV3, Response extends GeneratedMessageV3> Observable<TangoMessage<Response>> sendContinuousRequest(TangoMessage<Request> request, ITransportAdapter adapter); /** * Sends a response. @@ -84,7 +108,7 @@ public interface ITransporter extends ITransportComponent { * @param token the token * @return the single */ - <Response extends GeneratedMessageV3> Completable sendResponse(TangoMessage<Response> response,String token); + <Response extends GeneratedMessageV3> Completable sendResponse(TangoMessage<Response> response, String token); /** * Sets request received listener. @@ -107,5 +131,46 @@ public interface ITransporter extends ITransportComponent { */ void setRequestTimeout(Period duration); + /** + * Sets a value indicating whether to use a keep alive mechanism. + * + * @param value the value + */ + void setUseKeepAlive(boolean value); + + /** + * Gets a value indicating whether to use a keep alive mechanism. + * + * @return the use keep alive + */ + boolean getUseKeepAlive(); + + /** + * Sets a value indicating whether the transporter should remove an adapter when it fails. + * + * @param value the value + */ + void setFailsWithAdapter(boolean value); + + /** + * Gets a value indicating whether the transporter should remove an adapter when it fails. + * + * @return the fails with adapter + */ + boolean getFailsWithAdapter(); + + /** + * Sets a value indicating whether the transporter should remove an adapter when it fails. + * + * @param value the value + */ + void setRemoveAdaptersOnFailed(boolean value); + + /** + * Gets a value indicating whether the transporter should remove an adapter when it fails. + * + * @return the remove adapters on fail + */ + boolean getRemoveAdaptersOnFail(); } diff --git a/Software/Android_Studio/Tango.Transport/src/main/java/com/twine/tango/transport/TransporterBase.java b/Software/Android_Studio/Tango.Transport/src/main/java/com/twine/tango/transport/TransporterBase.java index ff192bc3b..5b410d22c 100644 --- a/Software/Android_Studio/Tango.Transport/src/main/java/com/twine/tango/transport/TransporterBase.java +++ b/Software/Android_Studio/Tango.Transport/src/main/java/com/twine/tango/transport/TransporterBase.java @@ -15,7 +15,10 @@ import com.twine.tango.core.ObservableCollection; import com.twine.tango.pmr.MessageFactory; import com.twine.tango.pmr.TangoMessage; import com.twine.tango.pmr.common.ErrorCodeOuterClass.ErrorCode; +import com.twine.tango.pmr.common.KeepAliveRequestOuterClass.KeepAliveRequest; +import com.twine.tango.pmr.common.KeepAliveResponseOuterClass.KeepAliveResponse; import com.twine.tango.pmr.common.MessageContainerOuterClass.MessageContainer; +import com.twine.tango.pmr.common.MessageTypeOuterClass.MessageType; import org.joda.time.Period; @@ -47,10 +50,14 @@ public abstract class TransporterBase implements ITransporter private ConcurrentLinkedQueue<Pair<ITransportAdapter, byte[]>> arrivedResponses; private Thread pushThread; private Thread pullThread; + private Thread keepAliveThread; private ObservableCollection<ITransportAdapter> adapters; private Map<String, PendingResponse> pendingResponses; private TransportComponentState state; private Period requestTimeout; + private boolean useKeepAlive; + private boolean failsWithAdapter; + private boolean removeAdaptersOnFailed; //region Events @@ -117,6 +124,42 @@ public abstract class TransporterBase implements ITransporter this.requestTimeout = requestTimeout; } + @Override + public void setUseKeepAlive(boolean value) + { + useKeepAlive = value; + } + + @Override + public boolean getUseKeepAlive() + { + return useKeepAlive; + } + + @Override + public void setFailsWithAdapter(boolean value) + { + failsWithAdapter = value; + } + + @Override + public boolean getFailsWithAdapter() + { + return failsWithAdapter; + } + + @Override + public void setRemoveAdaptersOnFailed(boolean value) + { + removeAdaptersOnFailed = value; + } + + @Override + public boolean getRemoveAdaptersOnFail() + { + return removeAdaptersOnFailed; + } + //endregion //region Protected Methods @@ -154,12 +197,14 @@ public abstract class TransporterBase implements ITransporter private void onAdapterStateChanged(Object sender, TransportComponentState state) { - if (state == TransportComponentState.Disposed) + if (state == TransportComponentState.Failed && removeAdaptersOnFailed) { adapters.remove((ITransportAdapter) sender); - } else if (state == TransportComponentState.Failed) + } + + if (state == TransportComponentState.Failed && failsWithAdapter) { - //TODO: decide what to do here... + onFailed(new ObjectDisposedException("One of the transporter adapters has failed. Going into a failed state...")); } } @@ -323,7 +368,8 @@ public abstract class TransporterBase implements ITransporter XLog.i("Transporter connected..."); x.onComplete(); - } catch (Exception e) + } + catch (Exception e) { XLog.e("Error connecting transporter", e); x.onError(e); @@ -350,7 +396,8 @@ public abstract class TransporterBase implements ITransporter XLog.i("Transporter disconnected..."); x.onComplete(); - } catch (Exception e) + } + catch (Exception e) { x.onError(e); } @@ -361,12 +408,24 @@ public abstract class TransporterBase implements ITransporter @Override public <Request extends GeneratedMessageV3, Response extends GeneratedMessageV3> Single<TangoMessage<Response>> sendRequest(TangoMessage<Request> request) { - return sendRequest(request, null); + return sendRequest(request, null, getRequestTimeout()); } @Override public <Request extends GeneratedMessageV3, Response extends GeneratedMessageV3> Single<TangoMessage<Response>> sendRequest(TangoMessage<Request> request, ITransportAdapter adapter) { + return sendRequest(request, adapter, getRequestTimeout()); + } + + @Override + public <Request extends GeneratedMessageV3, Response extends GeneratedMessageV3> Single<TangoMessage<Response>> sendRequest(TangoMessage<Request> request, Period timeout) + { + return sendRequest(request, null, timeout); + } + + @Override + public <Request extends GeneratedMessageV3, Response extends GeneratedMessageV3> Single<TangoMessage<Response>> sendRequest(TangoMessage<Request> request, ITransportAdapter adapter, Period timeout) + { XLog.i("Queuing request message: " + request.getClass().getSimpleName() + " Token: " + request.getContainer().getToken() + " on adapter: " + (adapter != null ? adapter.getAddress() : "ALL")); XLog.i("Expected response: " + Response.Builder.class.getSimpleName()); @@ -442,16 +501,18 @@ public abstract class TransporterBase implements ITransporter { XLog.i("Removing matching request token..."); pendingResponses.remove(token); - } else if (response.getContainer().getCompleted()) + } + else if (response.getContainer().getCompleted()) { XLog.i("Response completed. Removing matching request token..."); pendingResponses.remove(token); } - } else + } + else { //This should never happen. XLog.w("Matching request token was not found..."); - throw new RuntimeException(); + throw new RuntimeException("There was no matching request token and this should never happen!"); } PublishSubject<Response> subject = PublishSubject.create(); @@ -474,6 +535,13 @@ public abstract class TransporterBase implements ITransporter pushThread = new Thread(this::pushThreadMethod); pushThread.setName("Push Thread"); pushThread.start(); + + if (useKeepAlive) + { + keepAliveThread = new Thread(this::keepAliveThreadMethod); + keepAliveThread.setName("Keep Alive Thread"); + keepAliveThread.start(); + } } /** @@ -522,7 +590,8 @@ public abstract class TransporterBase implements ITransporter XLog.i("message sent on adapter: " + adapter.getAddress() + "..."); } } - } else + } + else { if (message.getAdapter().getState() == TransportComponentState.Connected) { @@ -534,11 +603,13 @@ public abstract class TransporterBase implements ITransporter if (message.getDirection() == TransportMessageDirection.Request) { pendingRequests.add(message); - } else + } + else { message.setResult(new Object(), true); } - } catch (Exception ex) + } + catch (Exception ex) { message.setException(ex); } @@ -548,7 +619,8 @@ public abstract class TransporterBase implements ITransporter SystemClock.sleep(10); } - } catch (Exception ex) + } + catch (Exception ex) { onFailed(ex); } @@ -584,7 +656,8 @@ public abstract class TransporterBase implements ITransporter try { container = onParseContainer(data.second); - } catch (Exception e) + } + catch (Exception e) { XLog.e("Invalid message container received!", e); continue; @@ -609,17 +682,20 @@ public abstract class TransporterBase implements ITransporter { XLog.i("Response has returned with error: " + container.getError().toString()); request.setResult(onParseTangoMessage(data.second), true); - } else + } + else { XLog.i("Parsing inner response message and setting pending request task result..."); request.setException(new ResponseErrorException(container.getError(), onParseTangoMessage(data.second))); } - } catch (Exception ex) + } + catch (Exception ex) { XLog.e("Error parsing inner message", ex); request.setException(ex); } - } else + } + else { XLog.i("Pending request was identified as 'continuous response'. keeping pending request."); @@ -633,18 +709,21 @@ public abstract class TransporterBase implements ITransporter XLog.i("Continuous sequence completed."); } request.setResult(onParseTangoMessage(data.second), container.getCompleted()); - } else + } + else { XLog.i("Response has returned with error: " + container.getError().toString()); request.setException(new ResponseErrorException(container.getError(), onParseTangoMessage(data.second))); } - } catch (Exception ex) + } + catch (Exception ex) { XLog.e("Error parsing inner message", ex); request.setException(ex); } } - } else + } + else { XLog.i("Message was identified as a new request message: " + container.getType().toString()); @@ -652,9 +731,24 @@ public abstract class TransporterBase implements ITransporter { XLog.i("Saving request token and adapter: " + container.getToken() + ", " + data.first.getAddress()); pendingResponses.put(container.getToken(), new PendingResponse(data.first, container.getContinuous())); - XLog.i("Invoking RequestReceived event..."); - AsyncTask.execute(() -> onRequestReceived(container)); - } catch (Exception ex) + + if (container.getType() == MessageType.KeepAliveRequest) + { + XLog.i("Submitting keep alive response..."); + sendResponse(MessageFactory.createTangoMessage(KeepAliveResponse.class, container.getToken())).subscribe(() -> + { + }, (ex) -> + { + ex.printStackTrace(); + }); + } + else + { + XLog.i("Invoking RequestReceived event..."); + AsyncTask.execute(() -> onRequestReceived(container)); + } + } + catch (Exception ex) { //Ignore any exception that might occur on the event handler side... } @@ -665,7 +759,8 @@ public abstract class TransporterBase implements ITransporter SystemClock.sleep(10); } - } catch (Exception ex) + } + catch (Exception ex) { onFailed(ex); } @@ -673,6 +768,31 @@ public abstract class TransporterBase implements ITransporter //endregion + //region Keep Alive Thread + + private void keepAliveThreadMethod() + { + while (state == TransportComponentState.Connected) + { + + this.<KeepAliveRequest, KeepAliveResponse>sendRequest(MessageFactory.createTangoMessage(KeepAliveRequest.class), Period.seconds(10)).subscribe((x) -> + { + + }, (ex) -> + { + if (ex.getClass() == TimeoutException.class) + { + onFailed(new TimeoutException("The transporter has not received a KeepAlive response within the given time.")); + } + }); + + + SystemClock.sleep(10000); + } + } + + //endregion + //region Dispose @Override diff --git a/Software/DB/Tango.db b/Software/DB/Tango.db Binary files differindex f109086d7..d676fc8c3 100644 --- a/Software/DB/Tango.db +++ b/Software/DB/Tango.db diff --git a/Software/DB/Tango.mdf b/Software/DB/Tango.mdf Binary files differindex 9bc12005f..25f73c7e6 100644 --- a/Software/DB/Tango.mdf +++ b/Software/DB/Tango.mdf diff --git a/Software/DB/Tango_log.ldf b/Software/DB/Tango_log.ldf Binary files differindex 2c0e5ff09..3a4e11874 100644 --- a/Software/DB/Tango_log.ldf +++ b/Software/DB/Tango_log.ldf diff --git a/Software/PMR/Messages/Common/KeepAliveRequest.proto b/Software/PMR/Messages/Common/KeepAliveRequest.proto new file mode 100644 index 000000000..fb47ee43c --- /dev/null +++ b/Software/PMR/Messages/Common/KeepAliveRequest.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +package Tango.PMR.common; +option java_package = "com.twine.tango.pmr.common"; + +message KeepAliveRequest +{ + +}
\ No newline at end of file diff --git a/Software/PMR/Messages/Common/KeepAliveResponse.proto b/Software/PMR/Messages/Common/KeepAliveResponse.proto new file mode 100644 index 000000000..3a5f73f31 --- /dev/null +++ b/Software/PMR/Messages/Common/KeepAliveResponse.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +package Tango.PMR.common; +option java_package = "com.twine.tango.pmr.common"; + +message KeepAliveResponse +{ + +}
\ No newline at end of file diff --git a/Software/PMR/Messages/Common/MessageType.proto b/Software/PMR/Messages/Common/MessageType.proto index aed740ad1..e112ee510 100644 --- a/Software/PMR/Messages/Common/MessageType.proto +++ b/Software/PMR/Messages/Common/MessageType.proto @@ -45,4 +45,6 @@ enum MessageType DirectSynchronizationResponse = 37; OverrideDataBaseRequest = 38; OverrideDataBaseResponse = 39; + KeepAliveRequest = 40; + KeepAliveResponse = 41; } diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/ViewModels/DirectSynchronizationViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/ViewModels/DirectSynchronizationViewVM.cs index cfa21a416..7d21bb487 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/ViewModels/DirectSynchronizationViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/ViewModels/DirectSynchronizationViewVM.cs @@ -146,6 +146,8 @@ namespace Tango.MachineStudio.Synchronization.ViewModels #endregion + #region Private Methods + private void Compare() { if (SelectedMachine.SerialNumber != ApplicationManager.ConnectedMachine.SerialNumber) @@ -166,8 +168,9 @@ namespace Tango.MachineStudio.Synchronization.ViewModels InvalidateRelayCommands(); Thread.Sleep(1500); - ApplicationManager.ConnectedMachine.RequestTimeout = TimeSpan.FromSeconds(10); - var response = await ApplicationManager.ConnectedMachine.SendRequest<DirectSynchronizationRequest, DirectSynchronizationResponse>(new DirectSynchronizationRequest()); + ApplicationManager.ConnectedMachine.UseKeepAlive = false; + + var response = await ApplicationManager.ConnectedMachine.SendRequest<DirectSynchronizationRequest, DirectSynchronizationResponse>(new DirectSynchronizationRequest(), TimeSpan.FromSeconds(30)); using (_notification.PushTaskItem("Generating temporary files...")) { @@ -227,6 +230,7 @@ namespace Tango.MachineStudio.Synchronization.ViewModels IsWorking = false; SelectedDifference = null; InvalidateRelayCommands(); + ApplicationManager.ConnectedMachine.UseKeepAlive = true; } } }); @@ -254,6 +258,8 @@ namespace Tango.MachineStudio.Synchronization.ViewModels { try { + ApplicationManager.ConnectedMachine.UseKeepAlive = false; + IsWorking = true; InvalidateRelayCommands(); Thread.Sleep(1500); @@ -274,7 +280,7 @@ namespace Tango.MachineStudio.Synchronization.ViewModels var response = await ApplicationManager.ConnectedMachine.SendRequest<OverrideDataBaseRequest, OverrideDataBaseResponse>(new OverrideDataBaseRequest() { RemoteDB = ByteString.CopyFrom(remoteDbBytes) - }); + }, TimeSpan.FromSeconds(30)); if (!response.Message.Successful) { @@ -301,6 +307,7 @@ namespace Tango.MachineStudio.Synchronization.ViewModels IsWorking = false; SelectedDifference = null; InvalidateRelayCommands(); + ApplicationManager.ConnectedMachine.UseKeepAlive = true; } } }); @@ -315,5 +322,7 @@ namespace Tango.MachineStudio.Synchronization.ViewModels { InvokeUINow(() => _notification.ShowInfo(message)); } + + #endregion } } diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/StudioApplication/DefaultStudioApplicationManager.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/StudioApplication/DefaultStudioApplicationManager.cs index b0315e633..336681801 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/StudioApplication/DefaultStudioApplicationManager.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/StudioApplication/DefaultStudioApplicationManager.cs @@ -33,7 +33,27 @@ namespace Tango.MachineStudio.UI.StudioApplication public IExternalBridgeClient ConnectedMachine { get { return _connectedMachine; } - set { _connectedMachine = value; RaisePropertyChangedAuto(); RaisePropertyChanged(nameof(IsMachineConnected)); } + set + { + _connectedMachine = value; + RaisePropertyChangedAuto(); + RaisePropertyChanged(nameof(IsMachineConnected)); + + if (_connectedMachine != null) + { + _connectedMachine.StateChanged -= ConnectedMachine_StateChanged; + _connectedMachine.StateChanged += ConnectedMachine_StateChanged; + } + } + } + + private void ConnectedMachine_StateChanged(object sender, Transport.TransportComponentState e) + { + if (e == Transport.TransportComponentState.Disconnected || e == Transport.TransportComponentState.Failed) + { + ConnectedMachine = null; + } + } public bool IsMachineConnected diff --git a/Software/Visual_Studio/Tango.Integration/Services/ExternalBridgeClient.cs b/Software/Visual_Studio/Tango.Integration/Services/ExternalBridgeClient.cs index 1ecbf4c22..cdc176d73 100644 --- a/Software/Visual_Studio/Tango.Integration/Services/ExternalBridgeClient.cs +++ b/Software/Visual_Studio/Tango.Integration/Services/ExternalBridgeClient.cs @@ -63,6 +63,7 @@ namespace Tango.Integration.Services { SerialNumber = serialNumber; IPAddress = ipAddress; + UseKeepAlive = true; } } } diff --git a/Software/Visual_Studio/Tango.PMR/Common/KeepAliveRequest.cs b/Software/Visual_Studio/Tango.PMR/Common/KeepAliveRequest.cs new file mode 100644 index 000000000..0066665ae --- /dev/null +++ b/Software/Visual_Studio/Tango.PMR/Common/KeepAliveRequest.cs @@ -0,0 +1,131 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: KeepAliveRequest.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.Common { + + /// <summary>Holder for reflection information generated from KeepAliveRequest.proto</summary> + public static partial class KeepAliveRequestReflection { + + #region Descriptor + /// <summary>File descriptor for KeepAliveRequest.proto</summary> + public static pbr::FileDescriptor Descriptor { + get { return descriptor; } + } + private static pbr::FileDescriptor descriptor; + + static KeepAliveRequestReflection() { + byte[] descriptorData = global::System.Convert.FromBase64String( + string.Concat( + "ChZLZWVwQWxpdmVSZXF1ZXN0LnByb3RvEhBUYW5nby5QTVIuY29tbW9uIhIK", + "EEtlZXBBbGl2ZVJlcXVlc3RCHAoaY29tLnR3aW5lLnRhbmdvLnBtci5jb21t", + "b25iBnByb3RvMw==")); + descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, + new pbr::FileDescriptor[] { }, + new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { + new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.Common.KeepAliveRequest), global::Tango.PMR.Common.KeepAliveRequest.Parser, null, null, null, null) + })); + } + #endregion + + } + #region Messages + public sealed partial class KeepAliveRequest : pb::IMessage<KeepAliveRequest> { + private static readonly pb::MessageParser<KeepAliveRequest> _parser = new pb::MessageParser<KeepAliveRequest>(() => new KeepAliveRequest()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pb::MessageParser<KeepAliveRequest> Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pbr::MessageDescriptor Descriptor { + get { return global::Tango.PMR.Common.KeepAliveRequestReflection.Descriptor.MessageTypes[0]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public KeepAliveRequest() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public KeepAliveRequest(KeepAliveRequest other) : this() { + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public KeepAliveRequest Clone() { + return new KeepAliveRequest(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override bool Equals(object other) { + return Equals(other as KeepAliveRequest); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool Equals(KeepAliveRequest other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + return true; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override int GetHashCode() { + int hash = 1; + 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) { + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int CalculateSize() { + int size = 0; + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(KeepAliveRequest other) { + if (other == null) { + return; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + input.SkipLastField(); + break; + } + } + } + + } + + #endregion + +} + +#endregion Designer generated code diff --git a/Software/Visual_Studio/Tango.PMR/Common/KeepAliveResponse.cs b/Software/Visual_Studio/Tango.PMR/Common/KeepAliveResponse.cs new file mode 100644 index 000000000..47037c03e --- /dev/null +++ b/Software/Visual_Studio/Tango.PMR/Common/KeepAliveResponse.cs @@ -0,0 +1,131 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: KeepAliveResponse.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.Common { + + /// <summary>Holder for reflection information generated from KeepAliveResponse.proto</summary> + public static partial class KeepAliveResponseReflection { + + #region Descriptor + /// <summary>File descriptor for KeepAliveResponse.proto</summary> + public static pbr::FileDescriptor Descriptor { + get { return descriptor; } + } + private static pbr::FileDescriptor descriptor; + + static KeepAliveResponseReflection() { + byte[] descriptorData = global::System.Convert.FromBase64String( + string.Concat( + "ChdLZWVwQWxpdmVSZXNwb25zZS5wcm90bxIQVGFuZ28uUE1SLmNvbW1vbiIT", + "ChFLZWVwQWxpdmVSZXNwb25zZUIcChpjb20udHdpbmUudGFuZ28ucG1yLmNv", + "bW1vbmIGcHJvdG8z")); + descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, + new pbr::FileDescriptor[] { }, + new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { + new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.Common.KeepAliveResponse), global::Tango.PMR.Common.KeepAliveResponse.Parser, null, null, null, null) + })); + } + #endregion + + } + #region Messages + public sealed partial class KeepAliveResponse : pb::IMessage<KeepAliveResponse> { + private static readonly pb::MessageParser<KeepAliveResponse> _parser = new pb::MessageParser<KeepAliveResponse>(() => new KeepAliveResponse()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pb::MessageParser<KeepAliveResponse> Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pbr::MessageDescriptor Descriptor { + get { return global::Tango.PMR.Common.KeepAliveResponseReflection.Descriptor.MessageTypes[0]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public KeepAliveResponse() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public KeepAliveResponse(KeepAliveResponse other) : this() { + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public KeepAliveResponse Clone() { + return new KeepAliveResponse(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override bool Equals(object other) { + return Equals(other as KeepAliveResponse); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool Equals(KeepAliveResponse other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + return true; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override int GetHashCode() { + int hash = 1; + 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) { + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int CalculateSize() { + int size = 0; + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(KeepAliveResponse other) { + if (other == null) { + return; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + input.SkipLastField(); + break; + } + } + } + + } + + #endregion + +} + +#endregion Designer generated code diff --git a/Software/Visual_Studio/Tango.PMR/Common/MessageType.cs b/Software/Visual_Studio/Tango.PMR/Common/MessageType.cs index d5be47c1c..1fe2147c7 100644 --- a/Software/Visual_Studio/Tango.PMR/Common/MessageType.cs +++ b/Software/Visual_Studio/Tango.PMR/Common/MessageType.cs @@ -22,7 +22,7 @@ namespace Tango.PMR.Common { static MessageTypeReflection() { byte[] descriptorData = global::System.Convert.FromBase64String( string.Concat( - "ChFNZXNzYWdlVHlwZS5wcm90bxIQVGFuZ28uUE1SLkNvbW1vbirWCAoLTWVz", + "ChFNZXNzYWdlVHlwZS5wcm90bxIQVGFuZ28uUE1SLkNvbW1vbiqDCQoLTWVz", "c2FnZVR5cGUSBwoDUkdCEAASBwoDSm9iEAESCwoHU2VnbWVudBACEhQKEENh", "bGN1bGF0ZVJlcXVlc3QQAxIVChFDYWxjdWxhdGVSZXNwb25zZRAEEhMKD1By", "b2dyZXNzUmVxdWVzdBAFEhQKEFByb2dyZXNzUmVzcG9uc2UQBhIcChhTdHVi", @@ -47,7 +47,8 @@ namespace Tango.PMR.Common { "HwobRXh0ZXJuYWxDbGllbnRMb2dpblJlc3BvbnNlECMSIAocRGlyZWN0U3lu", "Y2hyb25pemF0aW9uUmVxdWVzdBAkEiEKHURpcmVjdFN5bmNocm9uaXphdGlv", "blJlc3BvbnNlECUSGwoXT3ZlcnJpZGVEYXRhQmFzZVJlcXVlc3QQJhIcChhP", - "dmVycmlkZURhdGFCYXNlUmVzcG9uc2UQJ0IcChpjb20udHdpbmUudGFuZ28u", + "dmVycmlkZURhdGFCYXNlUmVzcG9uc2UQJxIUChBLZWVwQWxpdmVSZXF1ZXN0", + "ECgSFQoRS2VlcEFsaXZlUmVzcG9uc2UQKUIcChpjb20udHdpbmUudGFuZ28u", "cG1yLmNvbW1vbmIGcHJvdG8z")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { }, @@ -98,6 +99,8 @@ namespace Tango.PMR.Common { [pbr::OriginalName("DirectSynchronizationResponse")] DirectSynchronizationResponse = 37, [pbr::OriginalName("OverrideDataBaseRequest")] OverrideDataBaseRequest = 38, [pbr::OriginalName("OverrideDataBaseResponse")] OverrideDataBaseResponse = 39, + [pbr::OriginalName("KeepAliveRequest")] KeepAliveRequest = 40, + [pbr::OriginalName("KeepAliveResponse")] KeepAliveResponse = 41, } #endregion diff --git a/Software/Visual_Studio/Tango.Transport/ITransporter.cs b/Software/Visual_Studio/Tango.Transport/ITransporter.cs index d2eb03e5e..178991abf 100644 --- a/Software/Visual_Studio/Tango.Transport/ITransporter.cs +++ b/Software/Visual_Studio/Tango.Transport/ITransporter.cs @@ -31,7 +31,7 @@ namespace Tango.Transport /// <typeparam name="Response">The type of the response.</typeparam> /// <param name="request">The request.</param> /// <returns></returns> - Task<TangoMessage<Response>> SendRequest<Request, Response>(TangoMessage<Request> request) where Request : IMessage<Request> where Response : IMessage<Response>; + Task<TangoMessage<Response>> SendRequest<Request, Response>(TangoMessage<Request> request, TimeSpan? timeout = null) where Request : IMessage<Request> where Response : IMessage<Response>; /// <summary> /// Sends a request through the specified adapter. @@ -41,7 +41,7 @@ namespace Tango.Transport /// <param name="request">The request.</param> /// <param name="adapter">Transport adapter</param> /// <returns></returns> - Task<TangoMessage<Response>> SendRequest<Request, Response>(TangoMessage<Request> request, ITransportAdapter adapter) where Request : IMessage<Request> where Response : IMessage<Response>; + Task<TangoMessage<Response>> SendRequest<Request, Response>(TangoMessage<Request> request, ITransportAdapter adapter, TimeSpan? timeout = null) where Request : IMessage<Request> where Response : IMessage<Response>; /// <summary> /// Sends a request through all adapters which is expected to return multiple response messages. @@ -80,7 +80,7 @@ namespace Tango.Transport /// <param name="response">The response.</param> /// <param name="token">The token.</param> /// <returns></returns> - Task SendResponse<Response>(TangoMessage<Response> response,String token) where Response : IMessage<Response>; + Task SendResponse<Response>(TangoMessage<Response> response, String token) where Response : IMessage<Response>; /// <summary> /// Occurs when a new request message has been received. @@ -88,11 +88,21 @@ namespace Tango.Transport event EventHandler<MessageContainer> RequestReceived; /// <summary> - /// Gets or sets the request timeout. + /// Gets or sets the default request timeout. /// </summary> TimeSpan RequestTimeout { get; set; } /// <summary> + /// Gets or sets a value indicating whether to use a keep alive mechanism. + /// </summary> + bool UseKeepAlive { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether the transporter will get in to a failed state if any adapter has failed. + /// </summary> + bool FailsWithAdapter { get; set; } + + /// <summary> /// Gets or sets a value indicating whether the transporter should remove an adapter when it fails. /// </summary> bool RemoveAdaptersOnFailed { get; set; } diff --git a/Software/Visual_Studio/Tango.Transport/Tango.Transport.csproj b/Software/Visual_Studio/Tango.Transport/Tango.Transport.csproj index 8aea62da8..aa5b5ef67 100644 --- a/Software/Visual_Studio/Tango.Transport/Tango.Transport.csproj +++ b/Software/Visual_Studio/Tango.Transport/Tango.Transport.csproj @@ -51,6 +51,7 @@ <Reference Include="System.Reactive.Windows.Threading, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL"> <HintPath>..\packages\System.Reactive.Windows.Threading.3.1.1\lib\net45\System.Reactive.Windows.Threading.dll</HintPath> </Reference> + <Reference Include="System.ServiceModel" /> <Reference Include="System.Windows" /> <Reference Include="System.Xml.Linq" /> <Reference Include="System.Data.DataSetExtensions" /> diff --git a/Software/Visual_Studio/Tango.Transport/TransporterBase.cs b/Software/Visual_Studio/Tango.Transport/TransporterBase.cs index b6f8ac529..547b11e7c 100644 --- a/Software/Visual_Studio/Tango.Transport/TransporterBase.cs +++ b/Software/Visual_Studio/Tango.Transport/TransporterBase.cs @@ -13,6 +13,7 @@ using Tango.Logging; using Tango.PMR; using Tango.PMR.Common; using System.Reactive.Linq; +using System.ServiceModel; namespace Tango.Transport { @@ -27,6 +28,7 @@ namespace Tango.Transport private ConcurrentQueue<KeyValuePair<ITransportAdapter, byte[]>> _arrivedResponses; private Thread _pushThread; private Thread _pullThread; + private Thread _keepAliveThread; private ObservableCollection<ITransportAdapter> _adapters; private Dictionary<String, PendingResponse> _pendingResponses; @@ -92,6 +94,33 @@ namespace Tango.Transport /// </summary> public bool RemoveAdaptersOnFailed { get; set; } + private bool _useKeepAlive; + /// <summary> + /// Gets or sets a value indicating whether to use a keep alive mechanism. + /// </summary> + public bool UseKeepAlive + { + get { return _useKeepAlive; } + set + { + _useKeepAlive = value; + + if (UseKeepAlive) + { + LogManager.Log("KeepAlive is now working..."); + } + else + { + LogManager.Log("KeepAlive is now shutdown."); + } + } + } + + /// <summary> + /// Gets or sets a value indicating whether the transporter will get in to a failed state if any adapter has failed. + /// </summary> + public bool FailsWithAdapter { get; set; } + #endregion #region Virtual Methods @@ -132,6 +161,11 @@ namespace Tango.Transport { Adapters.Remove(sender as ITransportAdapter); } + + if (e == TransportComponentState.Failed && FailsWithAdapter) + { + OnFailed(new CommunicationException("One of the transporter adapters has failed. Going into a failed state...")); + } } /// <summary> @@ -275,9 +309,9 @@ namespace Tango.Transport /// <typeparam name="Response">The type of the response.</typeparam> /// <param name="request">The request.</param> /// <returns></returns> - public Task<TangoMessage<Response>> SendRequest<Request, Response>(TangoMessage<Request> request) where Request : IMessage<Request> where Response : IMessage<Response> + public Task<TangoMessage<Response>> SendRequest<Request, Response>(TangoMessage<Request> request, TimeSpan? timeout = null) where Request : IMessage<Request> where Response : IMessage<Response> { - return SendRequest<Request, Response>(request, null); + return SendRequest<Request, Response>(request, null, timeout); } /// <summary> @@ -288,7 +322,7 @@ namespace Tango.Transport /// <param name="request">The request.</param> /// <param name="adapter">Transport adapter</param> /// <returns></returns> - public Task<TangoMessage<Response>> SendRequest<Request, Response>(TangoMessage<Request> request, ITransportAdapter adapter) where Request : IMessage<Request> where Response : IMessage<Response> + public Task<TangoMessage<Response>> SendRequest<Request, Response>(TangoMessage<Request> request, ITransportAdapter adapter, TimeSpan? timeout = null) where Request : IMessage<Request> where Response : IMessage<Response> { LogManager.Log("Queuing request message: " + typeof(Request).Name + " Token: " + request.Container.Token + " on adapter: " + (adapter != null ? adapter.Address : "ALL")); LogManager.Log("Expected response: " + typeof(Response).Name); @@ -296,11 +330,11 @@ namespace Tango.Transport TaskCompletionSource<TangoMessage<Response>> source = new TaskCompletionSource<TangoMessage<Response>>(); TransportMessage<TangoMessage<Response>> message = new TransportMessage<TangoMessage<Response>>(adapter, request.Container.Token, request, TransportMessageDirection.Request, OnSerializeingMessage(request), source); _sendingQueue.Enqueue(message); - Task.Delay(RequestTimeout).ContinueWith((x) => + Task.Delay(timeout != null ? timeout.Value : RequestTimeout).ContinueWith((x) => { if (!source.Task.IsCompleted) { - LogManager.Log("Request message: " + typeof(Request).Name + " had timed out after " + RequestTimeout.TotalSeconds + " seconds."); + LogManager.Log("Request message: " + typeof(Request).Name + " had timed out after " + (timeout != null ? timeout.Value.TotalSeconds : RequestTimeout.TotalSeconds) + " seconds."); LogManager.Log("Setting request task exception..."); source.SetException(new TimeoutException()); } @@ -421,6 +455,13 @@ namespace Tango.Transport _pushThread = new Thread(PushThreadMethod); _pushThread.IsBackground = true; _pushThread.Start(); + + if (UseKeepAlive) + { + _keepAliveThread = new Thread(KeepAliveThreadMethod); + _keepAliveThread.IsBackground = true; + _keepAliveThread.Start(); + } } #endregion @@ -574,8 +615,17 @@ namespace Tango.Transport { LogManager.Log("Saving request token and adapter: " + container.Token + ", " + data.Key.Address); _pendingResponses.Add(container.Token, new PendingResponse(data.Key, container.Continuous)); - LogManager.Log("Invoking RequestReceived event..."); - Task.Factory.StartNew(() => OnRequestReceived(container)); + + if (container.Type == MessageType.KeepAliveRequest) + { + LogManager.Log("Submitting keep alive response..."); + SendResponse<KeepAliveResponse>(new KeepAliveResponse(), container.Token); + } + else + { + LogManager.Log("Invoking RequestReceived event..."); + Task.Factory.StartNew(() => OnRequestReceived(container)); + } } catch { @@ -596,6 +646,53 @@ namespace Tango.Transport #endregion + #region Keep Alive Thread + + /// <summary> + /// Responsible for sending keep alive messages. + /// </summary> + private async void KeepAliveThreadMethod() + { + while (State == TransportComponentState.Connected) + { + try + { + Thread.Sleep(10000); + + if (UseKeepAlive) + { + var response = await SendRequest<KeepAliveRequest, KeepAliveResponse>(new KeepAliveRequest(), TimeSpan.FromSeconds(10)); + } + } + catch (TimeoutException) + { + if (State != TransportComponentState.Connected) return; + + if (UseKeepAlive) + { + OnFailed(new TimeoutException("The transporter has not received a KeepAlive response within the given time.")); + return; + } + } + catch (Exception ex) + { + if (State != TransportComponentState.Connected) return; + + if (UseKeepAlive) + { + OnFailed(ex); + return; + } + } + + if (State != TransportComponentState.Connected) return; + + if (State != TransportComponentState.Connected) return; + } + } + + #endregion + #region Dispose /// <summary> @@ -610,3 +707,4 @@ namespace Tango.Transport #endregion } } + |
