diff --git a/source/Command.m b/source/Command.m index cc2f4723f7dc77faacdf5f3ed87d3bdda70f20ec..94d1fb069b66cdd97ff1192fb619017e3f959890 100644 --- a/source/Command.m +++ b/source/Command.m @@ -12,7 +12,8 @@ % addSystemCommand Adds a system command to the command object % addDirectCommand Adds a direct command to the command object % -% checkForError @MMI Checks error byte in received package. +% checkForError @MMI Checks error byte in received package +% isCorrupt @MMI Checks whether reply packet is corrupt % % clear Clears the command msg % display Displays the command msg (decimal) @@ -286,12 +287,45 @@ classdef Command < handle function cmd = Command(varargin) % Command.cmd Create an empty command % - % c = Command(OPTIONS) is an object that represents an EV3 command + % c = Command() is an object that represents an EV3 command + % c = Command([...]) is an object that represents an EV3 reply % % Example:: % c = Command(); - cmd.msg = uint8([]); + if nargin > 0 % Packet is a reply + try + cmd.msg = uint8(varargin{1}); + catch ME + id = [ID(), ':', 'InvalidParameter']; + msg = 'Failed to create reply-packet with Command-class.'; + baseException = MException(id, msg); + baseException = addCause(baseException, ME); + throw(baseException); + end + + % If corrupt, throw error + corrupt = cmd.isValidReply(); + if corrupt < 1 + msg = 'Invalid reply packet'; + id = [ID(), ':', 'CorruptPacket']; + ME = MException(id, msg); + switch corrupt + case 0 + causeMsg = 'Reply packet too short'; + case -1 + causeMsg = ['Specified packet length (bytes 1&2) does not equal ',... + 'actual packet length']; + case -2 + causeMsg = 'Error type (byte 5) is not valid'; + end + cause = MException(id, causeMsg); + ME = addCause(ME, cause); + throw(ME); + end + else % Packet is a command + cmd.msg = uint8([]); + end end function delete(cmd) @@ -322,6 +356,43 @@ classdef Command < handle end end + function state = isValidReply(cmd) + % Command.isValidReply Check if reply-packet is valid + % + % state = cmd.isValidReply checks cmd against reply-packet-format and returns + % whether if cmd is valid (that is, does not fit the + % format). + % Notes: + % - state = 1, if reply is not corrupted (at least not in a way that can be + % tested) + % - state = 0, if reply is too short (minimum length = 5 bytes) + % - state = -1, if reply is corrupted due to invalid length/length indicator + % - state = -2, if reply is corrupted due to invalid error type byte + % - IMPORTANT: Of course, the packet can still contain invalid information which + % cannot be tested properly without context. This corruption-test + % only checks the contextless information. + % + state = 1; + + % Minimum length of a reply packet is 5, for a packet without response buffer + minLength = 5; + if length(cmd.msg) < minLength + state = 0; + return + end + + % Note: The two things that can be checked without context are the length and the + % command type, the remainder varies from packet to packet. + pLength = double(typecast(cmd.msg(1:2),'uint16')) + 2; + pCmdType = cmd.msg(5); + + if pLength ~= length(cmd.msg) + state = -1; + elseif pCmdType ~= 2 && pCmdType ~=4 + state = -2; + end + end + function addHeaderSystem(cmd,counter) % Command.addHeaderSystem Add a system header with no reply %