Example #1
0
        public void Open(int listeningPort, string remoteHostname, int remotePort, MessageReceivedDelegate callback, ErrorHandlerDelegate errorHandler,
                         int minWaitMsBetweenSend = 20)
        {
            if (_plugin != null)
            {
                throw new Exception("UdpServer was already started.");
            }

            MinWaitMsBetweenSend = minWaitMsBetweenSend;
            _messageReceived     = callback;
            _errorHandler        = errorHandler;

            _plugin = new UdpClient(listeningPort);
            _plugin.Connect(remoteHostname, remotePort);
            _remoteIpEndPoint = new IPEndPoint(IPAddress.Any, remotePort);
            Opened            = true;

            _processMessagesThread = new Thread(ProcessMessages)
            {
                Name = "ProcessMessages"
            };
            _processMessagesThread.Start();

            _receiveMessagesThread = new Thread(ReceiveMessages)
            {
                Name = "ReceiveMessages"
            };
            _receiveMessagesThread.Start();

            _sendMessagesThread = new Thread(SendMessages)
            {
                Name = "SendMessages"
            };
            _sendMessagesThread.Start();
        }
Example #2
0
    IEnumerator SendMessageWithAckOrTimeoutCr <T>(T message, DieMessageType ackType, float timeOut, System.Action <DieMessage> ackAction, System.Action timeoutAction)
        where T : DieMessage
    {
        DieMessage ackMessage            = null;
        float      startTime             = Time.time;
        MessageReceivedDelegate callback = (ackMsg) =>
        {
            ackMessage = ackMsg;
        };

        AddMessageHandler(ackType, callback);
        byte[] msgBytes = DieMessages.ToByteArray(message);
        DicePool.Instance.WriteDie(this, msgBytes, msgBytes.Length, null);
        while (ackMessage == null && Time.time < startTime + timeOut)
        {
            yield return(null);
        }
        RemoveMessageHandler(ackType, callback);
        if (ackMessage != null)
        {
            ackAction?.Invoke(ackMessage);
        }
        else
        {
            timeoutAction?.Invoke();
        }
    }
Example #3
0
        internal IOManager(string portname,
                           MessageReceivedDelegate messageDelegate = null,
                           ErrorReceivedDelegate errorDelegate     = null,
                           EventReceivedDelegate eventDelegate     = null)
        {
            this.messageDelegate = messageDelegate;
            this.errorDelegate   = errorDelegate;
            this.eventDelegate   = eventDelegate;
            Port = portname;

            _serialPort = new SerialPort
            {
                PortName     = portname,
                BaudRate     = baudrate,
                Parity       = parity,
                ReadTimeout  = IO_TIMEOUT,
                WriteTimeout = IO_TIMEOUT
            };

            try
            {
                _serialPort.Open();
                _serialPort.DataReceived += DataReceivedHandler;
            }
            catch (Exception e)
            {
                _serialPort.Close();
                LogManager.WriteException($"{_serialPort.PortName} Open exception:", e);
                throw;
            }
        }
Example #4
0
    void RemoveMessageHandler(DieMessageType msgType, MessageReceivedDelegate newDel)
    {
        MessageReceivedDelegate del;

        if (messageDelegates.TryGetValue(msgType, out del))
        {
            del -= newDel;
        }
    }
Example #5
0
 internal CommandsManager(
     MessageReceivedDelegate messageDelegate = null,
     ErrorReceivedDelegate errorDelegate     = null,
     EventReceivedDelegate eventDelegate     = null)
 {
     this.messageDelegate = messageDelegate;
     this.errorDelegate   = errorDelegate;
     this.eventDelegate   = eventDelegate;
 }
Example #6
0
 /// <summary>
 /// 檢查註冊TopicSubscriber的OnMessageReceived事件被註冊的數量
 /// </summary>
 /// <param name="topicSubscriber">實作的TopicSubscriber物件</param>
 /// <returns>被註冊的數量</returns>
 private int CheckMessageReceivedDelegateCount(TopicSubscriber topicSubscriber)
 {
     try
     {
         MessageReceivedDelegate <string> dele = this.GetObjectDele <TopicSubscriber, MessageReceivedDelegate <string> >(topicSubscriber, "OnMessageReceived");
         return(dele.GetInvocationList().Length);
     }
     catch (Exception ex)
     {
         throw ex;
     }
 }
Example #7
0
        public override void Init()
        {
            // Ensure that the base init method is called. It establishes a connection with the broker.
            base.Init();

            connectionInfo = QpidConnectionInfo.FromUrl(connectionUri);
            _connection    = new AMQConnection(connectionInfo);
            _channel       = _connection.CreateChannel(false, AcknowledgeMode.AutoAcknowledge, 500, 300);

            _logger.Info("Starting...");
            _logger.Info("Exchange name is '" + _exchangeName + "'...");

            // Register this to listen for exceptions on the test connection.
            _exceptionDelegate             = new ExceptionListenerDelegate(OnException);
            _connection.ExceptionListener += _exceptionDelegate;

            // Declare a new headers exchange with the name of the test service.
            _channel.DeclareExchange(_exchangeName, ExchangeClassConstants.HEADERS);

            // Create a non-durable, temporary (aka auto-delete), exclusive queue.
            string queueName = _channel.GenerateUniqueName();

            _channel.DeclareQueue(queueName, false, true, true);

            // Bind the queue to the new headers exchange, setting up some header patterns for the exchange to match.
            _channel.Bind(queueName, _exchangeName, null, CreatePatternAsFieldTable());

            // Create a test consumer to consume messages from the test exchange.
            _consumer = _channel.CreateConsumerBuilder(queueName)
                        .WithPrefetchLow(100)
                        .WithPrefetchHigh(500)
                        .WithNoLocal(false) // make sure we get our own messages
                        .Create();

            // Register this to listen for messages on the consumer.
            _msgRecDelegate      = new MessageReceivedDelegate(OnMessage);
            _consumer.OnMessage += _msgRecDelegate;

            // Clear the most recent message and exception.
            _lastException = null;
            _lastMessage   = null;

            _publisher = _channel.CreatePublisherBuilder()
                         .WithExchangeName(_exchangeName)
                         .WithMandatory(true)
                         .Create();

            _publisher.DeliveryMode = DeliveryMode.NonPersistent;

            // Start all channel
            _connection.Start();
        }
Example #8
0
    void AddMessageHandler(DieMessageType msgType, MessageReceivedDelegate newDel)
    {
        MessageReceivedDelegate del;

        if (messageDelegates.TryGetValue(msgType, out del))
        {
            del += newDel;
        }
        else
        {
            messageDelegates.Add(msgType, newDel);
        }
    }
        public MessageReceiveLoop(IMessageSerialization messageSerialization, ISocket socket, 
            MessageReceivedDelegate messageReceivedDelegate, SocketExceptionDelegate onExceptionDelegate)
        {
            if (messageSerialization == null) throw new ArgumentNullException("messageSerialization");
            if (socket == null) throw new ArgumentNullException("socket");
            if (messageReceivedDelegate == null) throw new ArgumentNullException("messageReceivedDelegate");

            _socket = socket;
            _messageFrameReceiver = new MessageFrameReceiver(socket);
            _messageSerialization = messageSerialization;
            _messageReceivedDelegate = messageReceivedDelegate;
            _socketExceptionDelegate = onExceptionDelegate;
        }
 /// <summary>
 /// Set up a queue to listen for reports on.
 /// </summary>
 public IMessageConsumer CreateQListener(string routingKey, string exchangeNameDefaults,
                                         MessageReceivedDelegate handler)
 {
     string responseQueueName = null;
     return CreateListener(responseQueueName, routingKey, exchangeNameDefaults,
                           ToExchangeClass(exchangeNameDefaults), false, true, true, handler);
     responseQueueName = responseQueueName ?? channel.GenerateUniqueName();
     channel.DeclareQueue(responseQueueName, false, true, true);
     // Set this listener up to listen for reports on the response queue.
     channel.Bind(responseQueueName, exchangeNameDefaults, routingKey);
     //channel.Bind(responseQueueName, "<<default>>", RESPONSE_ROUTING_KEY);
     IMessageConsumer consumer = channel.CreateConsumerBuilder(responseQueueName).Create();
     consumer.OnMessage += new MessageReceivedDelegate(handler);
     return consumer;
 }
Example #11
0
    void RemoveMessageHandler(DieMessageType msgType, MessageReceivedDelegate newDel)
    {
        MessageReceivedDelegate del;

        if (messageDelegates.TryGetValue(msgType, out del))
        {
            del -= newDel;
            if (del == null)
            {
                messageDelegates.Remove(msgType);
            }
            else
            {
                messageDelegates[msgType] = del;
            }
        }
    }
Example #12
0
    IEnumerator SendMessageWithAck <T>(T message, DieMessageType ackType)
        where T : DieMessage
    {
        bool msgReceived = false;
        MessageReceivedDelegate callback = (ackMsg) =>
        {
            msgReceived = true;
        };

        AddMessageHandler(ackType, callback);
        byte[] msgBytes = DieMessages.ToByteArray(message);
        _sendBytes.SendBytes(this, msgBytes, msgBytes.Length, null);

        yield return(new WaitUntil(() => msgReceived));

        RemoveMessageHandler(ackType, callback);
    }
Example #13
0
    IEnumerator DownloadBulkDataCr(System.Action <byte[]> onBufferReady)
    {
        // Wait for setup message
        short size = 0;

        yield return(StartCoroutine(WaitForMessageCr(DieMessageType.BulkSetup, (msg) =>
        {
            var setupMsg = (DieMessageBulkSetup)msg;
            size = setupMsg.size;
        })));

        // Allocate a byte buffer
        byte[] buffer            = new byte[size];
        ushort totalDataReceived = 0;

        // Setup bulk receive handler
        MessageReceivedDelegate bulkReceived = (msg) =>
        {
            var bulkMsg = (DieMessageBulkData)msg;
            System.Array.Copy(bulkMsg.data, 0, buffer, bulkMsg.offset, bulkMsg.size);

            // Create acknowledge message now
            var msgAck = new DieMessageBulkDataAck();
            msgAck.offset = totalDataReceived;

            // Sum data receive before sending any other message
            totalDataReceived += bulkMsg.size;

            // Send acknowledgment (no need to do it synchronously)
            PostMessage(msgAck);
        };

        AddMessageHandler(DieMessageType.BulkData, bulkReceived);

        // Send acknowledgement to the die, so it may transfer bulk data immediately
        PostMessage(new DieMessageBulkSetupAck());

        // Wait for all the bulk data to be received
        yield return(new WaitUntil(() => totalDataReceived == size));

        // We're done
        RemoveMessageHandler(DieMessageType.BulkData, bulkReceived);
        onBufferReady.Invoke(buffer);
    }
Example #14
0
    IEnumerator SendMessageWithAckOrTimeout <T>(T message, DieMessageType ackType, float timeOut)
        where T : DieMessage
    {
        bool  msgReceived = false;
        float startTime   = Time.time;
        MessageReceivedDelegate callback = (ackMsg) =>
        {
            msgReceived = true;
        };

        AddMessageHandler(ackType, callback);
        byte[] msgBytes = DieMessages.ToByteArray(message);
        _sendBytes.SendBytes(this, msgBytes, msgBytes.Length, null);
        while (!msgReceived && Time.time < startTime + timeOut)
        {
            yield return(null);
        }
        RemoveMessageHandler(ackType, callback);
    }
Example #15
0
    IEnumerator WaitForMessageCr(DieMessageType msgType, System.Action <DieMessage> msgReceivedCallback)
    {
        bool       msgReceived           = false;
        DieMessage msg                   = default(DieMessage);
        MessageReceivedDelegate callback = (ackMsg) =>
        {
            msgReceived = true;
            msg         = ackMsg;
        };

        AddMessageHandler(msgType, callback);
        yield return(new WaitUntil(() => msgReceived));

        RemoveMessageHandler(msgType, callback);
        if (msgReceivedCallback != null)
        {
            msgReceivedCallback.Invoke(msg);
        }
    }
Example #16
0
        public MessageReceiveLoop(IMessageSerialization messageSerialization, ISocket socket,
                                  MessageReceivedDelegate messageReceivedDelegate, SocketExceptionDelegate onExceptionDelegate)
        {
            if (messageSerialization == null)
            {
                throw new ArgumentNullException("messageSerialization");
            }
            if (socket == null)
            {
                throw new ArgumentNullException("socket");
            }
            if (messageReceivedDelegate == null)
            {
                throw new ArgumentNullException("messageReceivedDelegate");
            }

            _socket = socket;
            _messageFrameReceiver    = new MessageFrameReceiver(socket);
            _messageSerialization    = messageSerialization;
            _messageReceivedDelegate = messageReceivedDelegate;
            _socketExceptionDelegate = onExceptionDelegate;
        }
Example #17
0
        public void Open(int listeningPort, string remoteHostname, int remotePort, MessageReceivedDelegate callback, ErrorHandlerDelegate errorhandler, int minWaitMsBetweenSend = 20)
        {
            if (_plugin != null)
                throw new Exception("UdpServer was already started.");

            MinWaitMsBetweenSend = minWaitMsBetweenSend;
            MessageReceived = callback;
            ErrorHandler = errorhandler;

            _plugin = new UdpClient(listeningPort);
            _plugin.Connect(remoteHostname, remotePort);
            RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, remotePort);
            Opened = true;

            _processMessagesThread = new Thread(ProcessMessages) { Name = "ProcessMessages" };
            _processMessagesThread.Start();

            _receiveMessagesThread = new Thread(ReceiveMessages) { Name = "ReceiveMessages" };
            _receiveMessagesThread.Start();

            _sendMessagesThread = new Thread(SendMessages) { Name = "SendMessages" };
            _sendMessagesThread.Start();
        }
Example #18
0
    IEnumerator GetDefaultAnimSetColorCr(System.Action <Color> retColor)
    {
        // Setup message handler
        MessageReceivedDelegate defaultAnimSetColorHandler = (msg) =>
        {
            var     bulkMsg  = (DieMessageDefaultAnimSetColor)msg;
            Color32 msgColor = new Color32(
                (byte)((bulkMsg.color >> 16) & 0xFF),
                (byte)((bulkMsg.color >> 8) & 0xFF),
                (byte)((bulkMsg.color >> 0) & 0xFF),
                0xFF);
            float h, s, v;
            Color.RGBToHSV(msgColor, out h, out s, out v);
            retColor(Color.HSVToRGB(h, 1, 1));
        };

        AddMessageHandler(DieMessageType.DefaultAnimSetColor, defaultAnimSetColorHandler);

        yield return(StartCoroutine(SendMessage(new DieMessageRequestDefaultAnimSetColor())));

        // We're done
        RemoveMessageHandler(DieMessageType.DefaultAnimSetColor, defaultAnimSetColorHandler);
    }
 public MessageHandler(ApolloPlugin plugin, string messageLabel, MessageReceivedDelegate onMessageReceived, MessageReceivedErrorDelegate onError = null)
 {
     OnMessageReceived = onMessageReceived ?? throw new ArgumentNullException(nameof(onMessageReceived));
     MessageFilter     = m => m.LabelMatches(messageLabel);
     FilterName        = $"Label == {messageLabel}";
 }
 public MessageHandler(ApolloPlugin plugin, MessageReceivedDelegate onMessageReceived, MessageReceivedErrorDelegate onError = null)
 {
     Plugin            = plugin;
     OnMessageReceived = onMessageReceived ?? throw new ArgumentNullException(nameof(onMessageReceived));
 }
 public CrossAppDomainCommunicator()
 {
     AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolve;
     _messageReceived = DefaultMessageReceived;
 }
Example #22
0
 public Server(int port, MessageReceivedDelegate messageRecievedEvent)
 {
     _port          = port;
     _receivedEvent = messageRecievedEvent;
 }
 public CrossAppDomainCommunicator()
 {
     AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolve;
       _messageReceived = DefaultMessageReceived;
 }
 public MessageQueueListener(MessageReceivedDelegate callback, Type type)
 {
     _callback = callback;
     _type     = type;
 }
        public override void Init()
        {          
            // Ensure that the base init method is called. It establishes a connection with the broker.
            base.Init();   

            connectionInfo = QpidConnectionInfo.FromUrl(connectionUri);         
            _connection = new AMQConnection(connectionInfo);
            _channel = _connection.CreateChannel(false, AcknowledgeMode.AutoAcknowledge, 500, 300);

            _logger.Info("Starting...");
            _logger.Info("Exchange name is '" + _exchangeName + "'...");

            // Register this to listen for exceptions on the test connection.
            _exceptionDelegate = new ExceptionListenerDelegate(OnException);
            _connection.ExceptionListener += _exceptionDelegate;

            // Declare a new headers exchange with the name of the test service.
            _channel.DeclareExchange(_exchangeName, ExchangeClassConstants.HEADERS);

            // Create a non-durable, temporary (aka auto-delete), exclusive queue.
            string queueName = _channel.GenerateUniqueName();
            _channel.DeclareQueue(queueName, false, true, true);

            // Bind the queue to the new headers exchange, setting up some header patterns for the exchange to match.
            _channel.Bind(queueName, _exchangeName, null, CreatePatternAsFieldTable());

            // Create a test consumer to consume messages from the test exchange.
            _consumer = _channel.CreateConsumerBuilder(queueName)
                .WithPrefetchLow(100)
                .WithPrefetchHigh(500)
                .WithNoLocal(false) // make sure we get our own messages
                .Create();

            // Register this to listen for messages on the consumer.
            _msgRecDelegate = new MessageReceivedDelegate(OnMessage);
            _consumer.OnMessage += _msgRecDelegate;
            
            // Clear the most recent message and exception.
            _lastException = null;
            _lastMessage = null;

            _publisher = _channel.CreatePublisherBuilder()
                    .WithExchangeName(_exchangeName)
                    .WithMandatory(true)
                    .Create();

            _publisher.DeliveryMode = DeliveryMode.NonPersistent;

            // Start all channel
            _connection.Start();
        }
 public void SetMessageReceivedDelegate(MessageReceivedDelegate messageReceived)
 {
     _messageReceived = messageReceived;
 }
 public MessageQueueListener(MessageReceivedDelegate callback, Type type)
 {
     _callback = callback;
     _type = type;
 }
 /// <summary>
 /// Set up a queue to listen for reports on.
 /// </summary>
 public IMessageConsumer CreateListener(string queueName, string routingKey, string exchangeName,
                                        string exchangeClass,
                                        bool isDurable, bool isExclusive, bool autoDelete,
                                        MessageReceivedDelegate handler)
 {
     exchangeClass = exchangeClass ?? ToExchangeClass(exchangeName);
     EnsureExchange(exchangeName, exchangeClass);
     if (queueName == null)
     {
         queueName = GenerateUniqueQueue();
     }
     else
     {
         EnsureQueue(queueName, isDurable, isExclusive, autoDelete);
     }
     // Set this listener up to listen for reports on the response queue.
     try
     {
         channel.Bind(queueName, exchangeName, routingKey);
         //channel.Bind(responseQueueName, "<<default>>", RESPONSE_ROUTING_KEY);
         IMessageConsumer consumer = channel.CreateConsumerBuilder(queueName).WithExclusive(isExclusive).Create();
         consumer.OnMessage += new MessageReceivedDelegate(handler);
         return consumer;
     }
     catch (Exception)
     {
         return null;
     }
 }
Example #29
0
        IEnumerator PlayTestAnimationCr(DataSet testAnimSet, System.Action <bool> callBack)
        {
            bool result = false;

            try
            {
                PixelsApp.Instance.ShowProgrammingBox("Uploading animation to " + name);

                // Prepare the die
                var prepareDie = new DieMessageTransferTestAnimSet();
                prepareDie.paletteSize      = testAnimSet.animationBits.getPaletteSize();;
                prepareDie.rgbKeyFrameCount = testAnimSet.animationBits.getRGBKeyframeCount();
                prepareDie.rgbTrackCount    = testAnimSet.animationBits.getRGBTrackCount();
                prepareDie.keyFrameCount    = testAnimSet.animationBits.getKeyframeCount();
                prepareDie.trackCount       = testAnimSet.animationBits.getTrackCount();
                prepareDie.animationSize    = (ushort)Marshal.SizeOf(testAnimSet.animations[0].GetType());

                var setData = testAnimSet.ToTestAnimationByteArray();
                var hash    = Utils.computeHash(setData);

                prepareDie.hash = hash;
                // Debug.Log("Animation Data to be sent:");
                // Debug.Log("palette: " + prepareDie.paletteSize * Marshal.SizeOf<byte>());
                // Debug.Log("rgb keyframes: " + prepareDie.rgbKeyFrameCount + " * " + Marshal.SizeOf<Animations.RGBKeyframe>());
                // Debug.Log("rgb tracks: " + prepareDie.rgbTrackCount + " * " + Marshal.SizeOf<Animations.RGBTrack>());
                // Debug.Log("keyframes: " + prepareDie.keyFrameCount + " * " + Marshal.SizeOf<Animations.Keyframe>());
                // Debug.Log("tracks: " + prepareDie.trackCount + " * " + Marshal.SizeOf<Animations.Track>());
                TransferTestAnimSetAckType acknowledge = TransferTestAnimSetAckType.NoMemory;
                yield return(StartCoroutine(SendMessageWithAckOrTimeoutCr(
                                                prepareDie,
                                                DieMessageType.TransferTestAnimSetAck,
                                                3.0f,
                                                (ack) => acknowledge = ((DieMessageTransferTestAnimSetAck)ack).ackType,
                                                null,
                                                null)));

                switch (acknowledge)
                {
                case TransferTestAnimSetAckType.Download:
                {
                    Debug.Log("Die is ready to receive test dataset, byte array should be: " + setData.Length + " bytes and hash 0x" + hash.ToString("X8"));

                    bool programmingFinished = false;
                    MessageReceivedDelegate programmingFinishedCallback = (finishedMsg) =>
                    {
                        programmingFinished = true;
                    };

                    AddMessageHandler(DieMessageType.TransferTestAnimSetFinished, programmingFinishedCallback);

                    yield return(StartCoroutine(UploadBulkDataCr(
                                                    setData,
                                                    (pct) => PixelsApp.Instance.UpdateProgrammingBox(pct),
                                                    (res) => result = res)));

                    if (result)
                    {
                        // We're done sending data, wait for the die to say its finished programming it!
                        Debug.Log("Done sending data, waiting for die to finish programming!");
                        yield return(new WaitUntil(() => programmingFinished));

                        RemoveMessageHandler(DieMessageType.TransferTestAnimSetFinished, programmingFinishedCallback);
                    }
                    else
                    {
                        RemoveMessageHandler(DieMessageType.TransferTestAnimSetFinished, programmingFinishedCallback);
                        Debug.Log("Error!");
                    }
                }
                break;

                case TransferTestAnimSetAckType.UpToDate:
                {
                    result = true;
                }
                break;

                default:
                    break;
                }
            }
            finally
            {
                PixelsApp.Instance.HideProgrammingBox();
                callBack?.Invoke(result);
            }
        }
Example #30
0
 public QueueSubscriptionService(EasyNetQLogger logger,MessageReceivedDelegate messageHandler)
 {
     _logger = logger;
     _messageHandler = messageHandler;
 }
 public void SetMessageReceivedDelegate(MessageReceivedDelegate messageReceived)
 {
     _messageReceived = messageReceived;
 }
Example #32
0
        /// <summary>
        /// Register and Start TopicSubscriber
        /// </summary>
        /// <param name="brokerURL">ActiveMQ URL</param>
        /// <param name="destination">ActiveMQ Column Name</param>
        /// <param name="dele">delegate object</param>
        /// <returns>TopicSubscriber(Registered and Started )</returns>
        private TopicSubscriber RegisterTopicSubscriber(string brokerURL, string destination, MessageReceivedDelegate <string> dele)
        {
            TopicSubscriber subscriber = new TopicSubscriber(brokerURL, destination);

            subscriber.Start();
            subscriber.OnMessageReceived += dele;
            return(subscriber);
        }
Example #33
0
        IEnumerator UploadDataSetCr(DataSet set, System.Action <float> uploadPctCallback, System.Action <bool, string> callBack)
        {
            bool   result   = false;
            string errorMsg = null;

            try
            {
                // Prepare the die
                var prepareDie = new DieMessageTransferAnimSet();
                prepareDie.paletteSize      = set.animationBits.getPaletteSize();;
                prepareDie.rgbKeyFrameCount = set.animationBits.getRGBKeyframeCount();
                prepareDie.rgbTrackCount    = set.animationBits.getRGBTrackCount();
                prepareDie.keyFrameCount    = set.animationBits.getKeyframeCount();
                prepareDie.trackCount       = set.animationBits.getTrackCount();
                prepareDie.animationCount   = set.getAnimationCount();
                prepareDie.animationSize    = (ushort)set.animations.Sum((anim) => Marshal.SizeOf(anim.GetType()));
                prepareDie.conditionCount   = set.getConditionCount();
                prepareDie.conditionSize    = (ushort)set.conditions.Sum((cond) => Marshal.SizeOf(cond.GetType()));
                prepareDie.actionCount      = set.getActionCount();
                prepareDie.actionSize       = (ushort)set.actions.Sum((action) => Marshal.SizeOf(action.GetType()));
                prepareDie.ruleCount        = set.getRuleCount();
                //StringBuilder builder = new StringBuilder();
                //builder.AppendLine("Animation Data to be sent:");
                //builder.AppendLine("palette: " + prepareDie.paletteSize * Marshal.SizeOf<byte>());
                //builder.AppendLine("rgb keyframes: " + prepareDie.rgbKeyFrameCount + " * " + Marshal.SizeOf<Animations.RGBKeyframe>());
                //builder.AppendLine("rgb tracks: " + prepareDie.rgbTrackCount + " * " + Marshal.SizeOf<Animations.RGBTrack>());
                //builder.AppendLine("keyframes: " + prepareDie.keyFrameCount + " * " + Marshal.SizeOf<Animations.Keyframe>());
                //builder.AppendLine("tracks: " + prepareDie.trackCount + " * " + Marshal.SizeOf<Animations.Track>());
                //builder.AppendLine("animations: " + prepareDie.animationCount + ", " + prepareDie.animationSize);
                //builder.AppendLine("conditions: " + prepareDie.conditionCount + ", " + prepareDie.conditionSize);
                //builder.AppendLine("actions: " + prepareDie.actionCount + ", " + prepareDie.actionSize);
                //builder.AppendLine("rules: " + prepareDie.ruleCount + " * " + Marshal.SizeOf<Behaviors.Rule>());
                //builder.AppendLine("behavior: " + Marshal.SizeOf<Behaviors.Behavior>());
                //Debug.Log(builder.ToString());
                //Debug.Log("Animation Data size: " + set.ComputeDataSetDataSize());

                bool?acceptTransfer = null;
                yield return(StartCoroutine(SendMessageWithAckOrTimeoutCr(
                                                prepareDie,
                                                DieMessageType.TransferAnimSetAck,
                                                3.0f,
                                                (msg) => acceptTransfer = (msg as DieMessageTransferAnimSetAck).result == 0 ? false : true,
                                                null,
                                                null)));

                if (acceptTransfer.HasValue)
                {
                    if (acceptTransfer.Value)
                    {
                        var setData = set.ToByteArray();
                        //StringBuilder hexdumpBuilder = new StringBuilder();
                        //for (int i = 0; i < setData.Length; ++i)
                        //{
                        //    if (i % 8 == 0)
                        //    {
                        //        hexdumpBuilder.AppendLine();
                        //    }
                        //    hexdumpBuilder.Append(setData[i].ToString("X02") + " ");
                        //}
                        //Debug.Log(hexdumpBuilder.ToString());

                        var hash = Utils.computeHash(setData);
                        Debug.Log("Die is ready to receive dataset, byte array should be: " + set.ComputeDataSetDataSize() + " bytes and hash 0x" + hash.ToString("X8"));

                        bool programmingFinished = false;
                        MessageReceivedDelegate programmingFinishedCallback = (finishedMsg) =>
                        {
                            programmingFinished = true;
                        };

                        AddMessageHandler(DieMessageType.TransferAnimSetFinished, programmingFinishedCallback);

                        yield return(StartCoroutine(UploadBulkDataCr(
                                                        setData,
                                                        uploadPctCallback,
                                                        (res) => result = res)));

                        if (result)
                        {
                            // We're done sending data, wait for the die to say its finished programming it!
                            Debug.Log("Done sending data, waiting for die to finish programming!");
                            yield return(new WaitUntil(() => programmingFinished));

                            RemoveMessageHandler(DieMessageType.TransferAnimSetFinished, programmingFinishedCallback);
                        }
                        else
                        {
                            RemoveMessageHandler(DieMessageType.TransferAnimSetFinished, programmingFinishedCallback);
                            errorMsg = "Error during animation data upload";
                            Debug.Log(errorMsg);
                        }
                    }
                    else
                    {
                        errorMsg = "Transfer refused, not enough memory";
                        Debug.Log(errorMsg);
                    }
                }
                else
                {
                    errorMsg = "Time out while trying to upload animation data";
                    Debug.Log(errorMsg);
                }
            }
            finally
            {
                callBack?.Invoke(result, errorMsg);
            }
        }