Here's my take on this code, let me know if you want me clarify anything...
***** The Command class
The Command constructor allocates and initializes a byte buffer that holds the command and provides methods for filling in the command data. Subclasses of this class provide additional methods for filling in the command data that is specific to the action that that command represents.
The format of the command buffer is:
(n=commandLength)
Code:
byte pos byte len value description
-------- -------- ------ -----------
0 2 0x5aa5 xm cmd magic
2 2 n+1 command length+1 (most significant byte first)
4 1 type command type (passed into the constructor)
5 n+1 ... command data
n+5 2 0xeded command footer (at end of every command)
setByte() is used set the actual data in the command (starting from byte position 5 above)
All the classes called cmdXXXXX that extend Command just define a method that fills in the command data in the buffer above.
Specifically, cmdMonitorLabelChange creates a command buffer with 0x50 as the command type, and has 5 bytes that define the command. So the byte buffer for the MonitorLabelChange command looks like this:
Code:
byte pos byte len value description
-------- -------- ------ -----------
0 2 0x5aa5 xm cmd magic
2 2 0x0006 command length (passed into constructor+1)
4 1 0x50 command type (passed into the constructor)
5 1 0x01 XM channel 1
6 1 0x00 service=false
7 1 0x01 program=true
8 1 0x01 info=true
9 1 0x00 extended_info=false
10 2 0xeded command footer (at end of every command)
total length of buffer: 12 bytes
***** The Response class
The Response class holds the bytes that come in as a response to a command. A response is of the same format as a command (see above for a description of the bytes). It is constructed with the buffer holding the response bytes. It has a method for getting a specific byte (getByte()) in the response buffer and also a method (extractString()) for getting a String located at a specific position in the response buffer. Subclasses of the Response class provide methods that parse out data from the response buffer that is specific to that command.
I think this is what they mean by some command being asynchronous: normally a response comes back in response to a command that is sent. So, I would send a command, wait for a response, then load the response into a buffer and then pull out data form that buffer. However, sometimes responses don't come back right away. In this case, I would send a command and then just not wait for the response since I don't know when it will come back. So, instead of explicitly waiting for this response to come back, what some of the Response subclasses do is define methods for handling themselves when the response comes in. That's what the handle() and isInternal() methods are for.
respLabelChangeMonitored (SYNCHRONOUS) provides a getChannel() method that pulls out the channel from the response buffer (the channel is a byte long value located at byte 2).
respMonitorChannelName (ASYNCHRONOUS) gets the channel name via the getChannelName() [string at byte 1] method. The channel number is determined via getChannel() @ byte 0.
I think you can figure out what the rest of respXXXX Response classes do by looking at their getXXXXX() methods and handle() methods.
Bookmarks