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));
            }
Example #2
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;
            }
        }
        async Task PublishToServerAsync(IChannelHandlerContext context, IMessagingServiceClient sendingClient, PublishPacket packet, string messageType)
        {
            if (!this.ConnectedToService)
            {
                packet.Release();
                return;
            }

            PreciseTimeSpan startedTimestamp = PreciseTimeSpan.FromStart;

            this.ResumeReadingIfNecessary(context);

            IMessage message = null;

            try
            {
                message = sendingClient.CreateMessage(packet.TopicName, packet.Payload);
                Util.CompleteMessageFromPacket(message, packet, this.settings);

                if (messageType != null)
                {
                    message.Properties[this.settings.ServicePropertyPrefix + MessagePropertyNames.MessageType] = messageType;
                }

                await sendingClient.SendAsync(message);

                PerformanceCounters.MessagesSentPerSecond.Increment();

                if (!this.IsInState(StateFlags.Closed))
                {
                    switch (packet.QualityOfService)
                    {
                    case QualityOfService.AtMostOnce:
                        // no response necessary
                        PerformanceCounters.InboundMessageProcessingTime.Register(startedTimestamp);
                        break;

                    case QualityOfService.AtLeastOnce:
                        Util.WriteMessageAsync(context, PubAckPacket.InResponseTo(packet))
                        .OnFault(ShutdownOnWriteFaultAction, context);
                        PerformanceCounters.InboundMessageProcessingTime.Register(startedTimestamp);     // todo: assumes PUBACK is written out sync
                        break;

                    case QualityOfService.ExactlyOnce:
                        ShutdownOnError(context, InboundPublishProcessingScope, new ProtocolGatewayException(ErrorCode.ExactlyOnceQosNotSupported, "QoS 2 is not supported."));
                        break;

                    default:
                        throw new ProtocolGatewayException(ErrorCode.UnknownQosType, "Unexpected QoS level: " + packet.QualityOfService.ToString());
                    }
                }
                message = null;
            }
            finally
            {
                message?.Dispose();
            }
        }
            async Task GetPart1SpecificSteps(IChannel channel, ReadListeningHandler readHandler)
            {
                int publishQoS1PacketId = GetRandomPacketId();
                await channel.WriteAndFlushManyAsync(
                    new PublishPacket(QualityOfService.AtMostOnce, false, false)
                    {
                        //TopicName = string.Format("devices/{0}/messages/log/verbose/", clientId),
                        TopicName = $"devices/{this.clientId}/messages/events",
                        Payload = Unpooled.WrappedBuffer(Encoding.UTF8.GetBytes("{\"test\": \"telemetry-QoS0\"}"))
                    },
                    new PublishPacket(QualityOfService.AtLeastOnce, false, false)
                    {
                        PacketId = publishQoS1PacketId,
                        TopicName = $"devices/{this.clientId}/messages/events",
                        Payload = Unpooled.WrappedBuffer(Encoding.UTF8.GetBytes("{\"test\": \"telemetry\"}"))
                    });

                var packets = new Packet[5];
                for (int i = packets.Length - 1; i >= 0; i--)
                {
                    packets[i] = Assert.IsAssignableFrom<Packet>(await readHandler.ReceiveAsync());
                }

                PubAckPacket pubAckPacket = Assert.Single(packets.OfType<PubAckPacket>());
                Assert.Equal(publishQoS1PacketId, pubAckPacket.PacketId);

                PublishPacket publishQoS0Packet = Assert.Single(packets.OfType<PublishPacket>().Where(x => x.QualityOfService == QualityOfService.AtMostOnce));
                this.AssertPacketCoreValue(publishQoS0Packet, NotificationQoS0Content);

                PublishPacket publishQoS1Packet = Assert.Single(packets.OfType<PublishPacket>().Where(x => x.QualityOfService == QualityOfService.AtLeastOnce));
                this.AssertPacketCoreValue(publishQoS1Packet, NotificationQoS1Content);

                PublishPacket[] publishQoS2Packets = packets.OfType<PublishPacket>().Where(x => x.QualityOfService == QualityOfService.ExactlyOnce).Reverse().ToArray();
                Assert.Equal(2, publishQoS2Packets.Length);
                PublishPacket publishQoS2Packet1 = publishQoS2Packets[0];
                this.AssertPacketCoreValue(publishQoS2Packet1, NotificationQoS2Content);
                PublishPacket publishQoS2Packet2 = publishQoS2Packets[1];
                this.AssertPacketCoreValue(publishQoS2Packet2, NotificationQoS2Content2);

                await channel.WriteAndFlushManyAsync(
                    PubAckPacket.InResponseTo(publishQoS1Packet),
                    PubRecPacket.InResponseTo(publishQoS2Packet1),
                    PubRecPacket.InResponseTo(publishQoS2Packet2));

                var pubRelQoS2Packet1 = Assert.IsAssignableFrom<PubRelPacket>(await readHandler.ReceiveAsync());
                Assert.Equal(publishQoS2Packet1.PacketId, pubRelQoS2Packet1.PacketId);

                var pubRelQoS2Packet2 = Assert.IsAssignableFrom<PubRelPacket>(await readHandler.ReceiveAsync());
                Assert.Equal(publishQoS2Packet2.PacketId, pubRelQoS2Packet2.PacketId);

                await channel.WriteAndFlushManyAsync(
                    PubCompPacket.InResponseTo(pubRelQoS2Packet1),
                    DisconnectPacket.Instance);

                // device queue still contains QoS 2 packet 2 which was PUBRECed but not PUBCOMPed.
            }
        static async Task RunMqttServerScenarioAsync(IChannel channel, ReadListeningHandler readListener)
        {
            var connectPacket = await readListener.ReceiveAsync(DefaultTimeout) as ConnectPacket;

            Assert.IsNotNull(connectPacket, "Must be a Connect pkt");
            // todo verify

            await channel.WriteAndFlushAsync(new ConnAckPacket
            {
                ReturnCode     = ConnectReturnCode.Accepted,
                SessionPresent = true
            });

            var subscribePacket = await readListener.ReceiveAsync(DefaultTimeout) as SubscribePacket;

            Assert.IsNotNull(subscribePacket);
            // todo verify

            await channel.WriteAndFlushAsync(SubAckPacket.InResponseTo(subscribePacket, QualityOfService.ExactlyOnce));

            var unsubscribePacket = await readListener.ReceiveAsync(DefaultTimeout) as UnsubscribePacket;

            Assert.IsNotNull(unsubscribePacket);
            // todo verify

            await channel.WriteAndFlushAsync(UnsubAckPacket.InResponseTo(unsubscribePacket));

            var publishQos0Packet = await readListener.ReceiveAsync(DefaultTimeout) as PublishPacket;

            Assert.IsNotNull(publishQos0Packet);
            // todo verify

            var publishQos1Packet = await readListener.ReceiveAsync(DefaultTimeout) as PublishPacket;

            Assert.IsNotNull(publishQos1Packet);
            // todo verify

            int publishQos1PacketId = GetRandomPacketId();
            await channel.WriteAndFlushManyAsync(
                PubAckPacket.InResponseTo(publishQos1Packet),
                new PublishPacket(QualityOfService.AtLeastOnce, false, false)
            {
                PacketId  = publishQos1PacketId,
                TopicName = PublishS2CQos1Topic,
                Payload   = Unpooled.WrappedBuffer(Encoding.UTF8.GetBytes(PublishS2CQos1Payload))
            });

            var pubAckPacket = await readListener.ReceiveAsync(DefaultTimeout) as PubAckPacket;

            Assert.AreEqual(publishQos1PacketId, pubAckPacket.PacketId);

            var disconnectPacket = await readListener.ReceiveAsync(DefaultTimeout) as DisconnectPacket;

            Assert.IsNotNull(disconnectPacket);
        }
Example #6
0
        IEnumerable <TestScenarioStep> GetMqttServerScenario(Func <object> currentMessageFunc)
        {
            yield return(TestScenarioStep.MoreFeedbackExpected());

            var connectPacket = Assert.IsType <ConnectPacket>(currentMessageFunc());

            // todo verify

            yield return(TestScenarioStep.Message(new ConnAckPacket
            {
                ReturnCode = ConnectReturnCode.Accepted,
                SessionPresent = true
            }));

            var subscribePacket = Assert.IsType <SubscribePacket>(currentMessageFunc());

            // todo verify

            yield return(TestScenarioStep.Message(SubAckPacket.InResponseTo(subscribePacket, QualityOfService.ExactlyOnce)));

            var unsubscribePacket = Assert.IsType <UnsubscribePacket>(currentMessageFunc());

            // todo verify

            yield return(TestScenarioStep.Message(UnsubAckPacket.InResponseTo(unsubscribePacket)));

            var publishQos0Packet = Assert.IsType <PublishPacket>(currentMessageFunc());

            // todo verify

            yield return(TestScenarioStep.MoreFeedbackExpected());

            var publishQos1Packet = Assert.IsType <PublishPacket>(currentMessageFunc());
            // todo verify

            int publishQos1PacketId = GetRandomPacketId();

            yield return(TestScenarioStep.Messages(PubAckPacket.InResponseTo(publishQos1Packet),
                                                   new PublishPacket(QualityOfService.AtLeastOnce, false, false)
            {
                PacketId = publishQos1PacketId,
                TopicName = PublishS2CQos1Topic,
                Payload = Unpooled.WrappedBuffer(Encoding.UTF8.GetBytes(PublishS2CQos1Payload))
            }));

            var pubAckPacket = Assert.IsType <PubAckPacket>(currentMessageFunc());

            Assert.Equal(publishQos1PacketId, pubAckPacket.PacketId);

            yield return(TestScenarioStep.MoreFeedbackExpected());

            var disconnectPacket = Assert.IsType <DisconnectPacket>(currentMessageFunc());
        }
        async Task PublishToServerAsync(IChannelHandlerContext context, PublishPacket packet, string messageType)
        {
            if (!this.ConnectedToHub)
            {
                return;
            }

            PreciseTimeSpan startedTimestamp = PreciseTimeSpan.FromStart;

            this.ResumeReadingIfNecessary(context);

            using (Stream bodyStream = packet.Payload.IsReadable() ? new ReadOnlyByteBufferStream(packet.Payload, true) : null)
                using (IMessage message = this.messagingFactory.CreateMessage(bodyStream))
                {
                    this.ApplyRoutingConfiguration(message, packet);

                    Util.CompleteMessageFromPacket(message, packet, this.settings);

                    if (messageType != null)
                    {
                        message.Properties[this.settings.ServicePropertyPrefix + MessagePropertyNames.MessageType] = messageType;
                    }

                    await this.messagingServiceClient.SendAsync(message);

                    PerformanceCounters.MessagesSentPerSecond.Increment();
                }

            if (!this.IsInState(StateFlags.Closed))
            {
                switch (packet.QualityOfService)
                {
                case QualityOfService.AtMostOnce:
                    // no response necessary
                    PerformanceCounters.InboundMessageProcessingTime.Register(startedTimestamp);
                    break;

                case QualityOfService.AtLeastOnce:
                    Util.WriteMessageAsync(context, PubAckPacket.InResponseTo(packet))
                    .OnFault(ShutdownOnWriteFaultAction, context);
                    PerformanceCounters.InboundMessageProcessingTime.Register(startedTimestamp);     // todo: assumes PUBACK is written out sync
                    break;

                case QualityOfService.ExactlyOnce:
                    ShutdownOnError(context, "QoS 2 is not supported.");
                    break;

                default:
                    throw new InvalidOperationException("Unexpected QoS level: " + packet.QualityOfService);
                }
            }
        }
Example #8
0
        private async Task OnPublish(MessageWebSocket ws, Packet packet)
        {
            var outStream     = ws.OutputStream;
            var publishPacket = (PublishPacket)packet;

            if (publishPacket.Payload == null)
            {
                throw new Exception($"{nameof(SyncClient)}: Publish packet received but payload is null");
            }
            var payload = Encoding.UTF8.GetString(publishPacket.Payload.ToArray());

            this.Log($"Publish to {publishPacket.TopicName} with payload: {payload}");
            switch (publishPacket.TopicName)
            {
            case "/ig_message_sync":
                var messageSyncPayload = JsonConvert.DeserializeObject <List <MessageSyncEventArgs> >(payload);
                var latest             = messageSyncPayload.Last();
                if (latest.SeqId > _seqId && latest.Data.Count > 0)
                {
                    _seqId = latest.SeqId;
                    if (latest.Data[0].Op != "remove")
                    {
                        _snapshotAt = latest.Data[0].Item.Timestamp;
                    }
                }
                MessageReceived?.Invoke(this, messageSyncPayload);
                break;

            case "/pubsub":
                payload = payload.Substring(payload.IndexOf('{'));      // pubsub is weird. It has a few non string bytes before the actual data.
                var pubsub = JsonConvert.DeserializeObject <PubsubEventArgs>(payload);
                if (pubsub.Data[0].Path.Contains("activity_indicator_id"))
                {
                    ActivityIndicatorChanged?.Invoke(this, pubsub);
                }
                break;

            case "/ig_realtime_sub":
                payload = payload.Substring(payload.IndexOf('{'));
                var container     = JsonConvert.DeserializeObject <JObject>(payload);
                var presenceEvent = container["presence_event"].ToObject <UserPresenceEventArgs>();
                UserPresenceChanged?.Invoke(this, presenceEvent);
                break;
            }


            if (publishPacket.QualityOfService == QualityOfService.AtLeastOnce)
            {
                await WriteAndFlushPacketAsync(PubAckPacket.InResponseTo(publishPacket), outStream);
            }
        }
        async Task ReceiveAndCompleteCommandAsync(IChannel clientChannel, ReadListeningHandler readHandler, IotHubConnectionStringBuilder hubConnectionStringBuilder, Device device)
        {
            var packet = Assert.IsType <PublishPacket>(await readHandler.ReceiveAsync());

            Assert.Equal($"devices/{this.deviceId}/messages/devicebound", packet.TopicName);
            Assert.Equal(MethodContent, Encoding.UTF8.GetString(packet.Payload.ToArray()));

            await clientChannel.WriteAndFlushManyAsync(PubAckPacket.InResponseTo(packet), PubRecPacket.InResponseTo(packet));

            var pubRelQoS2Packet2 = Assert.IsAssignableFrom <PubRelPacket>(await readHandler.ReceiveAsync());

            await clientChannel.WriteAndFlushManyAsync(
                PubCompPacket.InResponseTo(pubRelQoS2Packet2),
                DisconnectPacket.Instance);

            await this.EnsureDeviceQueueLengthAsync(hubConnectionStringBuilder.HostName, device, 0);
        }
            async Task GetPart2SpecificSteps(IChannel channel, ReadListeningHandler readHandler)
            {
                var packets = new Packet[2];
                for (int i = packets.Length - 1; i >= 0; i--)
                {
                    packets[i] = Assert.IsAssignableFrom<Packet>(await readHandler.ReceiveAsync());
                }

                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>());

                await channel.WriteAndFlushManyAsync(
                    PubAckPacket.InResponseTo(qos1Packet),
                    PubCompPacket.InResponseTo(pubRelQos2Packet),
                    DisconnectPacket.Instance);
            }
Example #11
0
        Task SendAckAsync(IChannelHandlerContext context, PublishPacket publish)
        {
            if (Logging.IsEnabled)
            {
                Logging.Enter(this, context.Name, publish, nameof(SendAckAsync));
            }

            try
            {
                this.ResumeReadingIfNecessary(context);
                return(Util.WriteMessageAsync(context, PubAckPacket.InResponseTo(publish), ShutdownOnWriteErrorHandler));
            }
            finally
            {
                if (Logging.IsEnabled)
                {
                    Logging.Exit(this, context.Name, publish, nameof(SendAckAsync));
                }
            }
        }
Example #12
0
        private async void OnMessageReceived(MessageWebSocket sender, MessageWebSocketMessageReceivedEventArgs args)
        {
            if (_pinging?.IsCancellationRequested ?? false)
            {
                return;
            }
            try
            {
                var    dataReader   = args.GetDataReader();
                var    outStream    = sender.OutputStream;
                var    loggedInUser = _instaApi.Session.LoggedInUser;
                Packet packet;
                try
                {
                    packet = StandalonePacketDecoder.DecodePacket(dataReader);
                }
                catch (Exception e)
                {
                    Debug.WriteLine(e);
                    Debug.WriteLine($"{nameof(SyncClient)}: Failed to decode packet.");
                    return;
                }

                switch (packet.PacketType)
                {
                case PacketType.CONNACK:
                    Debug.WriteLine($"{nameof(SyncClient)}: " + packet.PacketType);
                    var subscribePacket = new SubscribePacket(
                        _packetId++,
                        new SubscriptionRequest("/ig_message_sync", QualityOfService.AtMostOnce),
                        new SubscriptionRequest("/ig_send_message_response", QualityOfService.AtMostOnce)
                        );
                    await WriteAndFlushPacketAsync(subscribePacket, outStream);

                    var unsubPacket = new UnsubscribePacket(_packetId++, "/ig_sub_iris_response");
                    await WriteAndFlushPacketAsync(unsubPacket, outStream);

                    subscribePacket = new SubscribePacket(_packetId++,
                                                          new SubscriptionRequest("/ig_sub_iris_response", QualityOfService.AtMostOnce));
                    await WriteAndFlushPacketAsync(subscribePacket, outStream);

                    var random = new Random();
                    var json   = new JObject(
                        new JProperty("seq_id", _seqId),
                        new JProperty("snapshot_at_ms", _snapshotAt.ToUnixTimeMilliseconds()),
                        new JProperty("snapshot_app_version", "web"),
                        new JProperty("subscription_type", "message"));
                    var jsonBytes         = GetJsonBytes(json);
                    var irisPublishPacket = new PublishPacket(QualityOfService.AtLeastOnce, false, false)
                    {
                        PacketId  = _packetId++,
                        TopicName = "/ig_sub_iris",
                        Payload   = Unpooled.CopiedBuffer(jsonBytes)
                    };
                    await WriteAndFlushPacketAsync(irisPublishPacket, outStream);

                    json      = new JObject(new JProperty("unsub", new JArray($"ig/u/v1/{loggedInUser.Pk}")));
                    jsonBytes = GetJsonBytes(json);
                    var pubsubPublishPacket = new PublishPacket(QualityOfService.AtLeastOnce, false, false)
                    {
                        PacketId  = _packetId++,
                        TopicName = "/pubsub",
                        Payload   = Unpooled.CopiedBuffer(jsonBytes)
                    };
                    await WriteAndFlushPacketAsync(pubsubPublishPacket, outStream);

                    unsubPacket = new UnsubscribePacket(_packetId++, "/pubsub");
                    await WriteAndFlushPacketAsync(unsubPacket, outStream);

                    subscribePacket = new SubscribePacket(_packetId++,
                                                          new SubscriptionRequest("/pubsub", QualityOfService.AtMostOnce));
                    await WriteAndFlushPacketAsync(subscribePacket, outStream);

                    json                = new JObject(new JProperty("sub", new JArray($"ig/u/v1/{loggedInUser.Pk}")));
                    jsonBytes           = GetJsonBytes(json);
                    pubsubPublishPacket = new PublishPacket(QualityOfService.AtLeastOnce, false, false)
                    {
                        PacketId  = _packetId++,
                        TopicName = "/pubsub",
                        Payload   = Unpooled.CopiedBuffer(jsonBytes)
                    };
                    await WriteAndFlushPacketAsync(pubsubPublishPacket, outStream);


                    Debug.WriteLine($"{nameof(SyncClient)}: " + packet.PacketType);
                    _ = Task.Run(async() =>
                    {
                        while (!_pinging.IsCancellationRequested)
                        {
                            try
                            {
                                await Task.Delay(TimeSpan.FromSeconds(8), _pinging.Token);
                                var pingPacket = PingReqPacket.Instance;
                                var pingBuffer = StandalonePacketEncoder.EncodePacket(pingPacket);
                                await sender.OutputStream.WriteAsync(pingBuffer);
                                await sender.OutputStream.FlushAsync();
                            }
                            catch (TaskCanceledException)
                            {
                                Debug.WriteLine("Stopped pinging sync server");
                                return;
                            }
                        }
                    });
                    return;

                case PacketType.PUBLISH:
                    var publishPacket = (PublishPacket)packet;
                    var payload       = publishPacket.Payload.ReadString(publishPacket.Payload.ReadableBytes, Encoding.UTF8);
                    if (publishPacket.TopicName == "/ig_message_sync")
                    {
                        var messageSyncPayload = JsonConvert.DeserializeObject <List <MessageSyncEventArgs> >(payload);
                        var latest             = messageSyncPayload.Last();
                        if (latest.SeqId > _seqId ||
                            latest.Data[0].Item.Timestamp > _snapshotAt)
                        {
                            _seqId      = latest.SeqId;
                            _snapshotAt = latest.Data[0].Item.Timestamp;
                        }
                        MessageReceived?.Invoke(this, messageSyncPayload);
                    }
                    Debug.WriteLine($"{nameof(SyncClient)} pub to {publishPacket.TopicName} payload: {payload}");

                    if (publishPacket.QualityOfService == QualityOfService.AtLeastOnce)
                    {
                        await WriteAndFlushPacketAsync(PubAckPacket.InResponseTo(publishPacket), outStream);
                    }
                    return;

                case PacketType.PINGRESP:
                    Debug.WriteLine("Got pong from Sync Client");
                    break;

                default:
                    Debug.WriteLine($"{nameof(SyncClient)}: " + packet.PacketType);
                    break;
                }
            }
            catch (Exception e)
            {
#if !DEBUG
                Crashes.TrackError(e);
#endif
                Debug.WriteLine("Exception occured when processing incoming sync message.");
                Debug.WriteLine(e);
            }
        }
        static async Task RunMqttClientScenarioAsync(IChannel channel, ReadListeningHandler readListener)
        {
            await channel.WriteAndFlushAsync(new ConnectPacket
            {
                ClientId      = ClientId,
                Username      = "******",
                Password      = "******",
                WillTopicName = "last/word",
                WillMessage   = Unpooled.WrappedBuffer(Encoding.UTF8.GetBytes("oops"))
            });

            var connAckPacket = await readListener.ReceiveAsync(DefaultTimeout) as ConnAckPacket;

            Assert.IsNotNull(connAckPacket);
            Assert.AreEqual(ConnectReturnCode.Accepted, connAckPacket.ReturnCode);

            int subscribePacketId   = GetRandomPacketId();
            int unsubscribePacketId = GetRandomPacketId();
            await channel.WriteAndFlushManyAsync(
                new SubscribePacket(subscribePacketId,
                                    new SubscriptionRequest(SubscribeTopicFilter1, QualityOfService.ExactlyOnce),
                                    new SubscriptionRequest(SubscribeTopicFilter2, QualityOfService.AtLeastOnce),
                                    new SubscriptionRequest("for/unsubscribe", QualityOfService.AtMostOnce)),
                new UnsubscribePacket(unsubscribePacketId, "for/unsubscribe"));

            var subAckPacket = await readListener.ReceiveAsync(DefaultTimeout) as SubAckPacket;

            Assert.IsNotNull(subAckPacket);
            Assert.AreEqual(subscribePacketId, subAckPacket.PacketId);
            Assert.AreEqual(3, subAckPacket.ReturnCodes.Count);
            Assert.AreEqual(QualityOfService.ExactlyOnce, subAckPacket.ReturnCodes[0]);
            Assert.AreEqual(QualityOfService.AtLeastOnce, subAckPacket.ReturnCodes[1]);
            Assert.AreEqual(QualityOfService.AtMostOnce, subAckPacket.ReturnCodes[2]);

            var unsubAckPacket = await readListener.ReceiveAsync(DefaultTimeout) as UnsubAckPacket;

            Assert.IsNotNull(unsubAckPacket);
            Assert.AreEqual(unsubscribePacketId, unsubAckPacket.PacketId);

            int publishQoS1PacketId = GetRandomPacketId();
            await channel.WriteAndFlushManyAsync(
                new PublishPacket(QualityOfService.AtMostOnce, false, false)
            {
                TopicName = PublishC2STopic,
                Payload   = Unpooled.WrappedBuffer(Encoding.UTF8.GetBytes(PublishC2SQos0Payload))
            },
                new PublishPacket(QualityOfService.AtLeastOnce, false, false)
            {
                PacketId  = publishQoS1PacketId,
                TopicName = PublishC2SQos1Topic,
                Payload   = Unpooled.WrappedBuffer(Encoding.UTF8.GetBytes(PublishC2SQos1Payload))
            });

            //new PublishPacket(QualityOfService.AtLeastOnce, false, false) { TopicName = "feedback/qos/One", Payload = Unpooled.WrappedBuffer(Encoding.UTF8.GetBytes("QoS 1 test. Different data length.")) });

            var pubAckPacket = await readListener.ReceiveAsync(DefaultTimeout) as PubAckPacket;

            Assert.IsNotNull(pubAckPacket);
            Assert.AreEqual(publishQoS1PacketId, pubAckPacket.PacketId);

            var publishPacket = await readListener.ReceiveAsync(DefaultTimeout) as PublishPacket;

            Assert.IsNotNull(publishPacket);
            Assert.AreEqual(QualityOfService.AtLeastOnce, publishPacket.QualityOfService);
            Assert.AreEqual(PublishS2CQos1Topic, publishPacket.TopicName);
            Assert.AreEqual(PublishS2CQos1Payload, publishPacket.Payload.ToString(Encoding.UTF8));

            await channel.WriteAndFlushManyAsync(
                PubAckPacket.InResponseTo(publishPacket),
                DisconnectPacket.Instance);
        }
 Task SendAckAsync(IChannelHandlerContext context, PublishPacket publish)
 {
     this.ResumeReadingIfNecessary(context);
     return(Util.WriteMessageAsync(context, PubAckPacket.InResponseTo(publish), ShutdownOnWriteErrorHandler));
 }
Example #15
0
        private async Task OnPacketReceived(Packet msg)
        {
            if (!Running)
            {
                return;
            }
            var writer = _outboundWriter;

            try
            {
                switch (msg.PacketType)
                {
                case PacketType.CONNACK:
                    this.Log("Received CONNACK");
                    await SubscribeForDM();
                    await RealtimeSub();
                    await PubSub();

                    if (SnapshotAt != null && SeqId <= 0)
                    {
                        await IrisSub();
                    }
                    StartKeepAliveLoop();
                    break;

                case PacketType.PUBLISH:
                    this.Log("Received PUBLISH");
                    var publishPacket = (PublishPacket)msg;
                    if (publishPacket.Payload == null)
                    {
                        throw new Exception($"{nameof(RealtimeClient)}: Publish packet received but payload is null");
                    }
                    if (publishPacket.QualityOfService == QualityOfService.AtLeastOnce)
                    {
                        await FbnsPacketEncoder.EncodePacket(PubAckPacket.InResponseTo(publishPacket), writer);
                    }


                    var payload = DecompressPayload(publishPacket.Payload);
                    var json    = await GetJsonFromThrift(payload);

                    this.Log($"MQTT json: {json}");
                    if (string.IsNullOrEmpty(json))
                    {
                        break;
                    }
                    try
                    {
                        Debug.WriteLine("");
                        Debug.WriteLine($"Unknown topic received:{msg.PacketType} :  {publishPacket.TopicName} : {json}");


                        Debug.WriteLine("");
                        Debug.WriteLine(json);
                        switch (publishPacket.TopicName)
                        {
                        case "150": break;

                        case "133":         //      /ig_send_message_response
                            try
                            {
                                Responses.AddItem(JsonConvert.DeserializeObject <InstaDirectRespondResponse>(json));
                            }
                            catch
                            {
                                try
                                {
                                    var o = JsonConvert.DeserializeObject <InstaDirectRespondV2Response>(json);
                                    Responses.AddItem(new InstaDirectRespondResponse
                                    {
                                        Action     = o.Action,
                                        Message    = o.Message,
                                        Status     = o.Status,
                                        StatusCode = o.StatusCode,
                                        Payload    = o.Payload[0]
                                    });
                                }
                                catch { }
                            }
                            break;

                        case "88":
                        {
                            var obj = JsonConvert.DeserializeObject <InstaRealtimeRespondResponse>(json);
                            if (obj?.Data?.Length > 0)
                            {
                                var typing = new List <InstaRealtimeTypingEventArgs>();
                                var dm     = new List <InstaDirectInboxItem>();
                                for (int i = 0; i < obj.Data.Length; i++)
                                {
                                    var item = obj.Data[i];
                                    if (item != null)
                                    {
                                        if (item.IsTyping)
                                        {
                                            var typingResponse = JsonConvert.DeserializeObject <InstaRealtimeTypingResponse>(item.Value);
                                            if (typingResponse != null)
                                            {
                                                try
                                                {
                                                    var tr = new InstaRealtimeTypingEventArgs
                                                    {
                                                        SenderId       = typingResponse.SenderId,
                                                        ActivityStatus = typingResponse.ActivityStatus,
                                                        RealtimeOp     = item.Op,
                                                        RealtimePath   = item.Path,
                                                        TimestampUnix  = typingResponse.Timestamp,
                                                        Timestamp      = DateTimeHelper.FromUnixTimeMiliSeconds(typingResponse.Timestamp),
                                                        Ttl            = typingResponse.Ttl
                                                    };
                                                    typing.Add(tr);
                                                }
                                                catch { }
                                            }
                                        }
                                        else if (item.IsThreadItem || item.IsThreadParticipants)
                                        {
                                            if (item.HasItemInValue)
                                            {
                                                var directItemResponse = JsonConvert.DeserializeObject <InstaDirectInboxItemResponse>(item.Value);
                                                if (directItemResponse != null)
                                                {
                                                    try
                                                    {
                                                        var dI = ConvertersFabric.Instance.GetDirectThreadItemConverter(directItemResponse).Convert();
                                                        dI.RealtimeOp   = item.Op;
                                                        dI.RealtimePath = item.Path;
                                                        dm.Add(dI);
                                                    }
                                                    catch { }
                                                }
                                            }
                                            else
                                            {
                                                var dI = new InstaDirectInboxItem
                                                {
                                                    RealtimeOp   = item.Op,
                                                    RealtimePath = item.Path,
                                                    ItemId       = item.Value
                                                };
                                                dm.Add(dI);
                                            }
                                        }
                                    }
                                }
                                if (typing.Count > 0)
                                {
                                    OnTypingChanged(typing);
                                }
                                if (dm.Count > 0)
                                {
                                    OnDirectItemChanged(dm);
                                }
                            }
                        }
                        break;
                        }
                    }
                    catch { }
                    break;

                case PacketType.PUBACK:
                    this.Log("Received PUBACK");
                    break;

                case PacketType.PINGRESP:
                    this.Log("Received PINGRESP");
                    break;

                default:
                    Debug.WriteLine($"Unknown topic received:{msg.PacketType}");
                    break;
                }
            }
            catch (Exception e)
            {
                DebugLogger.LogExceptionX(e);
            }
        }
Example #16
0
            async Task GetPart1SpecificSteps(IChannel channel, ReadListeningHandler readHandler)
            {
                int publishQoS1PacketId = 1003;
                await channel.WriteAndFlushManyAsync(
                    new PublishPacket(QualityOfService.AtMostOnce, false, false)
                {
                    //TopicName = string.Format("devices/{0}/messages/log/verbose/", clientId),
                    TopicName = $"devices/{this.clientId}/messages/events",
                    Payload   = Unpooled.WrappedBuffer(Encoding.UTF8.GetBytes("{\"test\": \"telemetry-QoS0\"}"))
                },
                    new PublishPacket(QualityOfService.AtLeastOnce, false, false)
                {
                    PacketId  = publishQoS1PacketId,
                    TopicName = $"devices/{this.clientId}/messages/events",
                    Payload   = Unpooled.WrappedBuffer(Encoding.UTF8.GetBytes("{\"test\": \"telemetry\"}"))
                });

                Packet[] packets = (await Task.WhenAll(Enumerable.Repeat(0, 6).Select(_ => readHandler.ReceiveAsync())))
                                   .Select(Assert.IsAssignableFrom <Packet>)
                                   .ToArray();

                PubAckPacket pubAckPacket = Assert.Single(packets.OfType <PubAckPacket>());

                Assert.Equal(publishQoS1PacketId, pubAckPacket.PacketId);

                PublishPacket publishQoS0Packet = Assert.Single(packets.OfType <PublishPacket>().Where(x => x.QualityOfService == QualityOfService.AtMostOnce));

                this.AssertPacketCoreValue(publishQoS0Packet, "tips", NotificationQoS0Content);

                PublishPacket[] publishQoS1Packets = packets.OfType <PublishPacket>().Where(x => x.QualityOfService == QualityOfService.AtLeastOnce).ToArray();
                Assert.Equal(2, publishQoS1Packets.Length);
                var qos1Notification = Assert.Single(publishQoS1Packets, x => x.TopicName.EndsWith("firmware-update"));

                this.AssertPacketCoreValue(qos1Notification, "firmware-update", NotificationQoS1Content);
                var methodCall = Assert.Single(publishQoS1Packets, x => x.TopicName.EndsWith("commands"));

                this.AssertPacketCoreValue(methodCall, "commands", MethodCallContent);

                PublishPacket[] publishQoS2Packets = packets.OfType <PublishPacket>().Where(x => x.QualityOfService == QualityOfService.ExactlyOnce).ToArray();
                Assert.Equal(2, publishQoS2Packets.Length);
                PublishPacket publishQoS2Packet1 = publishQoS2Packets[0];

                this.AssertPacketCoreValue(publishQoS2Packet1, "critical-alert", NotificationQoS2Content);
                PublishPacket publishQoS2Packet2 = publishQoS2Packets[1];

                this.AssertPacketCoreValue(publishQoS2Packet2, string.Empty, NotificationQoS2Content2);

                await channel.WriteAndFlushManyAsync(
                    PubAckPacket.InResponseTo(qos1Notification),
                    PubAckPacket.InResponseTo(methodCall),
                    PubRecPacket.InResponseTo(publishQoS2Packet1),
                    PubRecPacket.InResponseTo(publishQoS2Packet2));

                var pubRelQoS2Packet1 = Assert.IsAssignableFrom <PubRelPacket>(await readHandler.ReceiveAsync());

                Assert.Equal(publishQoS2Packet1.PacketId, pubRelQoS2Packet1.PacketId);

                var pubRelQoS2Packet2 = Assert.IsAssignableFrom <PubRelPacket>(await readHandler.ReceiveAsync());

                Assert.Equal(publishQoS2Packet2.PacketId, pubRelQoS2Packet2.PacketId);

                await channel.WriteAndFlushManyAsync(
                    PubCompPacket.InResponseTo(pubRelQoS2Packet1),
                    DisconnectPacket.Instance);

                // device queue still contains QoS 2 packet 2 which was PUBRECed but not PUBCOMPed.
            }
Example #17
0
        private async Task OnPacketReceived(Packet msg)
        {
            if (!Running)
            {
                return;
            }
            var writer = _outboundWriter;

            try
            {
                switch (msg.PacketType)
                {
                case PacketType.CONNACK:
                    this.Log("Received CONNACK");
                    ConnectionData.UpdateAuth(((FbnsConnAckPacket)msg).Authentication);
                    await RegisterMqttClient();

                    break;

                case PacketType.PUBLISH:
                    this.Log("Received PUBLISH");
                    var publishPacket = (PublishPacket)msg;
                    if (publishPacket.Payload == null)
                    {
                        throw new Exception($"{nameof(PushClient)}: Publish packet received but payload is null");
                    }
                    if (publishPacket.QualityOfService == QualityOfService.AtLeastOnce)
                    {
                        await FbnsPacketEncoder.EncodePacket(PubAckPacket.InResponseTo(publishPacket), writer);
                    }

                    var payload = DecompressPayload(publishPacket.Payload);
                    var json    = Encoding.UTF8.GetString(payload);
                    this.Log($"MQTT json: {json}");
                    switch (Enum.Parse(typeof(TopicIds), publishPacket.TopicName))
                    {
                    case TopicIds.Message:
                        try
                        {
                            var message = JsonConvert.DeserializeObject <PushReceivedEventArgs>(json);
                            message.Json = json;
                            if (message.NotificationContent.CollapseKey == "direct_v2_message")
                            {
                                MessageReceived?.Invoke(this, message);
                            }
                        }
                        catch (Exception e)
                        {
                            // If something wrong happens here we don't need to shut down the whole push client
                            DebugLogger.LogException(e);
                        }
                        break;

                    case TopicIds.RegResp:
                        await OnRegisterResponse(json);

                        StartKeepAliveLoop();
                        break;

                    default:
                        this.Log($"Unknown topic received: {publishPacket.TopicName}");
                        break;
                    }

                    break;

                case PacketType.PUBACK:
                    this.Log("Received PUBACK");
                    _waitingForPubAck = false;
                    break;

                case PacketType.PINGRESP:
                    this.Log("Received PINGRESP");
                    break;

                default:
                    throw new NotSupportedException($"Packet type {msg.PacketType} is not supported.");
                }
            }
            catch (Exception e)
            {
                DebugLogger.LogException(e);
            }
        }
Example #18
0
        IEnumerable <TestScenarioStep> GetMqttClientScenario(Func <object> currentMessageFunc)
        {
            yield return(TestScenarioStep.Message(new ConnectPacket
            {
                ClientId = ClientId,
                Username = "******",
                Password = "******",
                WillTopicName = "last/word",
                WillMessage = Unpooled.WrappedBuffer(Encoding.UTF8.GetBytes("oops"))
            }));

            var connAckPacket = Assert.IsType <ConnAckPacket>(currentMessageFunc());

            Assert.Equal(ConnectReturnCode.Accepted, connAckPacket.ReturnCode);

            int subscribePacketId   = GetRandomPacketId();
            int unsubscribePacketId = GetRandomPacketId();

            yield return(TestScenarioStep.Messages(
                             new SubscribePacket(subscribePacketId,
                                                 new SubscriptionRequest(SubscribeTopicFilter1, QualityOfService.ExactlyOnce),
                                                 new SubscriptionRequest(SubscribeTopicFilter2, QualityOfService.AtLeastOnce),
                                                 new SubscriptionRequest("for/unsubscribe", QualityOfService.AtMostOnce)),
                             new UnsubscribePacket(unsubscribePacketId, "for/unsubscribe")));

            var subAckPacket = Assert.IsType <SubAckPacket>(currentMessageFunc());

            Assert.Equal(subscribePacketId, subAckPacket.PacketId);
            Assert.Equal(3, subAckPacket.ReturnCodes.Count);
            Assert.Equal(QualityOfService.ExactlyOnce, subAckPacket.ReturnCodes[0]);
            Assert.Equal(QualityOfService.AtLeastOnce, subAckPacket.ReturnCodes[1]);
            Assert.Equal(QualityOfService.AtMostOnce, subAckPacket.ReturnCodes[2]);

            yield return(TestScenarioStep.MoreFeedbackExpected());

            var unsubAckPacket = Assert.IsType <UnsubAckPacket>(currentMessageFunc());

            Assert.Equal(unsubscribePacketId, unsubAckPacket.PacketId);

            int publishQoS1PacketId = GetRandomPacketId();

            yield return(TestScenarioStep.Messages(
                             new PublishPacket(QualityOfService.AtMostOnce, false, false)
            {
                TopicName = PublishC2STopic,
                Payload = Unpooled.WrappedBuffer(Encoding.UTF8.GetBytes(PublishC2SQos0Payload))
            },
                             new PublishPacket(QualityOfService.AtLeastOnce, false, false)
            {
                PacketId = publishQoS1PacketId,
                TopicName = PublishC2SQos1Topic,
                Payload = Unpooled.WrappedBuffer(Encoding.UTF8.GetBytes(PublishC2SQos1Payload))
            }));

            //new PublishPacket(QualityOfService.AtLeastOnce, false, false) { TopicName = "feedback/qos/One", Payload = Unpooled.WrappedBuffer(Encoding.UTF8.GetBytes("QoS 1 test. Different data length.")) });

            var pubAckPacket = Assert.IsType <PubAckPacket>(currentMessageFunc());

            Assert.Equal(publishQoS1PacketId, pubAckPacket.PacketId);

            yield return(TestScenarioStep.MoreFeedbackExpected());

            var publishPacket = Assert.IsType <PublishPacket>(currentMessageFunc());

            Assert.Equal(QualityOfService.AtLeastOnce, publishPacket.QualityOfService);
            Assert.Equal(PublishS2CQos1Topic, publishPacket.TopicName);
            Assert.Equal(PublishS2CQos1Payload, Encoding.UTF8.GetString(publishPacket.Payload.ToArray()));

            yield return(TestScenarioStep.Messages(
                             PubAckPacket.InResponseTo(publishPacket),
                             DisconnectPacket.Instance));
        }
        static IEnumerable <TestScenarioStep> GetClientScenario(Func <object> currentMessageFunc, string iotHubName, string clientId, string password)
        {
            yield return(TestScenarioStep.Write(new ConnectPacket
            {
                ClientId = clientId,
                HasUsername = true,
                Username = iotHubName + "/" + clientId,
                HasPassword = true,
                Password = password,
                KeepAliveInSeconds = 120,
                HasWill = true,
                WillTopicName = "last/word",
                WillMessage = Unpooled.WrappedBuffer(Encoding.UTF8.GetBytes("oops"))
            }));

            var connAckPacket = Assert.IsType <ConnAckPacket>(currentMessageFunc());

            Assert.Equal(ConnectReturnCode.Accepted, connAckPacket.ReturnCode);

            int subscribePacketId = GetRandomPacketId();

            yield return(TestScenarioStep.Write(new SubscribePacket
            {
                PacketId = subscribePacketId,
                Requests = new[]
                {
                    new SubscriptionRequest(string.Format("devices/{0}/messages/devicebound/#", clientId), QualityOfService.ExactlyOnce)
                }
            }));

            var subAckPacket = Assert.IsType <SubAckPacket>(currentMessageFunc());

            Assert.Equal(subscribePacketId, subAckPacket.PacketId);
            Assert.Equal(1, subAckPacket.ReturnCodes.Count);
            Assert.Equal(QualityOfService.ExactlyOnce, subAckPacket.ReturnCodes[0]);

            int publishQoS1PacketId = GetRandomPacketId();

            yield return(TestScenarioStep.Write(
                             new PublishPacket(QualityOfService.AtMostOnce, false, false)
            {
                //TopicName = string.Format("devices/{0}/messages/log/verbose/", clientId),
                TopicName = string.Format("devices/{0}/messages/events", clientId),
                Payload = Unpooled.WrappedBuffer(Encoding.UTF8.GetBytes("{\"test\": \"telemetry-QoS0\"}"))
            },
                             new PublishPacket(QualityOfService.AtLeastOnce, false, false)
            {
                PacketId = publishQoS1PacketId,
                TopicName = string.Format("devices/{0}/messages/events", clientId),
                Payload = Unpooled.WrappedBuffer(Encoding.UTF8.GetBytes("{\"test\": \"telemetry\"}"))
            }));

            var packets = new Packet[4];

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

            PubAckPacket pubAckPacket = Assert.Single(packets.OfType <PubAckPacket>());

            Assert.Equal(publishQoS1PacketId, pubAckPacket.PacketId);

            PublishPacket publishQoS0Packet = Assert.Single(packets.OfType <PublishPacket>().Where(x => x.QualityOfService == QualityOfService.AtMostOnce));

            //Assert.Equal(string.Format("devices/{0}/messages/devicebound/tips", clientId), publishQoS0Packet.TopicName);
            Assert.Equal(string.Format("devices/{0}/messages/devicebound", clientId), publishQoS0Packet.TopicName);
            Assert.Equal(NotificationQoS0Content, Encoding.UTF8.GetString(publishQoS0Packet.Payload.ToArray()));

            PublishPacket publishQoS1Packet = Assert.Single(packets.OfType <PublishPacket>().Where(x => x.QualityOfService == QualityOfService.AtLeastOnce));

            //Assert.Equal(string.Format("devices/{0}/messages/devicebound/firmware-update", clientId), publishQoS1Packet.TopicName);
            Assert.Equal(string.Format("devices/{0}/messages/devicebound", clientId), publishQoS1Packet.TopicName);
            Assert.Equal(NotificationQoS1Content, Encoding.UTF8.GetString(publishQoS1Packet.Payload.ToArray()));

            PublishPacket publishQoS2Packet = Assert.Single(packets.OfType <PublishPacket>().Where(x => x.QualityOfService == QualityOfService.ExactlyOnce));

            //Assert.Equal(string.Format("devices/{0}/messages/devicebound/critical-alert", clientId), publishQoS2Packet.TopicName);
            Assert.Equal(string.Format("devices/{0}/messages/devicebound", clientId), publishQoS2Packet.TopicName);
            Assert.Equal(NotificationQoS2Content, Encoding.UTF8.GetString(publishQoS2Packet.Payload.ToArray()));

            yield return(TestScenarioStep.Write(
                             PubAckPacket.InResponseTo(publishQoS1Packet),
                             PubRecPacket.InResponseTo(publishQoS2Packet)));

            var pubRelQoS2Packet = Assert.IsAssignableFrom <PubRelPacket>(currentMessageFunc());

            Assert.Equal(publishQoS2Packet.PacketId, pubRelQoS2Packet.PacketId);

            yield return(TestScenarioStep.Write(
                             false, // it is a final step and we do not expect response
                             PubCompPacket.InResponseTo(pubRelQoS2Packet),
                             DisconnectPacket.Instance));
        }
Example #20
0
        private async Task OnPacketReceived(Packet msg)
        {
            try
            {
                switch (msg.PacketType)
                {
                case PacketType.CONNACK:
                    Log($"[{_instaApi.GetLoggedUser().UserName}] " + "Received CONNACK");
                    ConnectionData.UpdateAuth(((FbnsConnAckPacket)msg).Authentication);
                    await RegisterMqttClient();

                    break;

                case PacketType.PUBLISH:
                    Log($"[{_instaApi.GetLoggedUser().UserName}] " + "Received PUBLISH");
                    var publishPacket = (PublishPacket)msg;
                    if (publishPacket.Payload == null)
                    {
                        throw new Exception($"{nameof(PushClient)}: Publish packet received but payload is null");
                    }
                    if (publishPacket.QualityOfService == QualityOfService.AtLeastOnce)
                    {
                        await FbnsPacketEncoder.EncodePacket(PubAckPacket.InResponseTo(publishPacket), _outboundWriter);
                    }

                    var payload = DecompressPayload(publishPacket.Payload);
                    var json    = Encoding.UTF8.GetString(payload);
                    Log($"[{_instaApi.GetLoggedUser().UserName}] " + $"MQTT json: {json}");
                    switch (Enum.Parse(typeof(TopicIds), publishPacket.TopicName))
                    {
                    case TopicIds.Message:
                        var message = JsonConvert.DeserializeObject <PushReceivedEventArgs>(json);
                        message.Json     = json;
                        message.InstaApi = _instaApi;
                        MessageReceived?.Invoke(this, message);
                        break;

                    case TopicIds.RegResp:
                        await OnRegisterResponse(json);

                        StartKeepAliveLoop();
                        break;

                    default:
                        Log($"[{_instaApi.GetLoggedUser().UserName}] " + $"Unknown topic received: {publishPacket.TopicName}");
                        break;
                    }

                    break;

                case PacketType.PUBACK:
                    Log($"[{_instaApi.GetLoggedUser().UserName}] " + "Received PUBACK");
                    _waitingForPubAck = false;
                    break;

                // todo: PingResp never arrives even though data was received. Decoder problem?
                case PacketType.PINGRESP:
                    Log($"[{_instaApi.GetLoggedUser().UserName}] " + "Received PINGRESP");
                    break;

                default: return;
                    //throw new NotSupportedException($"Packet type {msg.PacketType} is not supported.");
                }
            }
            catch (Exception ex)
            {
                PrintException("SendPing", ex);
                Shutdown();
            }
        }
Example #21
0
        protected override async void ChannelRead0(IChannelHandlerContext ctx, Packet msg)
        {
            try
            {
                _context = ctx; // Save context for manual Ping later
                switch (msg.PacketType)
                {
                case PacketType.CONNACK:
                    Debug.WriteLine($"{nameof(PushClient)}:\tCONNACK received.");
                    ConnectionData.UpdateAuth(((FbnsConnAckPacket)msg).Authentication);
                    RegisterMqttClient(ctx);
                    break;

                case PacketType.PUBLISH:
                    Debug.WriteLine($"{nameof(PushClient)}:\tPUBLISH received.");
                    var publishPacket = (PublishPacket)msg;
                    if (publishPacket.QualityOfService == QualityOfService.AtLeastOnce)
                    {
                        await ctx.WriteAndFlushAsync(PubAckPacket.InResponseTo(publishPacket));
                    }

                    var payload = DecompressPayload(publishPacket.Payload);
                    var json    = Encoding.UTF8.GetString(payload);
                    Debug.WriteLine($"{nameof(PushClient)}:\tMQTT json: {json}");
                    switch (Enum.Parse(typeof(TopicIds), publishPacket.TopicName))
                    {
                    case TopicIds.Message:
                        var message = JsonConvert.DeserializeObject <PushReceivedEventArgs>(json);
                        message.Json = json;
                        OnMessageReceived(message);
                        break;

                    case TopicIds.RegResp:
                        OnRegisterResponse(json);
                        try
                        {
                            await _context.Executor.Schedule(KeepAliveLoop,
                                                             TimeSpan.FromSeconds(KEEP_ALIVE - 60));
                        }
                        catch (TaskCanceledException)
                        {
                            // pass
                        }

                        break;

                    default:
                        Debug.WriteLine($"Unknown topic received: {publishPacket.TopicName}", "Warning");
                        break;
                    }

                    break;

                case PacketType.PUBACK:
                    Debug.WriteLine($"{nameof(PushClient)}:\tPUBACK received.");
                    _waitingForPubAck = false;
                    break;

                // todo: PingResp never arrives even though data was received. Decoder problem?
                case PacketType.PINGRESP:
                    Debug.WriteLine($"{nameof(PushClient)}:\tPINGRESP received.");
                    break;

                default:
                    throw new NotSupportedException($"Packet type {msg.PacketType} is not supported.");
                }
            }
            catch (Exception e)
            {
                // Something went wrong with Push client. Shutting down.
#if !DEBUG
                Crashes.TrackError(e);
#endif
                await Shutdown().ConfigureAwait(false);
            }
        }
            IEnumerable <TestScenarioStep> GetPart1SpecificSteps(Func <object> currentMessageFunc)
            {
                int publishQoS1PacketId = GetRandomPacketId();

                yield return(TestScenarioStep.Write(
                                 new PublishPacket(QualityOfService.AtMostOnce, false, false)
                {
                    //TopicName = string.Format("devices/{0}/messages/log/verbose/", clientId),
                    TopicName = $"devices/{this.clientId}/messages/events",
                    Payload = Unpooled.WrappedBuffer(Encoding.UTF8.GetBytes("{\"test\": \"telemetry-QoS0\"}"))
                },
                                 new PublishPacket(QualityOfService.AtLeastOnce, false, false)
                {
                    PacketId = publishQoS1PacketId,
                    TopicName = $"devices/{this.clientId}/messages/events",
                    Payload = Unpooled.WrappedBuffer(Encoding.UTF8.GetBytes("{\"test\": \"telemetry\"}"))
                }));

                var packets = new Packet[5];

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

                PubAckPacket pubAckPacket = Assert.Single(packets.OfType <PubAckPacket>());

                Assert.Equal(publishQoS1PacketId, pubAckPacket.PacketId);

                PublishPacket publishQoS0Packet = Assert.Single(packets.OfType <PublishPacket>().Where(x => x.QualityOfService == QualityOfService.AtMostOnce));

                this.AssertPacketCoreValue(publishQoS0Packet, NotificationQoS0Content);

                PublishPacket publishQoS1Packet = Assert.Single(packets.OfType <PublishPacket>().Where(x => x.QualityOfService == QualityOfService.AtLeastOnce));

                this.AssertPacketCoreValue(publishQoS1Packet, NotificationQoS1Content);

                PublishPacket[] publishQoS2Packets = packets.OfType <PublishPacket>().Where(x => x.QualityOfService == QualityOfService.ExactlyOnce).Reverse().ToArray();
                Assert.Equal(2, publishQoS2Packets.Length);
                PublishPacket publishQoS2Packet1 = publishQoS2Packets[0];

                this.AssertPacketCoreValue(publishQoS2Packet1, NotificationQoS2Content);
                PublishPacket publishQoS2Packet2 = publishQoS2Packets[1];

                this.AssertPacketCoreValue(publishQoS2Packet2, NotificationQoS2Content2);

                yield return(TestScenarioStep.Write(
                                 PubAckPacket.InResponseTo(publishQoS1Packet),
                                 PubRecPacket.InResponseTo(publishQoS2Packet1),
                                 PubRecPacket.InResponseTo(publishQoS2Packet2)));

                var pubRelQoS2Packet1 = Assert.IsAssignableFrom <PubRelPacket>(currentMessageFunc());

                Assert.Equal(publishQoS2Packet1.PacketId, pubRelQoS2Packet1.PacketId);

                yield return(TestScenarioStep.ReadMore());

                var pubRelQoS2Packet2 = Assert.IsAssignableFrom <PubRelPacket>(currentMessageFunc());

                Assert.Equal(publishQoS2Packet2.PacketId, pubRelQoS2Packet2.PacketId);

                yield return(TestScenarioStep.Write(
                                 false, // it is a final step and we do not expect response
                                 PubCompPacket.InResponseTo(pubRelQoS2Packet1),
                                 DisconnectPacket.Instance));

                // device queue still contains QoS 2 packet 2 which was PUBRECed but not PUBCOMPed.
            }