123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222 |
- /*
- * @(#)ThinkGearStreamParser.c 2.0 Mar 04, 2008
- *
- * Copyright (c) 2008 NeuroSky, Inc. All Rights Reserved
- * NEUROSKY PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
- */
- /*
- Copyright (c) 2010 Embedded Systems and Pervasive Laboratory, Federal
- University of Campina Grande, Brazil, Angelo Perkusich, Mirko Perkusich,
- Taciana Rached
- Permission is hereby granted, free of charge, to any person obtaining a
- copy of this software and associated documentation files (the
- "Software"), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
- /**
- * @file ThinkGearStreamParser.c
- *
- * @author Kelvin Soo
- * @version 2.0 Mar 04, 2008 Kelvin Soo
- * - Renamed to ThinkGearStreamParser from ThinkGearStreamDecoder.
- * - Revised to call a callback function instead of stuffing arriving
- * data values into a ThinkGearData object.
- * - Renamed symbols according to updated Packet vocabulary.
- * @version 1.0 Nov 27, 2007 Kelvin Soo
- * - Initial version (ThinkGearStreamDecoder).
- */
- #include "ThinkGearStreamParser.h"
- /* Include libraries required specifically by this implementation of this
- * library and not already included by this library's header
- */
- #include <stdio.h>
- /* Decoder states (Packet decoding) */
- #define PARSER_STATE_NULL 0x00 /* NULL state */
- #define PARSER_STATE_SYNC 0x01 /* Waiting for SYNC byte */
- #define PARSER_STATE_SYNC_CHECK 0x02 /* Waiting for second SYNC byte */
- #define PARSER_STATE_PAYLOAD_LENGTH 0x03 /* Waiting for payload[] length */
- #define PARSER_STATE_PAYLOAD 0x04 /* Waiting for next payload[] byte */
- #define PARSER_STATE_CHKSUM 0x05 /* Waiting for chksum byte */
- /* Decoder states (2-byte raw decoding) */
- #define PARSER_STATE_WAIT_HIGH 0x06 /* Waiting for high byte */
- #define PARSER_STATE_WAIT_LOW 0x07 /* High r'cvd. Expecting low part */
- /* Other constants */
- #define PARSER_SYNC_BYTE 0xAA /* Syncronization byte */
- #define PARSER_EXCODE_BYTE 0x55 /* EXtended CODE level byte */
- /*
- * See header file for interface documentation.
- */
- ThinkGearStreamParser::ThinkGearStreamParser()
- {
- int parserType = PARSER_TYPE_PACKETS;
- /* Initialize the parser's state based on the parser type */
- switch( parserType ) {
- case( PARSER_TYPE_PACKETS ):
- state = PARSER_STATE_SYNC;
- break;
- case( PARSER_TYPE_2BYTERAW ):
- state = PARSER_STATE_WAIT_HIGH;
- break;
- }
- /* Save parser type */
- type = parserType;
- }
- /*
- * See header file for interface documentation.
- */
- int ThinkGearStreamParser::parseByte( unsigned char byte ) {
- int returnValue = 0;
- /* Pick handling according to current state... */
- switch( state ) {
- /* Waiting for SyncByte */
- case( PARSER_STATE_SYNC ):
- if( byte == PARSER_SYNC_BYTE ) {
- state = PARSER_STATE_SYNC_CHECK;
- }
- break;
- /* Waiting for second SyncByte */
- case( PARSER_STATE_SYNC_CHECK ):
- if( byte == PARSER_SYNC_BYTE ) {
- state = PARSER_STATE_PAYLOAD_LENGTH;
- } else {
- state = PARSER_STATE_SYNC;
- }
- break;
- /* Waiting for Data[] length */
- case( PARSER_STATE_PAYLOAD_LENGTH ):
- payloadLength = byte;
- if( payloadLength > 170 ) {
- state = PARSER_STATE_SYNC;
- returnValue = -3;
- } else if( payloadLength == 170 ) {
- returnValue = -4;
- } else {
- payloadBytesReceived = 0;
- payloadSum = 0;
- state = PARSER_STATE_PAYLOAD;
- }
- break;
- /* Waiting for Payload[] bytes */
- case( PARSER_STATE_PAYLOAD ):
- payload[payloadBytesReceived++] = byte;
- payloadSum = (unsigned char)(payloadSum + byte);
- if( payloadBytesReceived >= payloadLength ) {
- state = PARSER_STATE_CHKSUM;
- }
- break;
- /* Waiting for CKSUM byte */
- case( PARSER_STATE_CHKSUM ):
- chksum = byte;
- state = PARSER_STATE_SYNC;
- if( chksum != ((~payloadSum)&0xFF) ) {
- returnValue = -2;
- } else {
- returnValue = 1;
- parsePacketPayload();
- }
- break;
- /* unrecognized state */
- default:
- state = PARSER_STATE_SYNC;
- returnValue = -5;
- break;
- }
- /* Save current byte */
- lastByte = byte;
- return( returnValue );
- }
- /**
- * Parses each row of data from the @c packet's Data[] block,
- * updating the fields of @c data as appropriate.
- */
- int ThinkGearStreamParser::parsePacketPayload() {
- unsigned char i = 0;
- unsigned char extendedCodeLevel = 0;
- unsigned char code = 0;
- unsigned char numBytes = 0;
- /* Parse all bytes from the payload[] */
- while( i < payloadLength ) {
- /* Parse possible EXtended CODE bytes */
- while( payload[i] == PARSER_EXCODE_BYTE ) {
- extendedCodeLevel++;
- i++;
- }
- /* Parse CODE */
- code = payload[i++];
- /* Parse value length */
- if( code >= 0x80 ) numBytes = payload[i++];
- else numBytes = 1;
- /* Call the callback function to handle the DataRow value */
- ThinkGearStreamParser::handleDataValue( extendedCodeLevel, code, numBytes,
- payload+i);
- i = (unsigned char)(i + numBytes);
- }
- return( 0 );
- }
- void ThinkGearStreamParser::handleDataValue(unsigned char extendedCodeLevel,
- unsigned char code,
- unsigned char valueLength,
- const unsigned char *value)
- {
- if( extendedCodeLevel == 0 ) {
- switch( code ) {
- /* [CODE]: ATTENTION eSense */
- case( 0x04 ):
- qDebug() << "Attention Level: " << (value[0] & 0xFF);
- emit attentionLevel(value[0] & 0xFF);
- break;
- /* [CODE]: MEDITATION eSense */
- case( 0x05 ):
- qDebug() << "Meditation Level: " << (value[0] & 0xFF);
- emit meditationLevel(value[0] & 0xFF);
- break;
- /* Other [CODE]s */
- default:
- qDebug() << "No valid data";
- }
- }
- }
|