BrianPeek / legoev3

LEGO MINDSTORMS EV3 API for .NET
Apache License 2.0
137 stars 72 forks source link

Fix for issues with newer firmware #30

Open RavenLiquid opened 6 years ago

RavenLiquid commented 6 years ago

While trying to get this project to work, I came across the issue where the ResponseManager.HandleResponse is throwing some Key out of range errors.

The issue seems to be that the expected input is not compatible with this code. My device came with FW 1.07 and I upgraded to 1.09 so I have no idea if something has changed with older FWs but the problem is that the HandleResponse expects the first two bytes to be the sequence number. The Lego Communications documentation says the first two bytes are the size, so what happens is that the code tries to access a Response at the index that is the size of the message. Does not work that well.

The fix is actually quite simple. Up all the indexes with 2 so it skips the size.

internal static void HandleResponse(byte[] report)
        {
            if (report == null || report.Length < 3)
                return;

            ushort sequence = (ushort) (report[2] | (report[3] << 8));
            int replyType = report[4];

            if (sequence > 0)
            {
                try
                {
                    Response r = Responses[sequence];

                    if (Enum.IsDefined(typeof(ReplyType), replyType))
                        r.ReplyType = (ReplyType) replyType;

                    if (r.ReplyType == ReplyType.DirectReply || r.ReplyType == ReplyType.DirectReplyError)
                    {
                        r.Data = new byte[report.Length - 5];
                        Array.Copy(report, 5, r.Data, 0, report.Length - 5);
                    }
                    else if (r.ReplyType == ReplyType.SystemReply || r.ReplyType == ReplyType.SystemReplyError)
                    {
                        if (Enum.IsDefined(typeof(SystemOpcode), (int) report[4]))
                            r.SystemCommand = (SystemOpcode) report[4];

                        if (Enum.IsDefined(typeof(SystemReplyStatus), (int) report[6]))
                            r.SystemReplyStatus = (SystemReplyStatus) report[6];

                        r.Data = new byte[report.Length - 7];
                        Array.Copy(report, 7, r.Data, 0, report.Length - 7);
                    }

                    r.Event.Set();
                }
                catch (Exception e)
                {
                    Debug.WriteLine(e);
                    throw;
                }
            }
        }