void xpcc::sab::Interface<Device>::sendMessage(uint8_t address, Flags flags, uint8_t command, const void *payload, uint8_t payloadLength) { uint8_t crcSend; Device::write(syncByte); Device::write(payloadLength); crcSend = crcUpdate(crcInitialValue, payloadLength); Device::write(address | flags); crcSend = crcUpdate(crcSend, address | flags); Device::write(command); crcSend = crcUpdate(crcSend, command); const uint8_t *ptr = static_cast<const uint8_t *>(payload); for (uint_fast8_t i = 0; i < payloadLength; ++i) { crcSend = crcUpdate(crcSend, *ptr); Device::write(*ptr); ptr++; } Device::write(crcSend); }
void xpcc::sab::Interface<Device>::update() { uint8_t byte; while (Device::read(byte)) { //XPCC_LOG_DEBUG.printf("%02x ", byte); switch (state) { case SYNC: if (byte == syncByte) { state = LENGTH; } break; case LENGTH: if (byte > maxPayloadLength) { state = SYNC; } else { length = byte + 3; // +3 for header, command and crc byte position = 0; crc = crcUpdate(crcInitialValue, byte); state = DATA; } break; case DATA: buffer[position] = byte; crc = crcUpdate(crc, byte); position += 1; if (position >= length) { if (crc == 0) { lengthOfReceivedMessage = length; //XPCC_LOG_DEBUG << "SAB received" << xpcc::endl; } else { //XPCC_LOG_ERROR << "CRC error" << xpcc::endl; } state = SYNC; } break; default: state = SYNC; break; } } }
/////////////////////////////////////////////////////////////////////////////// // CalcHash /////////////////////////////////////////////////////////////////////////////// uint32 eError::CalcHash( const char* name ) { CRC_INFO crc; crcInit( crc ); crcUpdate( crc, (const uint8*)name, strlen( name ) ); crcFinit( crc ); return crc.crc; }
static inline u16 getCRC( u16 p_start, u16 p_length ) { int i; u16 data; u16 crc = 0xffff; for (i=0;i < p_length;i+=2) { data = pgm_read_word( p_start+i ); crc = crcUpdate( crc, data >> 8); crc = crcUpdate( crc, data & 0xff ); } return crc; }
/* ===================== loadBotResource ===================== */ static botEntry_t *loadBotResource( TCHAR *szPath ) { BYTE buff[BLOCK_SIZE]; HANDLE hFile; DWORD tmp; //TCHAR szName[NAMESIZE]; botEntry_t *botEntry; hFile = N_FOpenR( szPath ); if( hFile == INVALID_HANDLE_VALUE ) { return NULL; } //increase map count // k_system.cBots++; //increase memory // if( k_system.pBots ) { k_system.pBots = N_Realloc( k_system.pBots, sizeof(botEntry_t)*k_system.cBots ); } else { k_system.pBots = N_Malloc( sizeof(botEntry_t)*k_system.cBots ); } //obtain map entry pointer // botEntry = &( k_system.pBots[ k_system.cBots - 1 ] ); //calculate CRC // crcInit( &(botEntry->fe.dwCRC) ); while( ReadFile( hFile, buff, BLOCK_SIZE, &tmp, NULL ) ) { if( tmp == 0 ) { break; } crcUpdate( &(botEntry->fe.dwCRC), buff, tmp ); } crcFinish( &(botEntry->fe.dwCRC ) ); N_FClose( hFile ); //get bot name // //getBotName( szPath, botEntry->bot.name ); return botEntry; }
/* ===================== loadMapResource ===================== */ static mapEntry_t * loadMapResource( TCHAR *szPath ) { BYTE buff[BLOCK_SIZE]; HANDLE hFile; DWORD tmp; mapEntry_t *mapEntry; hFile = N_FOpenR( szPath ); if( hFile == INVALID_HANDLE_VALUE ) { return NULL; } //increase map count // k_system.cMaps++; //increase memory // if( k_system.pMaps ) { k_system.pMaps = N_Realloc( k_system.pMaps, sizeof( mapEntry_t ) * k_system.cMaps ); } else { k_system.pMaps = N_Malloc( sizeof( mapEntry_t ) * k_system.cMaps ); } //obtain map entry pointer // mapEntry = &( k_system.pMaps[ k_system.cMaps - 1 ] ); //calculate CRC // crcInit( &(mapEntry->fe.dwCRC) ); while( ReadFile( hFile, buff, BLOCK_SIZE, &tmp, NULL ) ) { if( tmp == 0 ) { break; } crcUpdate( &(mapEntry->fe.dwCRC), buff, tmp ); } crcFinish( &(mapEntry->fe.dwCRC ) ); N_FClose( hFile ); //get map name // //getMapName( szPath, mapEntry->map.name ); return mapEntry; }
/* ===================== playDemo ===================== */ BOOL playDemo() { repHeader_t repHeader = {0}; HANDLE hFile = INVALID_HANDLE_VALUE; TCHAR szRepPath[MAX_PATH]; DWORD crc; DWORD tmp; BYTE buff[BLOCK_SIZE]; BOOL bRes; int mapID; int i; __try { bRes = FALSE; //get replay file path // if( !GetLoadPath( k_system.hwnd, TEXT( "(*.rep)\0*.rep" ), TEXT( "*.rep" ), szRepPath ) ) { __leave; } //open replay file // hFile = N_FOpenR( szRepPath ); if( hFile == INVALID_HANDLE_VALUE ) { __leave; } //read header // N_FRead( hFile, &repHeader, sizeof(repHeader) ); //check header // if( repHeader.header != REPLAYHEADER ) { __leave; } //check map availability // if( (repHeader.mapCRC != 0) && !seeMapID( repHeader.mapCRC, NULL ) ) { __leave; } //check CRC // crcInit( &crc ); while( ReadFile( hFile, buff, BLOCK_SIZE, &tmp, NULL ) ) { if( tmp == 0 ) { break; } crcUpdate( &crc, buff, tmp ); } crcFinish( &crc ); if( repHeader.crc != crc ) { __leave; } //restore file position // N_FSeek( hFile, sizeof(repHeader), FILE_BEGIN ); //end all running games // endAllGames(); //decompress replay data // if( beginDecompress( szRepPath, sizeof(repHeader), gszTmpPath, NULL ) ) { ghRepFile = N_FOpenR( gszTmpPath ); if( ghRepFile == INVALID_HANDLE_VALUE ) { __leave; } //read figure data // N_FRead( ghRepFile, &k_replayFigSize, sizeof(k_replayFigSize) ); k_replayFig = N_Malloc( k_replayFigSize*sizeof(figure_t) ); for( i=0; i<k_replayFigSize; i++ ) { N_FRead( ghRepFile, &(k_replayFig[i].type), sizeof(k_replayFig[i].type) ); N_FRead( ghRepFile, &(k_replayFig[i].state), sizeof(k_replayFig[i].state) ); } k_replayFigID = 0; bRes = TRUE; } } __finally { if( hFile != INVALID_HANDLE_VALUE ) { N_FClose( hFile ); } //check if failed // if( bRes == FALSE ) { if( k_replayFig ) { N_Free( k_replayFig ); k_replayFig = NULL; k_replayFigSize = 0; } } } //play demo // if( bRes ) { k_system.flags |= SF_DEMOPLAY; //find map // if( repHeader.mapCRC == 0 ) { k_system.idMap = -1; } else { if( seeMapID( repHeader.mapCRC, &mapID ) ) { k_system.idMap = mapID; } else { return FALSE; } } //start the game // switch( repHeader.gametype ) { case GSINGLE: singleGameStart(); break; case GVS: vsGameStart(); break; default: return FALSE; } //schedule frame // N_FRead( ghRepFile, &gFrame, sizeof(gFrame) ); pushTimeSlice( TIME_REPLAY_FRAME, gFrame.time, gFrame.time, NULL, REPLAY, FALSE ); N_Message( TEXT( "Replaying: %s" ), szRepPath ); } return bRes; }
/* ===================== endReplaySystem ===================== */ BOOL endReplaySystem() { repHeader_t repHeader = {0}; HANDLE hFile; HANDLE hTmpFile; BYTE buff[BLOCK_SIZE]; TCHAR szRepTmpPath[MAX_PATH]; TCHAR szRepPath[MAX_PATH]; TCHAR szTmpPath[MAX_PATH]; TCHAR szArchPath[MAX_PATH]; DWORD crc; DWORD tmp, tmp2; int i; //this will make replay hold till //the end. // addReplayFrame( NOMOVE, LEFTGAME ); N_FClose( ghRepFile ); //create paths // N_Sprintf( szTmpPath, MAX_PATH, TEXT( "%s\\demos\\~demo.rep" ), kcfTable[VAR_BASE].v.s ); N_Sprintf( szRepPath, MAX_PATH, TEXT( "%s\\demos\\demo_%i.rep" ), kcfTable[VAR_BASE].v.s, gSuffix ); N_Sprintf( szRepTmpPath, MAX_PATH, TEXT( "%s.tmp" ), szRepPath ); N_Sprintf( szArchPath, MAX_PATH, TEXT( "%s.z" ), szRepTmpPath); //create temporary replay file // hFile = N_FOpenC( szRepTmpPath ); if( hFile == INVALID_HANDLE_VALUE ) { return FALSE; } //write figure data // N_FWrite( hFile, &k_replayFigSize, sizeof(k_replayFigSize) ); for( i=0; i<k_replayFigSize; i++ ) { N_FWrite( hFile, &(k_replayFig[i].type), sizeof(k_replayFig[i].type) ); N_FWrite( hFile, &(k_replayFig[i].state), sizeof(k_replayFig[i].state) ); } //copy replay data from temporary file // hTmpFile = N_FOpenR( szTmpPath ); while( ReadFile( hTmpFile, buff, BLOCK_SIZE, &tmp, NULL ) ) { if( tmp == 0 ) { break; } WriteFile( hFile, buff, tmp, &tmp2, NULL ); } N_FClose( hTmpFile ); N_FClose( hFile ); //create replay file // hFile = N_FOpenC( szRepPath ); //write header // repHeader.header = REPLAYHEADER; repHeader.gametype = gGameType; if( gMapID >= 0 ) { repHeader.mapCRC = k_system.pMaps[gMapID].fe.dwCRC; } else { repHeader.mapCRC = 0; } N_FWrite( hFile, &repHeader, sizeof(repHeader) ); crcInit( &crc ); //compress // if( beginCompress( szRepTmpPath ) ) { hTmpFile = N_FOpenR( szArchPath ); while( ReadFile( hTmpFile, buff, BLOCK_SIZE, &tmp, NULL ) ) { if( tmp == 0 ) { break; } WriteFile( hFile, buff, tmp, &tmp2, NULL ); crcUpdate( &crc, buff, tmp ); } N_FClose( hTmpFile ); endCompress( szRepTmpPath ); } crcFinish( &crc ); //write CRC // repHeader.crc = crc; N_FSeek( hFile, 0, FILE_BEGIN ); N_FWrite( hFile, &repHeader, sizeof(repHeader) ); //clean-up // N_FClose( hFile ); //delete ~demo.rep and demo_%i.rep.tmp // DeleteFile( szTmpPath ); DeleteFile( szRepTmpPath ); N_Free( k_replayFig ); k_replayFig = NULL; k_replayFigSize = 0; k_replayFigID = 0; gFrameTime = 0; gGameType = GNO; gMapID = -1; k_system.flags &= ~SF_RECORDING; return TRUE; }
void xpcc::rpr::Interface<Device, N>::update() { uint8_t data; if (status & STATUS_END_DELIMITER_RECEIVED && !messagesToSend.isEmpty()) { writeMessage(getMessage(messagesToSend)); popMessage(messagesToSend); } while (Device::read(data)) { XPCC_RPR_LOG("receiving raw " << xpcc::hex << data << xpcc::ascii); if (data == startDelimiterByte) { status &= ~STATUS_END_DELIMITER_RECEIVED; status |= STATUS_START_DELIMITER_RECEIVED; XPCC_RPR_LOG("start delimiter"); crc = crcInitialValue; length = 0; nextEscaped = false; // we do not send the frame boundaries here, but wait for the AC. } else if (data == endDelimiterByte) { if (length >= 6 && (status & STATUS_START_DELIMITER_RECEIVED)) { status &= ~STATUS_START_DELIMITER_RECEIVED; status |= STATUS_END_DELIMITER_RECEIVED; if (!(status & STATUS_SOURCE_RECOGNISED) && (receiveBuffer.type != MESSAGE_TYPE_UNICAST)) { XPCC_RPR_LOG("tx: forwarding endDelimiterByte"); Device::write(endDelimiterByte); } XPCC_RPR_LOG("end delimiter with length=" << length); if (status & STATUS_DESTINATION_RECOGNISED) { if (crc == 0) { XPCC_RPR_LOG("crc check success"); if (receiveBuffer.length > 1) { receiveBuffer.command = receiveBuffer.payload[0]; receiveBuffer.payload += 1; receiveBuffer.length -= 1; } pushMessage(receivedMessages, &receiveBuffer); receiveBuffer.payload = rx_buffer; } else { XPCC_RPR_LOG("crc check failure"); } } } crc = crcInitialValue; length = 0; nextEscaped = false; } else if (data == controlEscapeByte) { // the next byte is escaped nextEscaped = true; XPCC_RPR_LOG("escape sequence"); continue; } else { if (nextEscaped) { nextEscaped = false; // toggle bit 5 data = data ^ 0x20; XPCC_RPR_LOG("data escaped"); } // all data is now escaped // make sure we actually received a start delimiter before the payload if (!(status & STATUS_START_DELIMITER_RECEIVED)) return; switch (length++) { // LSB of destination address case 0: XPCC_RPR_LOG("rx: LSB dest"); addressBuffer = data; break; // MSB of destination address case 1: { XPCC_RPR_LOG("rx: MSB dest"); // check the destination address against our own uint16_t dest = (data << 8) | addressBuffer; status &= ~(STATUS_DESTINATION_RECOGNISED | STATUS_RX_BUFFER_OVERFLOW | STATUS_SOURCE_RECOGNISED); receiveBuffer.type = MESSAGE_TYPE_ANY; receiveBuffer.destination = dest; receiveBuffer.length = 0; // it is a broadcast, we need to listen if (receiveBuffer.destination == ADDRESS_BROADCAST) { XPCC_RPR_LOG("rx: broadcast"); receiveBuffer.type = MESSAGE_TYPE_BROADCAST; status |= STATUS_DESTINATION_RECOGNISED; } else { if (receiveBuffer.destination & ADDRESS_INDIVIDUAL_GROUP) { // group address if (_groupAddress == (receiveBuffer.destination & ADDRESS_VALUE)) { XPCC_RPR_LOG("rx: my group"); receiveBuffer.type = MESSAGE_TYPE_MULTICAST; status |= STATUS_DESTINATION_RECOGNISED; } } else { // individual address if (_address == (receiveBuffer.destination & ADDRESS_VALUE)) { XPCC_RPR_LOG("rx: my address"); receiveBuffer.type = MESSAGE_TYPE_UNICAST; status |= STATUS_DESTINATION_RECOGNISED; } } } if (status & STATUS_DESTINATION_RECOGNISED) { crc = crcUpdate(crc, addressBuffer); crc = crcUpdate(crc, data); } } break; // LSB of source address case 2: XPCC_RPR_LOG("rx: LSB source"); addressBuffer = data; break; // MSB of Source Address case 3: { XPCC_RPR_LOG("rx: MSB source"); // check the source address against our own uint16_t source = (data << 8) | addressBuffer; receiveBuffer.source = (source & ADDRESS_VALUE); if (_address == receiveBuffer.source) { status |= STATUS_SOURCE_RECOGNISED; } if (status & STATUS_DESTINATION_RECOGNISED) { crc = crcUpdate(crc, addressBuffer); crc = crcUpdate(crc, data); } if (!(status & STATUS_SOURCE_RECOGNISED) && (receiveBuffer.type != MESSAGE_TYPE_UNICAST)) { XPCC_RPR_LOG("tx: forwarding destination"); Device::write(startDelimiterByte); writeByteEscaped(receiveBuffer.destination); writeByteEscaped(receiveBuffer.destination >> 8); XPCC_RPR_LOG("tx: forwarding source"); writeByteEscaped(addressBuffer); writeByteEscaped(data); } else { XPCC_RPR_LOG("rx: no forwarding"); } } break; default: if (status & STATUS_DESTINATION_RECOGNISED) { if (length <= N+8) { XPCC_RPR_LOG("rx: buffering payload"); receiveBuffer.payload[length-5] = data; receiveBuffer.length++; crc = crcUpdate(crc, data); } else { // really, really bad programmer ! // now go sit in the corner and increase dat payload buffer status |= STATUS_RX_BUFFER_OVERFLOW; XPCC_RPR_LOG("rx: buffer overflow!!!"); } } if (!(status & STATUS_SOURCE_RECOGNISED) && (receiveBuffer.type != MESSAGE_TYPE_UNICAST)) { XPCC_RPR_LOG("forwarding payload"); writeByteEscaped(data); } break; } }