ThinkGearStreamParser.cpp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. /*
  2. * @(#)ThinkGearStreamParser.c 2.0 Mar 04, 2008
  3. *
  4. * Copyright (c) 2008 NeuroSky, Inc. All Rights Reserved
  5. * NEUROSKY PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. /*
  8. Copyright (c) 2010 Embedded Systems and Pervasive Laboratory, Federal
  9. University of Campina Grande, Brazil, Angelo Perkusich, Mirko Perkusich,
  10. Taciana Rached
  11. Permission is hereby granted, free of charge, to any person obtaining a
  12. copy of this software and associated documentation files (the
  13. "Software"), to deal in the Software without restriction, including
  14. without limitation the rights to use, copy, modify, merge, publish,
  15. distribute, sublicense, and/or sell copies of the Software, and to
  16. permit persons to whom the Software is furnished to do so, subject to
  17. the following conditions:
  18. The above copyright notice and this permission notice shall be included
  19. in all copies or substantial portions of the Software.
  20. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  21. OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  22. MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  23. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  24. CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  25. TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  26. SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  27. */
  28. /**
  29. * @file ThinkGearStreamParser.c
  30. *
  31. * @author Kelvin Soo
  32. * @version 2.0 Mar 04, 2008 Kelvin Soo
  33. * - Renamed to ThinkGearStreamParser from ThinkGearStreamDecoder.
  34. * - Revised to call a callback function instead of stuffing arriving
  35. * data values into a ThinkGearData object.
  36. * - Renamed symbols according to updated Packet vocabulary.
  37. * @version 1.0 Nov 27, 2007 Kelvin Soo
  38. * - Initial version (ThinkGearStreamDecoder).
  39. */
  40. #include "ThinkGearStreamParser.h"
  41. /* Include libraries required specifically by this implementation of this
  42. * library and not already included by this library's header
  43. */
  44. #include <stdio.h>
  45. /* Decoder states (Packet decoding) */
  46. #define PARSER_STATE_NULL 0x00 /* NULL state */
  47. #define PARSER_STATE_SYNC 0x01 /* Waiting for SYNC byte */
  48. #define PARSER_STATE_SYNC_CHECK 0x02 /* Waiting for second SYNC byte */
  49. #define PARSER_STATE_PAYLOAD_LENGTH 0x03 /* Waiting for payload[] length */
  50. #define PARSER_STATE_PAYLOAD 0x04 /* Waiting for next payload[] byte */
  51. #define PARSER_STATE_CHKSUM 0x05 /* Waiting for chksum byte */
  52. /* Decoder states (2-byte raw decoding) */
  53. #define PARSER_STATE_WAIT_HIGH 0x06 /* Waiting for high byte */
  54. #define PARSER_STATE_WAIT_LOW 0x07 /* High r'cvd. Expecting low part */
  55. /* Other constants */
  56. #define PARSER_SYNC_BYTE 0xAA /* Syncronization byte */
  57. #define PARSER_EXCODE_BYTE 0x55 /* EXtended CODE level byte */
  58. /*
  59. * See header file for interface documentation.
  60. */
  61. ThinkGearStreamParser::ThinkGearStreamParser()
  62. {
  63. int parserType = PARSER_TYPE_PACKETS;
  64. /* Initialize the parser's state based on the parser type */
  65. switch( parserType ) {
  66. case( PARSER_TYPE_PACKETS ):
  67. state = PARSER_STATE_SYNC;
  68. break;
  69. case( PARSER_TYPE_2BYTERAW ):
  70. state = PARSER_STATE_WAIT_HIGH;
  71. break;
  72. }
  73. /* Save parser type */
  74. type = parserType;
  75. }
  76. /*
  77. * See header file for interface documentation.
  78. */
  79. int ThinkGearStreamParser::parseByte( unsigned char byte ) {
  80. int returnValue = 0;
  81. /* Pick handling according to current state... */
  82. switch( state ) {
  83. /* Waiting for SyncByte */
  84. case( PARSER_STATE_SYNC ):
  85. if( byte == PARSER_SYNC_BYTE ) {
  86. state = PARSER_STATE_SYNC_CHECK;
  87. }
  88. break;
  89. /* Waiting for second SyncByte */
  90. case( PARSER_STATE_SYNC_CHECK ):
  91. if( byte == PARSER_SYNC_BYTE ) {
  92. state = PARSER_STATE_PAYLOAD_LENGTH;
  93. } else {
  94. state = PARSER_STATE_SYNC;
  95. }
  96. break;
  97. /* Waiting for Data[] length */
  98. case( PARSER_STATE_PAYLOAD_LENGTH ):
  99. payloadLength = byte;
  100. if( payloadLength > 170 ) {
  101. state = PARSER_STATE_SYNC;
  102. returnValue = -3;
  103. } else if( payloadLength == 170 ) {
  104. returnValue = -4;
  105. } else {
  106. payloadBytesReceived = 0;
  107. payloadSum = 0;
  108. state = PARSER_STATE_PAYLOAD;
  109. }
  110. break;
  111. /* Waiting for Payload[] bytes */
  112. case( PARSER_STATE_PAYLOAD ):
  113. payload[payloadBytesReceived++] = byte;
  114. payloadSum = (unsigned char)(payloadSum + byte);
  115. if( payloadBytesReceived >= payloadLength ) {
  116. state = PARSER_STATE_CHKSUM;
  117. }
  118. break;
  119. /* Waiting for CKSUM byte */
  120. case( PARSER_STATE_CHKSUM ):
  121. chksum = byte;
  122. state = PARSER_STATE_SYNC;
  123. if( chksum != ((~payloadSum)&0xFF) ) {
  124. returnValue = -2;
  125. } else {
  126. returnValue = 1;
  127. parsePacketPayload();
  128. }
  129. break;
  130. /* unrecognized state */
  131. default:
  132. state = PARSER_STATE_SYNC;
  133. returnValue = -5;
  134. break;
  135. }
  136. /* Save current byte */
  137. lastByte = byte;
  138. return( returnValue );
  139. }
  140. /**
  141. * Parses each row of data from the @c packet's Data[] block,
  142. * updating the fields of @c data as appropriate.
  143. */
  144. int ThinkGearStreamParser::parsePacketPayload() {
  145. unsigned char i = 0;
  146. unsigned char extendedCodeLevel = 0;
  147. unsigned char code = 0;
  148. unsigned char numBytes = 0;
  149. /* Parse all bytes from the payload[] */
  150. while( i < payloadLength ) {
  151. /* Parse possible EXtended CODE bytes */
  152. while( payload[i] == PARSER_EXCODE_BYTE ) {
  153. extendedCodeLevel++;
  154. i++;
  155. }
  156. /* Parse CODE */
  157. code = payload[i++];
  158. /* Parse value length */
  159. if( code >= 0x80 ) numBytes = payload[i++];
  160. else numBytes = 1;
  161. /* Call the callback function to handle the DataRow value */
  162. ThinkGearStreamParser::handleDataValue( extendedCodeLevel, code, numBytes,
  163. payload+i);
  164. i = (unsigned char)(i + numBytes);
  165. }
  166. return( 0 );
  167. }
  168. void ThinkGearStreamParser::handleDataValue(unsigned char extendedCodeLevel,
  169. unsigned char code,
  170. unsigned char valueLength,
  171. const unsigned char *value)
  172. {
  173. if( extendedCodeLevel == 0 ) {
  174. switch( code ) {
  175. /* [CODE]: ATTENTION eSense */
  176. case( 0x04 ):
  177. qDebug() << "Attention Level: " << (value[0] & 0xFF);
  178. emit attentionLevel(value[0] & 0xFF);
  179. break;
  180. /* [CODE]: MEDITATION eSense */
  181. case( 0x05 ):
  182. qDebug() << "Meditation Level: " << (value[0] & 0xFF);
  183. emit meditationLevel(value[0] & 0xFF);
  184. break;
  185. /* Other [CODE]s */
  186. default:
  187. qDebug() << "No valid data";
  188. }
  189. }
  190. }