public static async Task<PublishPacket> ComposePublishPacketAsync(IChannelHandlerContext context, Message message,
            QualityOfService qos, string topicName)
        {
            bool duplicate = message.DeliveryCount > 0;

            var packet = new PublishPacket(qos, duplicate, false);
            packet.TopicName = topicName;
            if (qos > QualityOfService.AtMostOnce)
            {
                int packetId = unchecked((ushort)message.SequenceNumber);
                switch (qos)
                {
                    case QualityOfService.AtLeastOnce:
                        packetId &= 0x7FFF; // clear 15th bit
                        break;
                    case QualityOfService.ExactlyOnce:
                        packetId |= 0x8000; // set 15th bit
                        break;
                    default:
                        throw new ArgumentOutOfRangeException("qos", qos, null);
                }
                packet.PacketId = packetId;
            }
            using (Stream payloadStream = message.GetBodyStream())
            {
                long streamLength = payloadStream.Length;
                if (streamLength > int.MaxValue)
                {
                    throw new InvalidOperationException(string.Format("Message size ({0} bytes) is too big to process.", streamLength));
                }

                int length = (int)streamLength;
                IByteBuffer buffer = context.Channel.Allocator.Buffer(length, length);
                await buffer.WriteBytesAsync(payloadStream, length);
                Contract.Assert(buffer.ReadableBytes == length);

                packet.Payload = buffer;
            }
            return packet;
        }
        public MqttAdapter(
            Settings settings,
            ISessionStatePersistenceProvider sessionStateManager,
            IDeviceIdentityProvider authProvider,
            IQos2StatePersistenceProvider qos2StateProvider,
            MessagingBridgeFactoryFunc messagingBridgeFactory)
        {
            Contract.Requires(settings != null);
            Contract.Requires(sessionStateManager != null);
            Contract.Requires(authProvider != null);
            Contract.Requires(messagingBridgeFactory != null);

            this.lifetimeCancellation = new CancellationTokenSource();

            if (qos2StateProvider != null)
            {
                this.maxSupportedQosToClient = QualityOfService.ExactlyOnce;
                this.qos2StateProvider       = qos2StateProvider;
            }
            else
            {
                this.maxSupportedQosToClient = QualityOfService.AtLeastOnce;
            }

            this.settings               = settings;
            this.sessionStateManager    = sessionStateManager;
            this.authProvider           = authProvider;
            this.messagingBridgeFactory = messagingBridgeFactory;
        }
Example #3
0
 public ApplicationMessage(string topic, ReadOnlyMemory <byte> payload, QualityOfService qoS, bool retain)
 {
     Topic   = topic;
     Payload = payload;
     QoS     = qoS;
     Retain  = retain;
 }
Example #4
0
 /// <summary>
 /// Publishes a value to the MQTT broker
 /// </summary>
 /// <param name="ct">A token to abort the asynchronous operations</param>
 /// <param name="topic">The topic to which the messages has to be published</param>
 /// <param name="value">The value of the message</param>
 /// <param name="qos">The quality of service requested for this message</param>
 /// <param name="retain">Defines if the message should be retained or not</param>
 /// <returns>An asynchronous operation</returns>
 public async Task Publish(CancellationToken ct, string topic, string value, QualityOfService qos = QualityOfService.AtLeastOnce, bool retain = true)
 {
     using (var mqtt = Enable())
     {
         await mqtt.Publish(ct, topic, value, qos, retain);
     }
 }
Example #5
0
        public async Task PublishAsync(string topic, byte[] payload, QualityOfService qos = QualityOfService.AtMostOnce, bool retain = false)
        {
            TaskCompletionSource <object> future = new TaskCompletionSource <object>();
            PublishPacket packet = new PublishPacket(qos, false, retain);

            packet.TopicName = topic;
            packet.PacketId  = PacketIdProvider.NewPacketId();
            packet.Payload   = Unpooled.WrappedBuffer(payload);
            packet.Retain();
            WriteResult result = await sendAndFlushAsync(packet);

            if (!result.Success)
            {
                packet.Release();//needed?
                future.SetException(result.Exception);
            }
            else if (qos == QualityOfService.AtLeastOnce)
            {
                packet.Release();       //needed?
                future.SetResult(null); //We don't get an ACK for QOS 0
            }
            else
            {
                PendingPublish pendingPublish = new PendingPublish(packet, future);//return after PubAct(QoS=1)/PubRel(QoS=2) received.
                pendingPublishes.TryAdd(packet.PacketId, pendingPublish);
                pendingPublish.RetransmitPublish(eventLoopGroup.GetNext(), sendAndFlushAsync);
            }
            await future.Task;
        }
Example #6
0
        public IAsyncAction PublishStringAsync(string topic, string payload, QualityOfService qos, int messageId, bool retain)
        {
            // Encode the string into a byte array
            byte[] utf8Str = Encoding.UTF8.GetBytes(payload);

            return(PublishAsync(topic, utf8Str, qos, messageId, retain));
        }
        public static PublishPacket ComposePublishPacket(IChannelHandlerContext context, IMessage message,
                                                         QualityOfService qos, IByteBufferAllocator allocator)
        {
            bool duplicate = message.DeliveryCount > 0;

            var packet = new PublishPacket(qos, duplicate, false);

            packet.TopicName = message.Address;
            if (qos > QualityOfService.AtMostOnce)
            {
                int packetId = unchecked ((int)message.SequenceNumber) & 0x3FFF; // clear bits #14 and #15
                switch (qos)
                {
                case QualityOfService.AtLeastOnce:
                    break;

                case QualityOfService.ExactlyOnce:
                    packetId |= 0x8000;     // set bit #15
                    break;

                default:
                    throw new ArgumentOutOfRangeException(nameof(qos), qos, null);
                }
                packet.PacketId = packetId + 1;
            }
            message.Payload.Retain();
            packet.Payload = message.Payload;
            return(packet);
        }
 /// <summary>
 /// Instantiate a new <see cref="OutgoingMessage"/>.
 /// </summary>
 /// <param name="retain">The retain flag.</param>
 /// <param name="topic">The message topic.</param>
 /// <param name="qos">The message qos.</param>
 protected OutgoingMessage(
     string topic, QualityOfService qos, bool retain,
     string?responseTopic = null, ushort correlationDataSize = 0, SpanAction?correlationDataWriter = null
     ) //properties
 {
     //Compute properties size.
     if (responseTopic != null)
     {
         _propertiesLength += 1 + responseTopic.MQTTSize();
     }
     if (correlationDataSize > 0 || correlationDataWriter != null)
     {
         if (correlationDataSize == 0 && correlationDataWriter != null)
         {
             throw new ArgumentException($"{nameof( correlationDataSize )} is 0 but {nameof( correlationDataWriter )} is not null. If no data will be written, don't set the writer.");
         }
         if (correlationDataWriter == null && correlationDataSize > 0)
         {
             throw new ArgumentException($"You set a {nameof( correlationDataSize )} but the {nameof( correlationDataWriter )} is null.");
         }
         _propertiesLength += 1 + correlationDataSize + 2;/*2 to write the data size itself*/
     }
     //Assignation
     _retain                = retain;
     _topic                 = topic;
     Qos                    = qos;
     _responseTopic         = responseTopic;
     _correlationDataSize   = correlationDataSize;
     _correlationDataWriter = correlationDataWriter;
 }
        public static SubAckPacket AddSubscriptions(ISessionState session, SubscribePacket packet, QualityOfService maxSupportedQos)
        {
            List <Subscription> subscriptions = session.Subscriptions;
            var returnCodes = new List <QualityOfService>(subscriptions.Count);

            foreach (SubscriptionRequest request in packet.Requests)
            {
                Subscription existingSubscription = null;
                for (int i = subscriptions.Count - 1; i >= 0; i--)
                {
                    Subscription subscription = subscriptions[i];
                    if (subscription.TopicFilter.Equals(request.TopicFilter, StringComparison.Ordinal))
                    {
                        subscriptions.RemoveAt(i);
                        existingSubscription = subscription;
                        break;
                    }
                }

                QualityOfService finalQos = request.QualityOfService < maxSupportedQos ? request.QualityOfService : maxSupportedQos;

                subscriptions.Add(existingSubscription == null
                    ? new Subscription(request.TopicFilter, request.QualityOfService)
                    : existingSubscription.CreateUpdated(finalQos));

                returnCodes.Add(finalQos);
            }
            var ack = new SubAckPacket
            {
                PacketId    = packet.PacketId,
                ReturnCodes = returnCodes
            };

            return(ack);
        }
Example #10
0
        /// <summary>实例化</summary>
        /// <param name="topicFilter"></param>
        /// <param name="qualityOfService"></param>
        public Subscription(String topicFilter, QualityOfService qualityOfService)
        {
            Contract.Requires(!String.IsNullOrEmpty(topicFilter));

            TopicFilter      = topicFilter;
            QualityOfService = qualityOfService;
        }
        bool TryMatchSubscription(string topicName, DateTime messageTime, out QualityOfService qos)
        {
            bool found = false;

            qos = QualityOfService.AtMostOnce;
            IReadOnlyList <ISubscription> subscriptions = this.sessionState.Subscriptions;

            for (int i = 0; i < subscriptions.Count; i++)
            {
                ISubscription subscription = subscriptions[i];
                if ((!found || subscription.QualityOfService > qos) &&
                    subscription.CreationTime <= messageTime &&
                    Util.CheckTopicFilterMatch(topicName, subscription.TopicFilter))
                {
                    found = true;
                    qos   = subscription.QualityOfService;
                    if (qos >= this.maxSupportedQosToClient)
                    {
                        qos = this.maxSupportedQosToClient;
                        break;
                    }
                }
            }
            return(found);
        }
        public MqttIotHubAdapter(Settings settings, DeviceClientFactoryFunc deviceClientFactory, ISessionStatePersistenceProvider sessionStateManager, IAuthenticationProvider authProvider,
            ITopicNameRouter topicNameRouter, IQos2StatePersistenceProvider qos2StateProvider)
        {
            Contract.Requires(settings != null);
            Contract.Requires(sessionStateManager != null);
            Contract.Requires(authProvider != null);
            Contract.Requires(topicNameRouter != null);

            if (qos2StateProvider != null)
            {
                this.maxSupportedQosToClient = QualityOfService.ExactlyOnce;
                this.qos2StateProvider = qos2StateProvider;
            }
            else
            {
                this.maxSupportedQosToClient = QualityOfService.AtLeastOnce;
            }

            this.settings = settings;
            this.deviceClientFactory = deviceClientFactory;
            this.sessionStateManager = sessionStateManager;
            this.authProvider = authProvider;
            this.topicNameRouter = topicNameRouter;

            this.publishProcessor = new PacketAsyncProcessor<PublishPacket>(this.PublishToServerAsync);
            this.publishProcessor.Completion.OnFault(ShutdownOnPublishToServerFaultAction);

            TimeSpan? ackTimeout = this.settings.DeviceReceiveAckCanTimeout ? this.settings.DeviceReceiveAckTimeout : (TimeSpan?)null;
            this.publishPubAckProcessor = new RequestAckPairProcessor<AckPendingMessageState, PublishPacket>(this.AcknowledgePublishAsync, this.RetransmitNextPublish, ackTimeout);
            this.publishPubAckProcessor.Completion.OnFault(ShutdownOnPubAckFaultAction);
            this.publishPubRecProcessor = new RequestAckPairProcessor<AckPendingMessageState, PublishPacket>(this.AcknowledgePublishReceiveAsync, this.RetransmitNextPublish, ackTimeout);
            this.publishPubRecProcessor.Completion.OnFault(ShutdownOnPubRecFaultAction);
            this.pubRelPubCompProcessor = new RequestAckPairProcessor<CompletionPendingMessageState, PubRelPacket>(this.AcknowledgePublishCompleteAsync, this.RetransmitNextPublishRelease, ackTimeout);
            this.pubRelPubCompProcessor.Completion.OnFault(ShutdownOnPubCompFaultAction);
        }
Example #13
0
        async void Connect(IChannelHandlerContext context)
        {
            var connectPacket = new ConnectPacket
            {
                ClientId           = this.deviceId,
                HasUsername        = true,
                Username           = this.iotHubHostName + "/" + this.deviceId,
                HasPassword        = true,
                Password           = this.password,
                KeepAliveInSeconds = this.mqttTransportSettings.KeepAliveInSeconds,
                CleanSession       = this.mqttTransportSettings.CleanSession,
                HasWill            = this.mqttTransportSettings.HasWill
            };

            if (connectPacket.HasWill)
            {
                Message          message            = this.willMessage.Message;
                QualityOfService publishToServerQoS = this.mqttTransportSettings.PublishToServerQoS;
                string           topicName          = string.Format(TelemetryTopicFormat, this.deviceId);
                PublishPacket    will = await Util.ComposePublishPacketAsync(context, message, publishToServerQoS, topicName);

                connectPacket.WillMessage          = will.Payload;
                connectPacket.WillQualityOfService = this.willMessage.QoS;
                connectPacket.WillRetain           = false;
                connectPacket.WillTopicName        = will.TopicName;
            }
            this.stateFlags = StateFlags.Connecting;

            await Util.WriteMessageAsync(context, connectPacket, ShutdownOnWriteErrorHandler);

            this.lastChannelActivityTime = DateTime.UtcNow;
            this.ScheduleKeepConnectionAlive(context);

            this.ScheduleCheckConnectTimeout(context);
        }
Example #14
0
        public SubscriptionRequest(string topicFilter, QualityOfService qualityOfService)
        {
            Contract.Requires(!string.IsNullOrEmpty(topicFilter));

            this.TopicFilter      = topicFilter;
            this.QualityOfService = qualityOfService;
        }
Example #15
0
        public async void TestPublishQos(QualityOfService qos)
        {
            var msg = "学无先后达者为师" + Rand.NextString(8);
            var rs  = await _client.PublishAsync("QosTopic", msg, qos);

            switch (qos)
            {
            case QualityOfService.AtMostOnce:
                Assert.Null(rs);
                break;

            case QualityOfService.AtLeastOnce:
                var ack = rs as PubAck;
                Assert.NotNull(ack);
                Assert.NotEqual(0, rs.Id);
                break;

            case QualityOfService.ExactlyOnce:
                //var rec = rs as PubRec;
                //Assert.NotNull(rec);
                var cmp = rs as PubComp;
                Assert.NotNull(cmp);
                Assert.NotEqual(0, rs.Id);
                break;
            }
        }
 public PublishedDataReceivedEventArgs(dynamic data, bool dupFlag, bool retain, QualityOfService qosLevel)
 {
     Data = data;
     DupFlag = dupFlag;
     Retain = retain;
     QosLevel = qosLevel;
 }
Example #17
0
 /// <summary>
 /// This constructor is used when DiscoveredData is being created from scratch
 /// </summary>
 /// <param name="typeNameType name of the dataparam>
 /// <param name="topicName">name of the topic</param>
 /// <param name="key">guid of the remote entity, which acts as a key for topic</param>
 /// <param name="qos">QualityOfService of discovered entity</param>
 protected DiscoveredData(String typeName, String topicName, Guid key, QualityOfService qos)
 {
     this.typeName = typeName;
     this.topicName = topicName;
     this.key = key;
     this.qos = qos;
 }
Example #18
0
        private static void BufferUsageExample(Initiator initiator, Service service, QualityOfService qualityOfService, ClientServerMessageBus bus, List <Key> newKeys)
        {
            bus.Send(initiator, new MoreBitsArrived(newKeys));
            bus.Send(service, new MoreBitsArrived(newKeys));

            bus.Send(initiator, new Initiate());

            bus.Send(initiator, new CreateKeyBuffer("app1.in", qualityOfService));
            bus.Send(initiator, new CreateKeyBuffer("app1.out", qualityOfService));

            bus.Send(service, new CreateKeyBuffer("app1.in", qualityOfService));
            bus.Send(service, new CreateKeyBuffer("app1.out", qualityOfService));

            bus.Send(initiator, new MoreBitsArrived(newKeys));
            bus.Send(service, new MoreBitsArrived(newKeys));

            bus.Send(initiator, new Initiate());

            bus.Send(initiator, new CloseKeyBuffer("app1.in"));
            bus.Send(service, new CloseKeyBuffer("app1.in"));

            bus.Send(initiator, new GetOutBufferKey("app1.out", 128));


            bus.Send(service, new GetOutBufferKey("app1.out", 128));
        }
Example #19
0
        internal MqttTransportHandler(IotHubConnectionString iotHubConnectionString, MqttTransportSettings settings, Func <IPAddress, int, Task <IChannel> > channelFactory)
            : base(settings)
        {
            this.mqttIotHubAdapterFactory = new MqttIotHubAdapterFactory(settings);
            this.messageQueue             = new ConcurrentQueue <Message>();
            this.completionQueue          = new Queue <string>();
            this.serverAddress            = Dns.GetHostEntry(iotHubConnectionString.HostName).AddressList[0];
            this.qos = settings.PublishToServerQoS;
            this.eventLoopGroupKey = iotHubConnectionString.IotHubName + "#" + iotHubConnectionString.DeviceId + "#" + iotHubConnectionString.Audience;

            if (channelFactory == null)
            {
                switch (settings.GetTransportType())
                {
                case TransportType.Mqtt_Tcp_Only:
                    this.channelFactory = this.CreateChannelFactory(iotHubConnectionString, settings);
                    break;

                case TransportType.Mqtt_WebSocket_Only:
                    this.channelFactory = this.CreateWebSocketChannelFactory(iotHubConnectionString, settings);
                    break;

                default:
                    throw new InvalidOperationException("Unsupported Transport Setting {0}".FormatInvariant(settings.GetTransportType()));
                }
            }
            else
            {
                this.channelFactory = channelFactory;
            }

            this.closeRetryPolicy = new RetryPolicy(new TransientErrorIgnoreStrategy(), 5, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1));
        }
 public BasicOutgoingApplicationMessage(
     string topic, QualityOfService qos, bool retain, Func <int> getPayloadSize, PayloadWriterDelegate payloadWriter,
     string?responseTopic = null, ushort correlationDataSize = 0, SpanAction?correlationDataWriter = null)    //Properties
     : base(topic, qos, retain, responseTopic, correlationDataSize, correlationDataWriter)
 {
     _getPayloadSize = getPayloadSize;
     _payloadWriter  = payloadWriter;
 }
 public AckPendingMessageState(string messageId, int packetId, QualityOfService qualityOfService, string lockToken)
 {
     this.MessageId        = messageId;
     this.PacketId         = packetId;
     this.QualityOfService = qualityOfService;
     this.LockToken        = lockToken;
     this.SentTime         = DateTime.UtcNow;
     this.StartTimestamp   = PreciseTimeSpan.FromStart;
 }
 public AckPendingMessageState(string messageId, int packetId, QualityOfService qualityOfService, string lockToken)
 {
     this.MessageId = messageId;
     this.PacketId = packetId;
     this.QualityOfService = qualityOfService;
     this.LockToken = lockToken;
     this.SentTime = DateTime.UtcNow;
     this.StartTimestamp = PreciseTimeSpan.FromStart;
 }
Example #23
0
            public Task Publish(CancellationToken ct, string topic, string value, QualityOfService qos, bool retain)
            {
                this.Log().Info($"Publishing ({(retain?"retained": "volatile")}) message to topic '{topic}': {value}");

                var message = new MqttApplicationMessage(topic, Encoding.UTF8.GetBytes(value), retain);

                Task Send(IMqttClient client) => client.PublishAsync(message, (MqttQualityOfService)qos, retain);

                return(UsingCurrentClient(ct, _sendMessageTries, Send, "publishing message on topic " + topic));
            }
Example #24
0
        public SubscriptionRequest(string topicFilter, QualityOfService qualityOfService)
        {
            if (string.IsNullOrEmpty(topicFilter))
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.topicFilter);
            }

            TopicFilter      = topicFilter;
            QualityOfService = qualityOfService;
        }
Example #25
0
        public IAsyncAction PublishUIntAsync(string topic, UInt16 payload, QualityOfService qos, int messageId, bool retain)
        {
            // Encode the uint into a byte array
            int pos          = 0;
            var payloadBytes = new byte[2];

            Frame.EncodeInt16(payload, payloadBytes, ref pos);

            return(PublishAsync(topic, payloadBytes, qos, messageId, retain));
        }
Example #26
0
        /// <summary>
        /// Notify the specified representation and qos.
        /// </summary>
        /// <since_tizen> 3 </since_tizen>
        /// <privilege>http://tizen.org/privilege/internet</privilege>
        /// <privlevel>public</privlevel>
        /// <param name="representation">Representation.</param>
        /// <param name="qos">The quality of service for message transfer.</param>
        /// <feature>http://tizen.org/feature/iot.ocf</feature>
        /// <pre>
        /// IoTConnectivityServerManager.Initialize() should be called to initialize.
        /// </pre>
        /// <seealso cref="Representation"/>
        /// <seealso cref="QualityOfService"/>
        /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported.</exception>
        /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have privilege to access.</exception>
        /// <exception cref="InvalidOperationException">Thrown when the operation is invalid.</exception>
        /// <example><code><![CDATA[
        /// ResourceInterfaces ifaces = new ResourceInterfaces(new List<string>(){ ResourceInterfaces.DefaultInterface });
        /// ResourceTypes types = new ResourceTypes(new List<string>(){ "oic.iot.door.new.notify" });
        /// Resource resource = new DoorResource("/door/uri/new/notify", types, ifaces, ResourcePolicy.Discoverable | ResourcePolicy.Observable);
        /// IoTConnectivityServerManager.RegisterResource(resource);
        ///
        /// Representation repr = new Representation();
        /// repr.UriPath = "/door/uri/new/notify";
        /// repr.Type = new ResourceTypes(new List<string>(){ "oic.iot.door.new.notify" });
        /// repr.Attributes = new Attributes() {
        ///      _attribute, 1 }
        /// };
        /// resource.Notify(repr, QualityOfService.High);
        /// ]]></code></example>
        public void Notify(Representation representation, QualityOfService qos)
        {
            int ret = (int)IoTConnectivityError.None;

            ret = Interop.IoTConnectivity.Server.Resource.Notify(_resourceHandle, representation._representationHandle, _observerHandle, (int)qos);
            if (ret != (int)IoTConnectivityError.None)
            {
                Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to send notification");
                throw IoTConnectivityErrorFactory.GetException(ret);
            }
        }
Example #27
0
 internal MqttTransportHandler(IotHubConnectionString iotHubConnectionString, MqttTransportSettings settings, Func <IPAddress, int, Task <IChannel> > channelFactory)
     : base(settings)
 {
     this.mqttIotHubAdapterFactory = new MqttIotHubAdapterFactory(settings);
     this.messageQueue             = new ConcurrentQueue <Message>();
     this.completionQueue          = new Queue <string>();
     this.serverAddress            = Dns.GetHostEntry(iotHubConnectionString.HostName).AddressList[0];
     this.qos = settings.PublishToServerQoS;
     this.eventLoopGroupKey = iotHubConnectionString.IotHubName + "#" + iotHubConnectionString.DeviceId + "#" + iotHubConnectionString.Audience;
     this.channelFactory    = channelFactory ?? this.CreateChannelFactory(iotHubConnectionString, settings);
     this.closeRetryPolicy  = new RetryPolicy(new TransientErrorIgnoreStrategy(), 5, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1));
 }
 public TestSendingLinkHandler(
     IIdentity identity,
     ISendingAmqpLink link,
     Uri requestUri,
     IDictionary <string, string> boundVariables,
     IConnectionHandler connectionHandler,
     IMessageConverter <AmqpMessage> messageConverter,
     QualityOfService qualityOfService)
     : base(identity, link, requestUri, boundVariables, connectionHandler, messageConverter)
 {
     this.QualityOfService = qualityOfService;
 }
        async void Connect(IChannelHandlerContext context)
        {
            try
            {
                string id       = string.IsNullOrWhiteSpace(this.moduleId) ? this.deviceId : $"{this.deviceId}/{this.moduleId}";
                string password = null;
                if (this.passwordProvider != null)
                {
                    password = await this.passwordProvider.GetPasswordAsync().ConfigureAwait(false);
                }
                else
                {
                    Debug.Assert(this.mqttTransportSettings.ClientCertificate != null);
                }

                var connectPacket = new ConnectPacket
                {
                    ClientId           = id,
                    HasUsername        = true,
                    Username           = $"{this.iotHubHostName}/{id}/?api-version={ClientApiVersionHelper.ApiVersionString}&DeviceClientType={Uri.EscapeDataString(this.productInfo.ToString())}",
                    HasPassword        = !string.IsNullOrEmpty(password),
                    Password           = password,
                    KeepAliveInSeconds = this.mqttTransportSettings.KeepAliveInSeconds,
                    CleanSession       = this.mqttTransportSettings.CleanSession,
                    HasWill            = this.mqttTransportSettings.HasWill
                };
                if (connectPacket.HasWill)
                {
                    Message          message            = this.willMessage.Message;
                    QualityOfService publishToServerQoS = this.mqttTransportSettings.PublishToServerQoS;
                    string           topicName          = this.GetTelemetryTopicName();
                    PublishPacket    will = await Util.ComposePublishPacketAsync(context, message, publishToServerQoS, topicName).ConfigureAwait(false);

                    connectPacket.WillMessage          = will.Payload;
                    connectPacket.WillQualityOfService = this.willMessage.QoS;
                    connectPacket.WillRetain           = false;
                    connectPacket.WillTopicName        = will.TopicName;
                }
                this.stateFlags = StateFlags.Connecting;

                await Util.WriteMessageAsync(context, connectPacket, ShutdownOnWriteErrorHandler).ConfigureAwait(false);

                this.lastChannelActivityTime = DateTime.UtcNow;
                this.ScheduleKeepConnectionAlive(context);

                this.ScheduleCheckConnectTimeout(context);
            }
            catch (Exception ex) when(!ex.IsFatal())
            {
                ShutdownOnError(context, ex);
            }
        }
Example #30
0
        public Task PublishAsync(string topic, byte[] payload, QualityOfService qos, int messageId, bool retain)
        {
            var msgBuilder = new MqttPublishMessageBuilder
            {
                MessageId        = messageId,
                TopicName        = topic,
                QualityOfService = qos,
                Retain           = retain,
                Payload          = payload
            };

            return(SendMessageAsync(msgBuilder));
        }
        public void AddOrUpdateSubscription(string topicFilter, QualityOfService qos)
        {
            int index = this.FindSubscriptionIndex(topicFilter);

            if (index >= 0)
            {
                this.subscriptions[index] = this.subscriptions[index].CreateUpdated(qos);
            }
            else
            {
                this.subscriptions.Add(new Subscription(topicFilter, qos));
            }
        }
Example #32
0
        public void AddOrUpdateSubscription(string topicFilter, QualityOfService qos)
        {
            int index = this.FindSubscriptionIndex(topicFilter);

            if (index >= 0)
            {
                this.subscriptions[index] = this.subscriptions[index].CreateUpdated(qos);
            }
            else
            {
                this.subscriptions.Add(new Subscription(topicFilter, qos));
            }
        }
Example #33
0
        public Task Publish(string topic, string message, QualityOfService qos, Action <MqttCommand> completed)
        {
            var pub = new Publish(topic, message);

            pub.Header.QualityOfService = qos;
            if (qos != QualityOfService.AtMostOnce)
            {
                pub.MessageId = _idSeq.Next();
            }

            var publish = new PublishSendFlow(_manager);

            return(publish.Start(pub, completed));
        }
Example #34
0
        public Transmitter(string transmitterId)
        {
            if (transmitterId == null || transmitterId == "")
            {
                throw new ArgumentException("Transmitter ID cannot be null or empty");
            }

            _client = new MqttClient("mqtt.relayr.io");
            _client.MqttMsgPublishReceived += _client_MqttMsgPublishReceived;
            
            _connectedDevices = new Dictionary<string, Device>();
            DefaultQualityOfService = QualityOfService.AtLeastOnce;

            _transmitterId = transmitterId;
        }
Example #35
0
            /// <summary>
            ///     Creates a channel config for round robin dispatching
            /// </summary>
            /// <param name="count">message count to distribute evenly</param>
            /// <returns>channel configuration</returns>
            public static ChannelConfiguration RoundRobinDispatchChannel(ushort count)
            {
                var qos = new QualityOfService
                {
                    PreFetchCount  = count,
                    PreFetchSize   = 0,
                    PreFetchGlobal = false,
                };

                return(new ChannelConfiguration
                {
                    Mode = ChannelMode.None,
                    QualityOfService = qos,
                });
            }
 internal AvailableNetworkSession(
     int numGamers,
     string host,
     int privateSlots,
     int publicSlots,
     NetworkSessionProperties properties,
     QualityOfService qos
     )
 {
     CurrentGamerCount     = numGamers;
     HostGamertag          = host;
     OpenPrivateGamerSlots = privateSlots;
     OpenPublicGamerSlots  = publicSlots;
     SessionProperties     = properties;
     QualityOfService      = qos;
 }
Example #37
0
        internal MqttTransportHandler(
            IPipelineContext context,
            IotHubConnectionString iotHubConnectionString,
            MqttTransportSettings settings,
            Func <IPAddress[], int, Task <IChannel> > channelFactory,
            Action <object, ConnectionEventArgs> onConnectionOpenedCallback,
            Func <object, ConnectionEventArgs, Task> onConnectionClosedCallback)
            : base(context, settings)
        {
            this.connectionOpenedListener = onConnectionOpenedCallback;
            this.connectionClosedListener = onConnectionClosedCallback;

            this.mqttIotHubAdapterFactory = new MqttIotHubAdapterFactory(settings);
            this.messageQueue             = new ConcurrentQueue <Message>();
            this.completionQueue          = new Queue <string>();

            this.serverAddresses           = null; // this will be resolved asynchronously in OpenAsync
            this.hostName                  = iotHubConnectionString.HostName;
            this.receiveEventMessageFilter = string.Format(CultureInfo.InvariantCulture, receiveEventMessagePatternFilter, iotHubConnectionString.DeviceId, iotHubConnectionString.ModuleId);
            this.receiveEventMessagePrefix = string.Format(CultureInfo.InvariantCulture, receiveEventMessagePrefixPattern, iotHubConnectionString.DeviceId, iotHubConnectionString.ModuleId);

            this.qos = settings.PublishToServerQoS;
            this.eventLoopGroupKey = iotHubConnectionString.IotHubName + "#" + iotHubConnectionString.DeviceId + "#" + iotHubConnectionString.Audience;

            if (channelFactory == null)
            {
                switch (settings.GetTransportType())
                {
                case TransportType.Mqtt_Tcp_Only:
                    this.channelFactory = this.CreateChannelFactory(iotHubConnectionString, settings, context.Get <ProductInfo>());
                    break;

                case TransportType.Mqtt_WebSocket_Only:
                    this.channelFactory = this.CreateWebSocketChannelFactory(iotHubConnectionString, settings, context.Get <ProductInfo>());
                    break;

                default:
                    throw new InvalidOperationException("Unsupported Transport Setting {0}".FormatInvariant(settings.GetTransportType()));
                }
            }
            else
            {
                this.channelFactory = channelFactory;
            }

            this.closeRetryPolicy = new RetryPolicy(new TransientErrorIgnoreStrategy(), 5, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1));
        }
Example #38
0
        public static SubAckPacket InResponseTo(SubscribePacket subscribePacket, QualityOfService maxQoS)
        {
            var subAckPacket = new SubAckPacket
            {
                PacketId = subscribePacket.PacketId
            };
            IReadOnlyList<SubscriptionRequest> subscriptionRequests = subscribePacket.Requests;
            var returnCodes = new QualityOfService[subscriptionRequests.Count];
            for (int i = 0; i < subscriptionRequests.Count; i++)
            {
                QualityOfService requestedQos = subscriptionRequests[i].QualityOfService;
                returnCodes[i] = requestedQos <= maxQoS ? requestedQos : maxQoS;
            }

            subAckPacket.ReturnCodes = returnCodes;

            return subAckPacket;
        }
        // Set everything up
        private static void Initialize() {
            _client = new MqttClient("mqtt.relayr.io");
            _client.MqttMsgPublishReceived += _client_MqttMsgPublishReceived;

            _subscribedDevices = new Dictionary<string, Device>();
            _deviceIdToTopic = new Dictionary<string, string>();

            _arguments = new Dictionary<string, string>();
            _arguments.Add("transport", "mqtt");
            _arguments.Add("deviceId", "");

            // Assign a random value to the clientId if one hasn't been set yet.
            Random r = new Random();
            if (ClientId == null) 
            { 
                ClientId = r.Next(0, Int16.MaxValue) + "";
            }

            // Assign the quality of service to be AtLeastOnce if it hasn't been set yet.
            if (DefaultQualityOfService == null)
            {
                DefaultQualityOfService = QualityOfService.AtLeastOnce;
            }
        }
        internal MqttTransportHandler(IotHubConnectionString iotHubConnectionString, MqttTransportSettings settings)
        {
            this.DefaultReceiveTimeout = DefaultReceiveTimeoutInSeconds;
            this.connectCompletion = new TaskCompletionSource();
            this.mqttIotHubAdapterFactory = new MqttIotHubAdapterFactory(settings);
            this.messageQueue = new ConcurrentQueue<Message>();
            this.completionQueue = new Queue<string>();
            this.serverAddress = Dns.GetHostEntry(iotHubConnectionString.HostName).AddressList[0];
            var group = new SingleInstanceEventLoopGroup();
            this.qos = settings.PublishToServerQoS;

            this.bootstrap = new Bootstrap()
                .Group(@group)
                .Channel<TcpSocketChannel>()
                .Option(ChannelOption.TcpNodelay, true)
                .Handler(new ActionChannelInitializer<ISocketChannel>(ch =>
                {
                    ch.Pipeline.AddLast(
                        TlsHandler.Client(iotHubConnectionString.HostName, null),
                        MqttEncoder.Instance,
                        new MqttDecoder(false, 256 * 1024),
                        this.mqttIotHubAdapterFactory.Create(
                            this.OnConnected,
                            this.OnMessageReceived,
                            this.OnError, 
                            iotHubConnectionString, 
                            settings));
                }));

            this.ScheduleCleanup(async () =>
            {
                this.connectCompletion.TrySetCanceled();
                await group.ShutdownGracefullyAsync();
            });

        }
Example #41
0
        public static SubAckPacket AddSubscriptions(ISessionState session, SubscribePacket packet, QualityOfService maxSupportedQos)
        {
            List<Subscription> subscriptions = session.Subscriptions;
            var returnCodes = new List<QualityOfService>(subscriptions.Count);
            foreach (SubscriptionRequest request in packet.Requests)
            {
                Subscription existingSubscription = null;
                for (int i = subscriptions.Count - 1; i >= 0; i--)
                {
                    Subscription subscription = subscriptions[i];
                    if (subscription.TopicFilter.Equals(request.TopicFilter, StringComparison.Ordinal))
                    {
                        subscriptions.RemoveAt(i);
                        existingSubscription = subscription;
                        break;
                    }
                }

                QualityOfService finalQos = request.QualityOfService < maxSupportedQos ? request.QualityOfService : maxSupportedQos;

                subscriptions.Add(existingSubscription == null
                    ? new Subscription(request.TopicFilter, request.QualityOfService)
                    : existingSubscription.CreateUpdated(finalQos));

                returnCodes.Add(finalQos);
            }
            var ack = new SubAckPacket
            {
                PacketId = packet.PacketId,
                ReturnCodes = returnCodes
            };
            return ack;
        }
Example #42
0
        public void PublishAsync(string topic, byte[] payload, QualityOfService qos, int messageId, bool retain)
        {
            var msgBuilder = new MqttPublishMessageBuilder
            {
                MessageId = messageId,
                TopicName = topic,
                QualityOfService = qos,
                Retain = retain,
                Payload = payload
            };

            SendMessageAsync(msgBuilder);
        }
 internal MqttTransportHandler(IotHubConnectionString iotHubConnectionString, MqttTransportSettings settings, Func<IPAddress, int, Task<IChannel>> channelFactory)
     : base(settings)
 {
     this.mqttIotHubAdapterFactory = new MqttIotHubAdapterFactory(settings);
     this.messageQueue = new ConcurrentQueue<Message>();
     this.completionQueue = new Queue<string>();
     this.serverAddress = Dns.GetHostEntry(iotHubConnectionString.HostName).AddressList[0];
     this.qos = settings.PublishToServerQoS;
     this.eventLoopGroupKey = iotHubConnectionString.IotHubName + "#" + iotHubConnectionString.DeviceId + "#" + iotHubConnectionString.Audience;
     this.channelFactory = channelFactory ?? this.CreateChannelFactory(iotHubConnectionString, settings);
     this.closeRetryPolicy = new RetryPolicy(new TransientErrorIgnoreStrategy(), 5, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1));
 }
Example #44
0
        public void PublishStringAsync(string topic, string payload, QualityOfService qos, int messageId, bool retain)
        {
            // Encode the string into a byte array
            byte[] utf8Str = Encoding.UTF8.GetBytes(payload);

            PublishAsync(topic, utf8Str, qos, messageId, retain);
        }
Example #45
0
        public void PublishUIntAsync(string topic, UInt16 payload, QualityOfService qos, int messageId, bool retain)
        {
            // Encode the uint into a byte array
            int pos = 0;
            var payloadBytes = new byte[2];
            Frame.EncodeInt16(payload, payloadBytes, ref pos);

            PublishAsync(topic, payloadBytes, qos, messageId, retain);
        }
        // Does the meat of the work in subscribing to a device (as well as initalization and 
        // connecting if need be)
        public static async Task<Device> SubscribeToDeviceDataAsync(dynamic device, QualityOfService qualityOfService)
        {
            string id = Device.GetDeviceIdFromDynamic(device);
            if (id == null)
            {
                throw new ArgumentException("Passed dynamic object must be of a relayr device type");
            }

            return await SubscribeToDeviceDataAsync(id, qualityOfService);
        }
        // Does the meat of the work in subscribing to a device (as well as initalization and 
        // connecting if need be)
        public static async Task<Device> SubscribeToDeviceDataAsync(string deviceId, QualityOfService qualityOfService)
        {
            // Initialize, if required
            if (_client == null)
            {
                Initialize();
            }

            // Get the connection information for this device
            _arguments["deviceId"] = deviceId;
            HttpResponseMessage response = await HttpManager.Manager.PerformHttpOperation(ApiCall.CreateChannel, null, _arguments);
            dynamic connectionInfo = await HttpManager.Manager.ConvertResponseContentToObject(response);

            // Use that connection information to attempt to connect to the mqtt server, if necessary
            // Return null if a connection couldn't be created
            if (!_client.IsConnected)
            {
                string userId = (string)connectionInfo["credentials"]["user"];
                string password = (string)connectionInfo["credentials"]["password"];

                ConnectToBroker(userId, password);
                if (!_client.IsConnected)
                {
                    return null;
                }
            }

            // Get the quality of service byte
            byte serviceLevel = MqttMsgBase.QOS_LEVEL_AT_LEAST_ONCE;
            switch (qualityOfService)
            {
                case QualityOfService.AtMostOnce:
                    serviceLevel = MqttMsgBase.QOS_LEVEL_AT_MOST_ONCE;
                    break;
                case QualityOfService.ExactlyOnce:
                    serviceLevel = MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE;
                    break;
                case QualityOfService.GrantedFailure:
                    serviceLevel = MqttMsgBase.QOS_LEVEL_GRANTED_FAILURE;
                    break;
            }

            // Subscribe to data from the device
            string topic = (string)connectionInfo["credentials"]["topic"];
            _client.Subscribe(new string[] { topic }, new byte[] { serviceLevel });

            Device device = new Device(deviceId, topic, qualityOfService);
            _subscribedDevices.Add(topic, device);
            _deviceIdToTopic.Add(deviceId, topic);

            return device;
        }
 bool TryMatchSubscription(string topicName, DateTime messageTime, out QualityOfService qos)
 {
     bool found = false;
     qos = QualityOfService.AtMostOnce;
     foreach (Subscription subscription in this.sessionState.Subscriptions)
     {
         if ((!found || subscription.QualityOfService > qos)
             && subscription.CreationTime < messageTime
             && Util.CheckTopicFilterMatch(topicName, subscription.TopicFilter))
         {
             found = true;
             qos = subscription.QualityOfService;
             if (qos >= this.maxSupportedQosToClient)
             {
                 qos = this.maxSupportedQosToClient;
                 break;
             }
         }
     }
     return found;
 }
        protected static async Task GetPublishSteps(IChannel channel, ReadListeningHandler readHandler, string clientId, QualityOfService qos,
            string topicNamePattern, int count, int minPayloadSize, int maxPayloadSize)
        {
            Contract.Requires(count > 0);
            Contract.Requires(qos < QualityOfService.ExactlyOnce);

            PublishPacket[] publishPackets = Enumerable.Repeat(0, count)
                .Select(_ => new PublishPacket(qos, false, false)
                {
                    TopicName = string.Format(topicNamePattern, clientId),
                    PacketId = Random.Next(1, ushort.MaxValue),
                    Payload = GetPayloadBuffer(Random.Next(minPayloadSize, maxPayloadSize))
                })
                .ToArray();
            await channel.WriteAndFlushManyAsync(publishPackets);

            if (qos == QualityOfService.AtMostOnce)
            {
                return;
            }

            int acked = 0;
            do
            {
                object receivedMessage = await readHandler.ReceiveAsync();
                var pubackPacket = receivedMessage as PubAckPacket;
                if (pubackPacket == null || pubackPacket.PacketId != publishPackets[acked].PacketId)
                {
                    throw new InvalidOperationException($"{clientId}: Expected PUBACK({publishPackets[acked].PacketId.ToString()}), received {receivedMessage}");
                }

                acked++;
            }
            while (acked < count);
        }
Example #50
0
 public Task Subscribe(string topic, QualityOfService qos, Action<MqttCommand> completed)
 {
     return Subscribe(
         new[] {new Subscription(topic, qos)},
         completed);
 }
Example #51
0
 public WillMessage(QualityOfService qos, Message message)
 {
     this.QoS = qos;
     this.Message = message;
 }
Example #52
0
 public Task Subscribe(string topic, QualityOfService qos)
 {
     return Subscribe(topic, qos, null);
 }
Example #53
0
 public SubscriptionRequest(string topicFilter, QualityOfService qualityOfService)
 {
     this.TopicFilter = topicFilter;
     this.QualityOfService = qualityOfService;
 }
Example #54
0
 public PublishPacket(QualityOfService qos, bool duplicate, bool retain)
 {
     this.qos = qos;
     this.duplicate = duplicate;
     this.retainRequested = retain;
 }
 public bool Contains(QualityOfService qos)
 {
     return _list.Contains(qos);
 }
Example #56
0
        public Task Publish(string topic, string message, QualityOfService qos, Action<MqttCommand> completed)
        {
            var pub = new Publish(topic, message);
            pub.Header.QualityOfService = qos;
            if (qos != QualityOfService.AtMostOnce)
            {
                pub.MessageId = _idSeq.Next();
            }

            var publish = new PublishSendFlow(_manager);
            return publish.Start(pub, completed);
        }
 public int Add(QualityOfService qos)
 {
     return _list.Add(qos);
 }
Example #58
0
 public Subscription(string topic, QualityOfService qos)
 {
     Topic = topic;
     QoS = qos;
 }
 public int IndexOf(QualityOfService qos)
 {
     return _list.IndexOf(qos);
 }
Example #60
0
        public IAsyncAction PublishAsync(
            string topic,
            [ReadOnlyArray]
            byte[] payload,
            QualityOfService qos,
            int messageId,
            bool retain
            )
        {
            var msgBuilder = new MqttPublishMessageBuilder
            {
                QualityOfService = qos,
                MessageId = messageId,
                Retain = retain,
                TopicName = topic,
                Payload = payload
            };

            return SendMessageAsync(msgBuilder);
        }