@@ -60,8 +60,8 @@ FirmataParser::FirmataParser(uint8_t * const dataBuffer, size_t dataBufferSize)
6060 currentDataBufferOverflowCallback((dataBufferOverflowCallbackFunction)NULL),
6161 currentStringCallback((stringCallbackFunction)NULL),
6262 currentSysexCallback((sysexCallbackFunction)NULL),
63- currentReportFirmwareCallback((systemCallbackFunction )NULL),
64- currentReportVersionCallback((systemCallbackFunction )NULL),
63+ currentReportFirmwareCallback((versionCallbackFunction )NULL),
64+ currentReportVersionCallback((versionCallbackFunction )NULL),
6565 currentSystemResetCallback((systemCallbackFunction)NULL)
6666{
6767 allowBufferUpdate = ((uint8_t *)NULL == dataBuffer);
@@ -130,6 +130,9 @@ void FirmataParser::parse(uint8_t inputData)
130130 if (currentReportDigitalCallback)
131131 (*currentReportDigitalCallback)(currentReportDigitalCallbackContext, multiByteChannel, dataBuffer[0 ]);
132132 break ;
133+ case REPORT_VERSION:
134+ if (currentReportVersionCallback)
135+ (*currentReportVersionCallback)(currentReportVersionCallbackContext, dataBuffer[0 ], dataBuffer[1 ], (const char *)NULL );
133136 }
134137 executeMultiByteCommand = 0 ;
135138 }
@@ -163,8 +166,8 @@ void FirmataParser::parse(uint8_t inputData)
163166 systemReset ();
164167 break ;
165168 case REPORT_VERSION:
166- if (currentReportVersionCallback)
167- (*currentReportVersionCallback)(currentReportVersionCallbackContext) ;
169+ waitForData = 2 ; // two data bytes needed
170+ executeMultiByteCommand = command ;
168171 break ;
169172 }
170173 }
@@ -244,15 +247,15 @@ void FirmataParser::attach(uint8_t command, callbackFunction newFunction, void *
244247}
245248
246249/* *
247- * Attach a system callback function (options are: REPORT_FIRMWARE, REPORT_VERSION
248- * and SYSTEM_RESET).
250+ * Attach a version callback function (options are: REPORT_FIRMWARE, REPORT_VERSION).
249251 * @param command The ID of the command to attach a callback function to.
250252 * @param newFunction A reference to the callback function to attach.
251253 * @param context An optional context to be provided to the callback function (NULL by default).
252254 * @note The context parameter is provided so you can pass a parameter, by reference, to
253255 * your callback function.
256+ * @note The description value in the REPORT_VERSION callback will always be NULL
254257 */
255- void FirmataParser::attach (uint8_t command, systemCallbackFunction newFunction, void * context)
258+ void FirmataParser::attach (uint8_t command, versionCallbackFunction newFunction, void * context)
256259{
257260 switch (command) {
258261 case REPORT_FIRMWARE:
@@ -263,6 +266,20 @@ void FirmataParser::attach(uint8_t command, systemCallbackFunction newFunction,
263266 currentReportVersionCallback = newFunction;
264267 currentReportVersionCallbackContext = context;
265268 break ;
269+ }
270+ }
271+
272+ /* *
273+ * Attach a system callback function (currently supports SYSTEM_RESET).
274+ * @param command The ID of the command to attach a callback function to.
275+ * @param newFunction A reference to the callback function to attach.
276+ * @param context An optional context to be provided to the callback function (NULL by default).
277+ * @note The context parameter is provided so you can pass a parameter, by reference, to
278+ * your callback function.
279+ */
280+ void FirmataParser::attach (uint8_t command, systemCallbackFunction newFunction, void * context)
281+ {
282+ switch (command) {
266283 case SYSTEM_RESET:
267284 currentSystemResetCallback = newFunction;
268285 currentSystemResetCallbackContext = context;
@@ -326,6 +343,8 @@ void FirmataParser::detach(uint8_t command)
326343 switch (command) {
327344 case REPORT_FIRMWARE:
328345 case REPORT_VERSION:
346+ attach (command, (versionCallbackFunction)NULL , NULL );
347+ break ;
329348 case SYSTEM_RESET:
330349 attach (command, (systemCallbackFunction)NULL , NULL );
331350 break ;
@@ -394,14 +413,24 @@ void FirmataParser::processSysexMessage(void)
394413{
395414 switch (dataBuffer[0 ]) { // first byte in buffer is command
396415 case REPORT_FIRMWARE:
397- if (currentReportFirmwareCallback)
398- (*currentReportFirmwareCallback)(currentReportFirmwareCallbackContext);
416+ if (currentReportFirmwareCallback) {
417+ size_t sv_major = dataBuffer[1 ], sv_minor = dataBuffer[2 ];
418+ size_t i = 0 , j = 3 ;
419+ while (j < sysexBytesRead) {
420+ // The string length will only be at most half the size of the
421+ // stored input buffer so we can decode the string within the buffer.
422+ bufferDataAtPosition (dataBuffer[j], i);
423+ ++i;
424+ ++j;
425+ }
426+ bufferDataAtPosition (' \0 ' , i); // Terminate the string
427+ (*currentReportFirmwareCallback)(currentReportFirmwareCallbackContext, sv_major, sv_minor, (const char *)&dataBuffer[0 ]);
428+ }
399429 break ;
400430 case STRING_DATA:
401431 if (currentStringCallback) {
402432 size_t bufferLength = (sysexBytesRead - 1 ) / 2 ;
403- size_t i = 1 ;
404- size_t j = 0 ;
433+ size_t i = 1 , j = 0 ;
405434 while (j < bufferLength) {
406435 // The string length will only be at most half the size of the
407436 // stored input buffer so we can decode the string within the buffer.
@@ -417,7 +446,7 @@ void FirmataParser::processSysexMessage(void)
417446 if (dataBuffer[j - 1 ] != ' \0 ' ) {
418447 bufferDataAtPosition (' \0 ' , j);
419448 }
420- (*currentStringCallback)(currentStringCallbackContext, (char *)&dataBuffer[0 ]);
449+ (*currentStringCallback)(currentStringCallbackContext, (const char *)&dataBuffer[0 ]);
421450 }
422451 break ;
423452 default :
0 commit comments