00001
00002
00003
00004
00005
00006
00007
00021 #include "ThinkGearStreamParser.h"
00022
00023
00024
00025
00026 #include <stdio.h>
00027
00028
00029 #define PARSER_STATE_NULL 0x00
00030 #define PARSER_STATE_SYNC 0x01
00031 #define PARSER_STATE_SYNC_CHECK 0x02
00032 #define PARSER_STATE_PAYLOAD_LENGTH 0x03
00033 #define PARSER_STATE_PAYLOAD 0x04
00034 #define PARSER_STATE_CHKSUM 0x05
00035
00036
00037 #define PARSER_STATE_WAIT_HIGH 0x06
00038 #define PARSER_STATE_WAIT_LOW 0x07
00039
00040
00041 #define PARSER_SYNC_BYTE 0xAA
00042 #define PARSER_EXCODE_BYTE 0x55
00043
00044
00045 int
00046 parsePacketPayload( ThinkGearStreamParser *parser );
00047 int
00048 parseDataRow( ThinkGearStreamParser *parser, unsigned char *rowPtr );
00049
00050
00051
00052
00053 int
00054 THINKGEAR_initParser( ThinkGearStreamParser *parser,
00055 unsigned char parserType,
00056 void (*handleDataValueFunc)(
00057 unsigned char extendedCodeLevel,
00058 unsigned char code, unsigned char numBytes,
00059 const unsigned char *value, void *customData),
00060 void *customData ) {
00061
00062 if( !parser ) return( -1 );
00063
00064
00065 switch( parserType ) {
00066 case( PARSER_TYPE_PACKETS ):
00067 parser->state = PARSER_STATE_SYNC;
00068 break;
00069 case( PARSER_TYPE_2BYTERAW ):
00070 parser->state = PARSER_STATE_WAIT_HIGH;
00071 break;
00072 default: return( -2 );
00073 }
00074
00075
00076 parser->type = parserType;
00077
00078
00079 parser->handleDataValue = handleDataValueFunc;
00080 parser->customData = customData;
00081
00082 return( 0 );
00083 }
00084
00085
00086
00087
00088 int
00089 THINKGEAR_parseByte( ThinkGearStreamParser *parser, unsigned char byte ) {
00090
00091 int returnValue = 0;
00092
00093 if( !parser ) return( -1 );
00094
00095
00096 switch( parser->state ) {
00097
00098
00099 case( PARSER_STATE_SYNC ):
00100 if( byte == PARSER_SYNC_BYTE ) {
00101 parser->state = PARSER_STATE_SYNC_CHECK;
00102 }
00103 break;
00104
00105
00106 case( PARSER_STATE_SYNC_CHECK ):
00107 if( byte == PARSER_SYNC_BYTE ) {
00108 parser->state = PARSER_STATE_PAYLOAD_LENGTH;
00109 } else {
00110 parser->state = PARSER_STATE_SYNC;
00111 }
00112 break;
00113
00114
00115 case( PARSER_STATE_PAYLOAD_LENGTH ):
00116 parser->payloadLength = byte;
00117 if( parser->payloadLength > 170 ) {
00118 parser->state = PARSER_STATE_SYNC;
00119 returnValue = -3;
00120 } else if( parser->payloadLength == 170 ) {
00121 returnValue = -4;
00122 } else {
00123 parser->payloadBytesReceived = 0;
00124 parser->payloadSum = 0;
00125 parser->state = PARSER_STATE_PAYLOAD;
00126 }
00127 break;
00128
00129
00130 case( PARSER_STATE_PAYLOAD ):
00131 parser->payload[parser->payloadBytesReceived++] = byte;
00132 parser->payloadSum = (unsigned char)(parser->payloadSum + byte);
00133 if( parser->payloadBytesReceived >= parser->payloadLength ) {
00134 parser->state = PARSER_STATE_CHKSUM;
00135 }
00136 break;
00137
00138
00139 case( PARSER_STATE_CHKSUM ):
00140 parser->chksum = byte;
00141 parser->state = PARSER_STATE_SYNC;
00142 if( parser->chksum != ((~parser->payloadSum)&0xFF) ) {
00143 returnValue = -2;
00144 } else {
00145 returnValue = 1;
00146 parsePacketPayload( parser );
00147 }
00148 break;
00149
00150
00151 case( PARSER_STATE_WAIT_HIGH ):
00152
00153
00154 if( (byte & 0xC0) == 0x80 ) {
00155
00156 parser->state = PARSER_STATE_WAIT_LOW;
00157 }
00158 break;
00159
00160
00161 case( PARSER_STATE_WAIT_LOW ):
00162
00163
00164 if( (byte & 0xC0) == 0x40 ) {
00165
00166
00167 parser->payload[0] = parser->lastByte;
00168 parser->payload[1] = byte;
00169
00170
00171 if( parser->handleDataValue ) {
00172 parser->handleDataValue( 0, PARSER_CODE_RAW_SIGNAL, 2,
00173 parser->payload,
00174 parser->customData );
00175 }
00176
00177 returnValue = 1;
00178 }
00179
00180
00181 parser->state = PARSER_STATE_WAIT_HIGH;
00182
00183 break;
00184
00185
00186 default:
00187 parser->state = PARSER_STATE_SYNC;
00188 returnValue = -5;
00189 break;
00190 }
00191
00192
00193 parser->lastByte = byte;
00194
00195 return( returnValue );
00196 }
00197
00202 int
00203 parsePacketPayload( ThinkGearStreamParser *parser ) {
00204
00205 unsigned char i = 0;
00206 unsigned char extendedCodeLevel = 0;
00207 unsigned char code = 0;
00208 unsigned char numBytes = 0;
00209
00210
00211 while( i < parser->payloadLength ) {
00212
00213
00214 while( parser->payload[i] == PARSER_EXCODE_BYTE ) {
00215 extendedCodeLevel++;
00216 i++;
00217 }
00218
00219
00220 code = parser->payload[i++];
00221
00222
00223 if( code >= 0x80 ) numBytes = parser->payload[i++];
00224 else numBytes = 1;
00225
00226
00227 if( parser->handleDataValue ) {
00228 parser->handleDataValue( extendedCodeLevel, code, numBytes,
00229 parser->payload+i, parser->customData );
00230 }
00231 i = (unsigned char)(i + numBytes);
00232 }
00233
00234 return( 0 );
00235 }