Esempio n. 1
0
        async void RetransmitPublishMessage(IChannelHandlerContext context, IMessage message, AckPendingMessageState messageInfo)
        {
            try
            {
                using (message)
                {
                    string topicName;
                    message.Properties[TemplateParameters.DeviceIdTemplateParam] = this.DeviceId;
                    if (!this.messageRouter.TryRouteOutgoingMessage(RouteSourceType.Notification, message, out topicName))
                    {
                        throw new InvalidOperationException("Route mapping failed on retransmission.");
                    }

                    PublishPacket packet = await Util.ComposePublishPacketAsync(context, message, messageInfo.QualityOfService, topicName, context.Channel.Allocator);

                    messageInfo.ResetMessage(message);
                    await this.publishPubAckProcessor.RetransmitAsync(context, packet, messageInfo);
                }
            }
            catch (Exception ex)
            {
                // todo: log more details
                ShutdownOnError(context, "<- PUBLISH (retransmission)", ex);
            }
        }
Esempio n. 2
0
 public static PubRecPacket InResponseTo(PublishPacket publishPacket)
 {
     return(new PubRecPacket
     {
         PacketId = publishPacket.PacketId
     });
 }
        async Task SendMessageAsync(IChannelHandlerContext context, Message message)
        {
            string topicName = string.Format(TelemetryTopicFormat, this.deviceId);

            PublishPacket packet = await Util.ComposePublishPacketAsync(context, message, this.mqttTransportSettings.PublishToServerQoS, topicName);

            var publishCompletion = new TaskCompletionSource();
            var workItem          = new PublishWorkItem
            {
                Completion = publishCompletion,
                Value      = packet
            };

            switch (this.mqttTransportSettings.PublishToServerQoS)
            {
            case QualityOfService.AtMostOnce:
                this.serviceBoundOneWayProcessor.Post(context, workItem);
                break;

            case QualityOfService.AtLeastOnce:
                this.serviceBoundTwoWayProcessor.Post(context, workItem);
                break;

            default:
                throw new NotSupportedException($"Unsupported telemetry QoS: '{this.mqttTransportSettings.PublishToServerQoS}'");
            }
            await publishCompletion.Task;
        }
Esempio n. 4
0
        /// <summary>
        ///     Closes channel
        /// </summary>
        /// <param name="context"></param>
        /// <param name="graceful"></param>
        async void Shutdown(IChannelHandlerContext context, bool graceful)
        {
            if (this.IsInState(StateFlags.Closed))
            {
                return;
            }

            try
            {
                this.stateFlags |= StateFlags.Closed; // "or" not to interfere with ongoing logic which has to honor Closed state when it's right time to do (case by case)

                PerformanceCounters.ConnectionsCurrent.Decrement();

                Queue <Packet> connectQueue = this.connectPendingQueue;
                if (connectQueue != null)
                {
                    while (connectQueue.Count > 0)
                    {
                        Packet packet = connectQueue.Dequeue();
                        ReferenceCountUtil.Release(packet);
                    }
                }

                PublishPacket will = !graceful && this.IsInState(StateFlags.Connected) ? this.willPacket : null;

                this.CloseIotHubConnection(context, will);
                await context.CloseAsync();
            }
            catch (Exception ex)
            {
                MqttIotHubAdapterEventSource.Log.Warning("Error occurred while shutting down the channel.", ex);
            }
        }
Esempio n. 5
0
        Task AcceptMessageAsync(IChannelHandlerContext context, PublishPacket publish)
        {
            if (Logging.IsEnabled)
            {
                Logging.Enter(this, context.Name, publish, nameof(AcceptMessageAsync));
            }

            Message message;

            try
            {
                var bodyStream = new ReadOnlyByteBufferStream(publish.Payload, true);

                message = new Message(bodyStream, true);

                Util.PopulateMessagePropertiesFromPacket(message, publish);

                message.MqttTopicName = publish.TopicName;
            }
            catch (Exception ex) when(!ex.IsFatal())
            {
                ShutdownOnError(context, ex);
                return(TaskConstants.Completed);
            }

            this.mqttIotHubEventHandler.OnMessageReceived(message);

            if (Logging.IsEnabled)
            {
                Logging.Exit(this, context.Name, publish, nameof(AcceptMessageAsync));
            }

            return(TaskConstants.Completed);
        }
Esempio n. 6
0
        static void DecodePublishPacket(IByteBuffer buffer, PublishPacket packet, ref int remainingLength)
        {
            string topicName = DecodeString(buffer, ref remainingLength, 1);

            Util.ValidateTopicName(topicName);

            packet.TopicName = topicName;
            if (packet.QualityOfService > QualityOfService.AtMostOnce)
            {
                DecodePacketIdVariableHeader(buffer, packet, ref remainingLength);
            }

            IByteBuffer payload;

            if (remainingLength > 0)
            {
                payload = buffer.ReadSlice(remainingLength);
                payload.Retain();
                remainingLength = 0;
            }
            else
            {
                payload = Unpooled.Empty;
            }
            packet.Payload = payload;
        }
Esempio n. 7
0
 public static PubAckPacket InResponseTo(PublishPacket publishPacket)
 {
     return new PubAckPacket
     {
         PacketId = publishPacket.PacketId
     };
 }
Esempio n. 8
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;
        }
Esempio n. 9
0
        private Task ProcessReceivedPublishPacketAsync(PublishPacket publishPacket)
        {
            OnMessageReceived?.Invoke(new Message
            {
                Topic   = publishPacket.TopicName,
                Payload = publishPacket.Payload,
                Qos     = publishPacket.Qos,
                Retain  = publishPacket.Retain
            });

            switch (publishPacket.Qos)
            {
            case MqttQos.AtMostOnce:
                return(Task.CompletedTask);

            case MqttQos.AtLeastOnce:
                return(_clientChannel.WriteAndFlushAsync(new PubAckPacket(publishPacket.PacketId)));

            case MqttQos.ExactlyOnce:
                return(_clientChannel.WriteAndFlushAsync(new PubRecPacket(publishPacket.PacketId)));

            default:
                throw new MqttException("Received a not supported QoS level.");
            }
        }
Esempio n. 10
0
        static void EncodePublishMessage(IByteBufferAllocator bufferAllocator, PublishPacket packet, List <object> output)
        {
            IByteBuffer payload = packet.Payload ?? Unpooled.Empty;

            string topicName = packet.TopicName;

            Util.ValidateTopicName(topicName);
            byte[] topicNameBytes = EncodeStringInUtf8(topicName);

            int variableHeaderBufferSize = StringSizeLength + topicNameBytes.Length +
                                           (packet.QualityOfService > QualityOfService.AtMostOnce ? PacketIdLength : 0);
            int payloadBufferSize     = payload.ReadableBytes;
            int variablePartSize      = variableHeaderBufferSize + payloadBufferSize;
            int fixedHeaderBufferSize = 1 + MaxVariableLength;

            IByteBuffer buf = bufferAllocator.Buffer(fixedHeaderBufferSize + variablePartSize);

            buf.WriteByte(CalculateFirstByteOfFixedHeader(packet));
            WriteVariableLengthInt(buf, variablePartSize);
            buf.WriteShort(topicNameBytes.Length);
            buf.WriteBytes(topicNameBytes);
            if (packet.QualityOfService > QualityOfService.AtMostOnce)
            {
                buf.WriteShort(packet.PacketId);
            }

            output.Add(buf);

            if (payload.IsReadable())
            {
                output.Add(payload.Retain());
            }
        }
Esempio n. 11
0
        public static void PopulateMessagePropertiesFromPacket(Message message, PublishPacket publish)
        {
            message.LockToken = publish.QualityOfService == QualityOfService.AtLeastOnce ? publish.PacketId.ToString() : null;

            // Device bound messages could be in 2 formats, depending on whether it is going to the device, or to a module endpoint
            // Format 1 - going to the device - devices/{deviceId}/messages/devicebound/{properties}/
            // Format 2 - going to module endpoint - devices/{deviceId}/modules/{moduleId/endpoints/{endpointId}/{properties}/
            // So choose the right format to deserialize properties.
            string[] topicSegments     = publish.TopicName.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
            string   propertiesSegment = topicSegments.Length > 6 ? topicSegments[6] : topicSegments[4];

            Dictionary <string, string> properties = UrlEncodedDictionarySerializer.Deserialize(propertiesSegment, 0);

            foreach (KeyValuePair <string, string> property in properties)
            {
                string propertyName;
                if (ToSystemPropertiesMap.TryGetValue(property.Key, out propertyName))
                {
                    message.SystemProperties[propertyName] = ConvertToSystemProperty(property);
                }
                else
                {
                    message.Properties[property.Key] = property.Value;
                }
            }
        }
Esempio n. 12
0
        async Task IrisSub()
        {
            var dic = new Dictionary <string, object>
            {
                { "seq_id", SeqId.ToString() },
                { "sub", new List <string>() },
                { "snapshot_at_ms", SnapshotAt.ToUnixTimeMiliSeconds() }
            };
            var json       = JsonConvert.SerializeObject(dic);
            var bytes      = Encoding.UTF8.GetBytes(json);
            var dataStream = new MemoryStream(512);

            using (var zlibStream = new ZlibStream(dataStream, CompressionMode.Compress, CompressionLevel.Level9, true))
            {
                await zlibStream.WriteAsync(bytes, 0, bytes.Length);
            }

            var compressed    = dataStream.GetWindowsRuntimeBuffer(0, (int)dataStream.Length);
            var publishPacket = new PublishPacket(QualityOfService.AtLeastOnce, false, false)
            {
                Payload   = compressed,
                PacketId  = (ushort)CryptographicBuffer.GenerateRandomNumber(),
                TopicName = "/ig_sub_iris"
            };
            await FbnsPacketEncoder.EncodePacket(publishPacket, _outboundWriter);
        }
Esempio n. 13
0
        async Task PubSub()
        {
            var user = _instaApi.GetLoggedUser().LoggedInUser;
            var dic  = new Dictionary <string, List <string> >
            {
                { "sub",
                  new List <string>
                  {
                      SkyWalker.DirectSubscribe(user?.Pk.ToString()),
                      SkyWalker.LiveSubscribe(user?.Pk.ToString()),
                  } }
            };
            var json       = JsonConvert.SerializeObject(dic);
            var bytes      = Encoding.UTF8.GetBytes(json);
            var dataStream = new MemoryStream(512);

            using (var zlibStream = new ZlibStream(dataStream, CompressionMode.Compress, CompressionLevel.Level9, true))
            {
                await zlibStream.WriteAsync(bytes, 0, bytes.Length);
            }

            var compressed    = dataStream.GetWindowsRuntimeBuffer(0, (int)dataStream.Length);
            var publishPacket = new PublishPacket(QualityOfService.AtLeastOnce, false, false)
            {
                Payload   = compressed,
                PacketId  = (ushort)CryptographicBuffer.GenerateRandomNumber(),
                TopicName = "/pubsub"
            };
            await FbnsPacketEncoder.EncodePacket(publishPacket, _outboundWriter);
        }
Esempio n. 14
0
        async Task RealtimeSub()
        {
            var user = _instaApi.GetLoggedUser().LoggedInUser;
            var dic  = new Dictionary <string, List <string> >
            {
                { "sub",
                  new List <string>
                  {
                      GraphQLSubscriptions.GetAppPresenceSubscription(),
                GraphQLSubscriptions.GetZeroProvisionSubscription(_instaApi.GetCurrentDevice().DeviceGuid.ToString()),
                      GraphQLSubscriptions.GetDirectStatusSubscription(),
                      GraphQLSubscriptions.GetDirectTypingSubscription(user?.Pk.ToString()),
                      GraphQLSubscriptions.GetAsyncAdSubscription(user?.Pk.ToString())
                  } }
            };
            var json       = JsonConvert.SerializeObject(dic);
            var bytes      = Encoding.UTF8.GetBytes(json);
            var dataStream = new MemoryStream(512);

            using (var zlibStream = new ZlibStream(dataStream, CompressionMode.Compress, CompressionLevel.Level9, true))
            {
                await zlibStream.WriteAsync(bytes, 0, bytes.Length);
            }

            var compressed    = dataStream.GetWindowsRuntimeBuffer(0, (int)dataStream.Length);
            var publishPacket = new PublishPacket(QualityOfService.AtLeastOnce, false, false)
            {
                Payload   = compressed,
                PacketId  = (ushort)CryptographicBuffer.GenerateRandomNumber(),
                TopicName = "/ig_realtime_sub"
            };
            await FbnsPacketEncoder.EncodePacket(publishPacket, _outboundWriter);
        }
        async void RetransmitPublishMessage(IChannelHandlerContext context, Message message, AckPendingMessageState messageInfo)
        {
            try
            {
                using (message)
                {
                    string topicName;
                    var    completeContext = new ReadOnlyMergeDictionary <string, string>(this.sessionContext, message.Properties);
                    if (!this.topicNameRouter.TryMapRouteToTopicName(RouteSourceType.Notification, completeContext, out topicName))
                    {
                        throw new InvalidOperationException("Route mapping failed on retransmission.");
                    }

                    PublishPacket packet = await Util.ComposePublishPacketAsync(context, message, messageInfo.QualityOfService, topicName);

                    messageInfo.ResetMessage(message);
                    await this.publishPubAckProcessor.RetransmitAsync(context, packet, messageInfo);
                }
            }
            catch (Exception ex)
            {
                // todo: log more details
                ShutdownOnError(context, "<- PUBLISH (retransmission)", ex);
            }
        }
        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);
        }
Esempio n. 17
0
        private ushort Publish(PublishPacket packet)
        {
            if (packet.QosLevel != MqttQos.AtMostOnce)
            {
                if (packet.PacketId == 0)
                {
                    packet.PacketId = this.GetNextPacketId();
                }
                Persistence.RegisterOutgoingFlow(new OutgoingFlow()
                {
                    PacketId = packet.PacketId,
                    Topic    = packet.Topic,
                    Qos      = packet.QosLevel,
                    Payload  = packet.Message
                });
            }

            try {
                IsPublishing = true;
                Send(packet);
                return(packet.PacketId);
            } catch {
                IsPublishing = false;
                throw;
            }
        }
Esempio n. 18
0
        public void OnPublish(IChannelHandlerContext context, PublishPacket packet)
        {
            switch (packet.QualityOfService)
            {
            case QualityOfService.AtMostOnce:
                publishCallback(packet);
                break;

            case QualityOfService.AtLeastOnce:
                publishCallback(packet);
                if (packet.PacketId != -1)
                {
                    context.WriteAndFlushAsync(PubAckPacket.InResponseTo(packet));
                }
                break;

            case QualityOfService.ExactlyOnce:
                if (packet.PacketId != -1)
                {
                    var pubRecPacket = PubRecPacket.InResponseTo(packet);
                    PendingQoS2Publish pendingQoS2Publish = new PendingQoS2Publish(packet, pubRecPacket);
                    pendingIncomingQoS2Publishes.TryAdd(pubRecPacket.PacketId, pendingQoS2Publish);
                    packet.Retain();
                    pendingQoS2Publish.Retransmit(eventLoopGroup.GetNext(), sendAndFlushAsync);
                    context.WriteAndFlushAsync(pubRecPacket);
                }
                break;
            }
        }
Esempio n. 19
0
        static void EncodePublishMessage(DataWriter writer, PublishPacket packet)
        {
            IBuffer payload = packet.Payload;

            string topicName = packet.TopicName;

            // Util.ValidateTopicName(topicName);
            byte[] topicNameBytes = EncodeStringInUtf8(topicName);

            int variableHeaderBufferSize = STRING_SIZE_LENGTH + topicNameBytes.Length +
                                           (packet.QualityOfService > QualityOfService.AtMostOnce ? PACKET_ID_LENGTH : 0);
            int payloadBufferSize = (int)payload.Length;
            int variablePartSize  = variableHeaderBufferSize + payloadBufferSize;

            writer.WriteByte(CalculateFirstByteOfFixedHeader(packet));
            WriteVariableLengthInt(writer, variablePartSize);
            writer.WriteInt16((short)topicNameBytes.Length);
            writer.WriteBytes(topicNameBytes);
            if (packet.QualityOfService > QualityOfService.AtMostOnce)
            {
                writer.WriteInt16((short)packet.PacketId);
            }

            writer.WriteBuffer(payload);
        }
Esempio n. 20
0
        void ProcessPublish(IChannelHandlerContext context, PublishPacket packet)
        {
            if (Logging.IsEnabled)
            {
                Logging.Enter(this, context.Name, packet, nameof(ProcessPublish));
            }

            if (this.IsInState(StateFlags.Closed))
            {
                return;
            }

            switch (packet.QualityOfService)
            {
            case QualityOfService.AtMostOnce:
                this.deviceBoundOneWayProcessor.Post(context, packet);
                break;

            case QualityOfService.AtLeastOnce:
                this.deviceBoundTwoWayProcessor.Post(context, packet);
                break;

            default:
                throw new NotSupportedException($"Unexpected QoS: '{packet.QualityOfService}'");
            }
            this.ResumeReadingIfNecessary(context);

            if (Logging.IsEnabled)
            {
                Logging.Exit(this, context.Name, packet, nameof(ProcessPublish));
            }
        }
            IEnumerable <TestScenarioStep> GetPart2SpecificSteps(Func <object> currentMessageFunc)
            {
                yield return(TestScenarioStep.ReadMore());

                var packets = new Packet[2];

                for (int i = packets.Length - 1; i >= 0; i--)
                {
                    packets[i] = Assert.IsAssignableFrom <Packet>(currentMessageFunc());
                    if (i > 0)
                    {
                        yield return(TestScenarioStep.ReadMore());
                    }
                }

                PublishPacket qos1Packet = Assert.Single(packets.OfType <PublishPacket>());

                Assert.Equal(QualityOfService.AtLeastOnce, qos1Packet.QualityOfService);
                this.AssertPacketCoreValue(qos1Packet, Encoding.ASCII.GetString(qos1Packet.Payload.ToArray()));

                PubRelPacket pubRelQos2Packet = Assert.Single(packets.OfType <PubRelPacket>());

                yield return(TestScenarioStep.Write(
                                 false,
                                 PubAckPacket.InResponseTo(qos1Packet),
                                 PubCompPacket.InResponseTo(pubRelQos2Packet),
                                 DisconnectPacket.Instance));
            }
Esempio n. 22
0
        /// <summary>
        ///     Indicate activity
        /// </summary>
        /// <param name="threadId">Thread id</param>
        /// <param name="isActive">Active status</param>
        public async Task <IResult <bool> > IndicateActivityAsync(string threadId, bool isActive)
        {
            try
            {
                var token = ExtensionHelper.GetThreadToken();

                var data = new Dictionary <string, string>
                {
                    { "action", "indicate_activity" },
                    { "item_type", "indicate_activity" },
                    { "thread_id", threadId },
                    { "client_context", token },
                    { "activity_status", isActive ? "1" : "0" },
                };
                var json          = JsonConvert.SerializeObject(data);
                var bytes         = Encoding.UTF8.GetBytes(json);
                var publishPacket = new PublishPacket(QualityOfService.AtLeastOnce, false, false)
                {
                    Payload   = ZlibHelper.Compress(bytes).AsBuffer(),
                    PacketId  = (ushort)CryptographicBuffer.GenerateRandomNumber(),
                    TopicName = "132"
                };
                await FbnsPacketEncoder.EncodePacket(publishPacket, _outboundWriter);

                return(Result.Success(true));
            }
            catch (SocketException socketException)
            {
                return(Result.Fail(socketException, default(bool), ResponseType.NetworkProblem));
            }
            catch (Exception exception)
            {
                return(Result.Fail <bool>(exception));
            }
        }
Esempio n. 23
0
        async Task CompletePublishAsync(IChannelHandlerContext context, PublishPacket will)
        {
            if (will == null)
            {
                return;
            }

            var sendingClient = this.ResolveSendingClient(will.TopicName);

            MessageAsyncProcessor <PublishPacket> publishProcessor;

            if (this.publishProcessors.TryGetValue(sendingClient, out publishProcessor))
            {
                await publishProcessor.Completion;
            }

            try
            {
                await this.PublishToServerAsync(context, sendingClient, will, MessageTypes.Will);
            }
            catch (Exception ex)
            {
                CommonEventSource.Log.Warning("Failed sending Will Message.", ex);
            }
        }
        private async Task PublishRegisterAsync(IChannelHandlerContext context)
        {
            IByteBuffer packagePayload = Unpooled.Empty;

            if (_message.Payload != null && _message.Payload.Length > 0)
            {
                var deviceRegistration = new DeviceRegistration {
                    Payload = new JRaw(_message.Payload)
                };
                using var customContentStream = new MemoryStream(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(deviceRegistration)));
                long streamLength = customContentStream.Length;
                int  length       = (int)streamLength;
                packagePayload = context.Channel.Allocator.Buffer(length, length);
                await packagePayload.WriteBytesAsync(customContentStream, length).ConfigureAwait(false);
            }

            int packetId = GetNextPacketId();
            var message  = new PublishPacket(Qos, false, false)
            {
                TopicName = string.Format(CultureInfo.InvariantCulture, RegisterTopic, packetId),
                PacketId  = packetId,
                Payload   = packagePayload
            };

            await context.WriteAndFlushAsync(message).ConfigureAwait(false);
        }
Esempio n. 25
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);
        }
Esempio n. 26
0
        async void CloseIotHubConnection(IChannelHandlerContext context, PublishPacket will)
        {
            if (!this.ConnectedToHub)
            {
                // closure happened before IoT Hub connection was established or it was initiated due to disconnect
                return;
            }

            try
            {
                this.publishProcessor.Complete();
                this.publishPubAckProcessor.Complete();
                this.publishPubRecProcessor.Complete();
                this.pubRelPubCompProcessor.Complete();
                await Task.WhenAll(
                    this.CompletePublishAsync(context, will),
                    this.publishPubAckProcessor.Completion,
                    this.publishPubRecProcessor.Completion,
                    this.pubRelPubCompProcessor.Completion);

                IMessagingServiceClient hub = this.messagingServiceClient;
                this.messagingServiceClient = null;
                await hub.DisposeAsync();
            }
            catch (Exception ex)
            {
                MqttIotHubAdapterEventSource.Log.Info("Failed to close IoT Hub Client cleanly.", ex.ToString());
            }
        }
Esempio n. 27
0
        Task AcceptMessageAsync(IChannelHandlerContext context, PublishPacket publish)
        {
            Message message;

            try
            {
                var buffer = new byte[publish.Payload.ReadableBytes];
                publish.Payload.GetBytes(0, buffer);
                var bodyStream = new MemoryStream(buffer);
                bodyStream.Position = 0;

                message = new Message(bodyStream);

                Util.PopulateMessagePropertiesFromPacket(message, publish);
            }
            catch (Exception ex)
            {
                ShutdownOnError(context, ex);
                return(TaskConstants.Completed);
            }
            finally
            {
                publish.Release();
            }
            this.onMessageReceived(message);
            return(TaskConstants.Completed);
        }
        async Task CompletePublishAsync(IChannelHandlerContext context, PublishPacket will)
        {
            var completionTasks = new List <Task>();

            foreach (var publishProcessorRecord in this.publishProcessors)
            {
                publishProcessorRecord.Value.Close();
                completionTasks.Add(publishProcessorRecord.Value.Closed);
            }
            await Task.WhenAll(completionTasks);

            IMessagingServiceClient sendingClient = null;

            if (will != null)
            {
                sendingClient = this.ResolveSendingClient(will.TopicName);
                try
                {
                    await this.PublishToServerAsync(context, sendingClient, will, MessageTypes.Will);
                }
                catch (Exception ex)
                {
                    CommonEventSource.Log.Warning("Failed sending Will Message.", ex, this.ChannelId, this.Id);
                }
            }
        }
Esempio n. 29
0
        private static void EncodePublishPacket(PublishPacket packet, DataWriter writer)
        {
            var payload = packet.Payload;

            string topicName = packet.TopicName;

            byte[] topicNameBytes = EncodeStringInUtf8(topicName);

            uint variableHeaderBufferSize = (uint)(STRING_SIZE_LENGTH + topicNameBytes.Length +
                                                   (packet.QualityOfService > QualityOfService.AtMostOnce ? PACKET_ID_LENGTH : 0));
            uint payloadBufferSize = payload?.Length ?? 0;
            uint variablePartSize  = variableHeaderBufferSize + payloadBufferSize;

            writer.WriteByte(CalculateFirstByteOfFixedHeader(packet));
            WriteVariableLengthInt(writer, variablePartSize);
            writer.WriteUInt16((ushort)topicNameBytes.Length);
            writer.WriteBytes(topicNameBytes);
            if (packet.QualityOfService > QualityOfService.AtMostOnce)
            {
                writer.WriteUInt16(packet.PacketId);
            }

            if (payload != null)
            {
                writer.WriteBuffer(payload);
            }
        }
Esempio n. 30
0
        static void DecodePublishPacket(DataReader reader, PublishPacket packet, ref uint remainingLength)
        {
            string topicName = DecodeString(reader, ref remainingLength);

            packet.TopicName = topicName;
            if (packet.QualityOfService > QualityOfService.AtMostOnce)
            {
                DecodePacketIdVariableHeader(reader, packet, ref remainingLength);
            }

            IBuffer payload;

            if (remainingLength > 0)
            {
                try
                {
                    Debug.WriteLine("UnconsumedBufferLength: " + reader.UnconsumedBufferLength);
                    if (reader.UnconsumedBufferLength < remainingLength)
                    {
                        remainingLength = reader.UnconsumedBufferLength;
                    }
                    payload         = reader.ReadBuffer(remainingLength);
                    remainingLength = 0;
                }
                catch { payload = null; }
            }
            else
            {
                payload = null;
            }
            packet.Payload = payload;
        }
Esempio n. 31
0
        public static PublishPacket DecodePublish(byte[] data)
        {
            var r = new Reader(data);

            var type = r.ReadByte();

            Guard.Assert((byte)PacketType.Publish, type, "Type");

            var length = r.ReadInt32Vlq(out _);

            if (length + 2 > data.Length)
            {
                throw new InvalidOperationException("Packet too short");
            }

            const int topicLengthBytes = 2;

            var topicLength = r.ReadInt16BigEndian();
            var topic       = Encoding.GetString(r.ReadBytes(topicLength));
            var remaining   = length - topicLengthBytes - topicLength;
            var payload     = r.ReadBytes(remaining);

            var result = new PublishPacket
            {
                Topic   = topic,
                Payload = payload.ToArray(),
            };

            ProcessTTR(r, result);

            Guard.Assert(r.Position, data.Length);

            return(result);
        }