-
Notifications
You must be signed in to change notification settings - Fork 515
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[v3.0.0] version callbacks #358
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -61,7 +61,7 @@ FirmataParser::FirmataParser(uint8_t * const dataBuffer, size_t dataBufferSize) | |
currentStringCallback((stringCallbackFunction)NULL), | ||
currentSysexCallback((sysexCallbackFunction)NULL), | ||
currentReportFirmwareCallback((versionCallbackFunction)NULL), | ||
currentReportVersionCallback((systemCallbackFunction)NULL), | ||
currentReportVersionCallback((versionCallbackFunction)NULL), | ||
currentSystemResetCallback((systemCallbackFunction)NULL) | ||
{ | ||
allowBufferUpdate = ((uint8_t *)NULL == dataBuffer); | ||
|
@@ -130,6 +130,9 @@ void FirmataParser::parse(uint8_t inputData) | |
if (currentReportDigitalCallback) | ||
(*currentReportDigitalCallback)(currentReportDigitalCallbackContext, multiByteChannel, dataBuffer[0]); | ||
break; | ||
case REPORT_VERSION: | ||
if (currentReportVersionCallback) | ||
(*currentReportVersionCallback)(currentReportVersionCallbackContext, dataBuffer[0], dataBuffer[1], (const char *)NULL); | ||
} | ||
executeMultiByteCommand = 0; | ||
} | ||
|
@@ -163,8 +166,8 @@ void FirmataParser::parse(uint8_t inputData) | |
systemReset(); | ||
break; | ||
case REPORT_VERSION: | ||
if (currentReportVersionCallback) | ||
(*currentReportVersionCallback)(currentReportVersionCallbackContext); | ||
waitForData = 2; // two data bytes needed | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is where I wish we had unit test coverage for the parser. I'm still not 100% sure this will not break with most existing Firmata client libraries. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd want to know that if waitForData is 2 or 0 this will still work as expected. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah tracing through the code, this will cause the next two bytes after a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It does change the behavior... With this change, you will need to send all three bytes for the version in order to get the callback from Conceivably Perhaps it would be good to split these up. It would allow us to pull in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's going to break a lot of client libraries. We'll have to wait for Firmata v3.0 then. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is because many Firmata client libraries initiate communication with the board by querying the protocol version. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think there is some general confusion here because There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But you're trying to use the same parser both on the host and client side so now I understand the larger issue here. |
||
executeMultiByteCommand = command; | ||
break; | ||
} | ||
} | ||
|
@@ -244,12 +247,13 @@ void FirmataParser::attach(uint8_t command, callbackFunction newFunction, void * | |
} | ||
|
||
/** | ||
* Attach a version callback function (supported option: REPORT_FIRMWARE). | ||
* Attach a version callback function (supported options are: REPORT_FIRMWARE, REPORT_VERSION). | ||
* @param command The ID of the command to attach a callback function to. | ||
* @param newFunction A reference to the callback function to attach. | ||
* @param context An optional context to be provided to the callback function (NULL by default). | ||
* @note The context parameter is provided so you can pass a parameter, by reference, to | ||
* your callback function. | ||
* @note The description value in the REPORT_VERSION callback will always be NULL | ||
*/ | ||
void FirmataParser::attach(uint8_t command, versionCallbackFunction newFunction, void * context) | ||
{ | ||
|
@@ -258,11 +262,15 @@ void FirmataParser::attach(uint8_t command, versionCallbackFunction newFunction, | |
currentReportFirmwareCallback = newFunction; | ||
currentReportFirmwareCallbackContext = context; | ||
break; | ||
case REPORT_VERSION: | ||
currentReportVersionCallback = newFunction; | ||
currentReportVersionCallbackContext = context; | ||
break; | ||
} | ||
} | ||
|
||
/** | ||
* Attach a system callback function (supported options are: SYSTEM_RESET, REPORT_VERSION). | ||
* Attach a system callback function (supported option: SYSTEM_RESET). | ||
* @param command The ID of the command to attach a callback function to. | ||
* @param newFunction A reference to the callback function to attach. | ||
* @param context An optional context to be provided to the callback function (NULL by default). | ||
|
@@ -272,10 +280,6 @@ void FirmataParser::attach(uint8_t command, versionCallbackFunction newFunction, | |
void FirmataParser::attach(uint8_t command, systemCallbackFunction newFunction, void * context) | ||
{ | ||
switch (command) { | ||
case REPORT_VERSION: | ||
currentReportVersionCallback = newFunction; | ||
currentReportVersionCallbackContext = context; | ||
break; | ||
case SYSTEM_RESET: | ||
currentSystemResetCallback = newFunction; | ||
currentSystemResetCallbackContext = context; | ||
|
@@ -341,6 +345,8 @@ void FirmataParser::detach(uint8_t command) | |
attach(command, (versionCallbackFunction)NULL, NULL); | ||
break; | ||
case REPORT_VERSION: | ||
attach(command, (versionCallbackFunction)NULL, NULL); | ||
break; | ||
case SYSTEM_RESET: | ||
attach(command, (systemCallbackFunction)NULL, NULL); | ||
break; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Firmata client libraries do not provide data parameters for REPORT_VERSION so I'm not sure where the version data would come from. You could pass it in statically though. This is probably why the ESP8266 isn't working.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am aware, but I need to standardize the message so the parser can parse it - even if portions are disregarded. The name of the byte is REPORT version, not QUERY. You happen to be using it for both.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I'm starting to understand. Let me know if this is correct.
The version parameters are needed in the callback since the callback is actually for the reply rather than the query. When the callback is called, those parameters are available.
The confusion on the protocol side is that
REPORT_VERSION
andREPORT_FIRMWARE
were shared for both query and reply (which was common in the early days of Firmata).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see since we can anticipate that dataBuffer[0] and dataBuffer[1] will contain the appropriate data when the callback is called. I was overlooking the fact that dataBuffer was a member variable, that's what was largely throwing me off. Maybe we should have a convention member variables. I've been prefixing with
m
for the SPI feature I've been working on: https://github.com/firmata/arduino/blob/spi-alpha/utility/SPIFirmata.h#L94-L96.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
REPORT_VERSION
was used to query the version from the host/server, and it would subsequently report the version usingREPORT_VERSION
.REPORT_VERSION
is a single byte operation in the protocol documentation is wrong, because the version is actually reported using three bytes.REPORT_VERSION
should always send three bytes and the server/host should be smart enough realize it is being queried and discard them.QUERY_VERSION
used to explicitly query the version from the server/hostREPORT_FIRMWARE
should follow a similar approachThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll add
QUERY_FIRMWARE_VERSION
andQUERY_PROTOCOL_VERSION
for v3.0 since I can't really think of a good reason for a client library to send it's version to the board.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefix all my _member variables on my projects, so I'm down. I was just following style.