public void ResendMessagePartsTest()
        {
            try
            {
                byte[] indexes = new byte[] { 8, 9, 19, 20, 21, 78 };
                byte   group   = 159;

                var bytes   = MessageAckMT.Create(ProtocolVersion.v3__WeatherExtension, group, indexes).Pack()[0].Payload;
                var message = Message.Unpack(bytes) as MessageAckMT;

                if (message.TargetGroup != group || !message.ResendIndexes.SequenceEqual(indexes))
                {
                    Assert.Fail();
                }
            }
            catch (Exception e)
            {
            }
        }
        public async Task <ushort> SendData(byte[] data)
        {
            try
            {
                await locker.WaitAsync();

                await Task.Delay(1000);


                ushort _messageId   = (ushort)storage.GetShort(device.Id, "message-id", 0);
                var    ___messageId = _messageId + 1;
                storage.PutShort(device.Id, "message-id", (short)___messageId);

                i++;

                if (i % 8 == 0)
                {
                    throw new Exception("Dummy send error");
                }


                var m = Message.Unpack(data, new InMemoryBuffer());

                if (m is BalanceMO balance)
                {
                    thread.PostDelayed(() =>
                    {
                        var balanceMT = BalanceMT.Create(ProtocolVersion.v3__WeatherExtension, DateTime.UtcNow, DateTime.UtcNow.AddDays(-12), DateTime.UtcNow.AddDays(30), 672, 1000, 328).Pack();

                        PacketReceived(this, new PacketReceivedEventArgs()
                        {
                            Payload   = balanceMT[0].Payload,
                            MessageId = (short)(10006 + ___messageId),
                        });
                    }, TimeSpan.FromSeconds(15));
                }
                if (m is MessageSentMO sent)
                {
                    thread.PostDelayed(() =>
                    {
                        var resendIndexes = new byte[resendParts];
                        for (int k = 0; k < resendParts; k++)
                        {
                            resendIndexes[k] = (byte)k;
                        }

                        resendParts -= 2;

                        if (resendParts < 0)
                        {
                            resendParts = 2;
                        }

                        var ack = MessageAckMT.Create(ProtocolVersion.v3__WeatherExtension, (byte)sent.SentGroup, resendIndexes).Pack();

                        PacketReceived(this, new PacketReceivedEventArgs()
                        {
                            Payload   = ack[0].Payload,
                            MessageId = (short)(10005 + ___messageId),
                        });
                    }, TimeSpan.FromSeconds(10));
                }


                thread.Post(async() =>
                {
                    await Task.Delay(TimeSpan.FromSeconds(4));


                    PacketStatusUpdated(this, new PacketStatusUpdatedEventArgs()
                    {
                        MessageId = (short)_messageId,
                        Status    = MessageStatus.Transmitted,
                    });


                    //await Task.Delay(TimeSpan.FromSeconds(6));


                    //var m = Message.Unpack(data) as ChatMessageMO;

                    //if (m != null && m.TotalParts == 1)
                    //{
                    //var p = ChatMessageMT.Create(m.Version, m.Subscriber, m.Id, m.Conversation, m.Text, m.Lat, m.Lon, m.Alt, m.ByskyToken, m.File, m.FileExtension, m.ImageQuality, m.Subject).Pack();

                    //PacketReceived(this, new PacketReceivedEventArgs()
                    //{
                    //    Payload = p[0].Payload,
                    //    MessageId = (short)(10000 + ___messageId),
                    //});
                    //}
                });

                return(_messageId);
            }
            finally
            {
                locker.Release();
            }
        }