/* appMain is the application. it is called every loop through main, as does the USB handler code. * do not block if you want USB to work. */ void appMainLoop(void) { __xdata u8 processbuffer; #ifdef TRANSMIT_TEST __xdata u8 testPacket[14]; if (loopCnt++ == 90000) { /* Send a packet */ testPacket[0] = 0x0D; testPacket[1] = xmitCnt++; testPacket[2] = 0x48; testPacket[3] = 0x41; testPacket[4] = 0x4C; testPacket[5] = 0x4C; testPacket[6] = 0x4F; //testPacket[6] = 0x43; //testPacket[7] = 0x43; testPacket[7] = lastCode[0]; testPacket[8] = lastCode[1]; testPacket[9] = 0x31; testPacket[10] = 0x31; testPacket[11] = 0x31; testPacket[12] = 0x31; transmit(testPacket, 13, 0, 0); //blink(400,400); REALLYFASTBLINK(); #ifndef VIRTUAL_COM debug("sent packet..."); #endif loopCnt = 0; } #endif if (rfif) { lastCode[0] = 0xd; IEN2 &= ~IEN2_RFIE; if(rfif & RFIF_IRQ_DONE) { processbuffer = !rfRxCurrentBuffer; if(rfRxProcessed[processbuffer] == RX_UNPROCESSED) { if (PKTCTRL0&1) // variable length packets have a leading "length" byte, let's skip it txdata(APP_NIC, NIC_RECV, (u8)rfrxbuf[processbuffer][0], (u8*)&rfrxbuf[processbuffer][1]); else txdata(APP_NIC, NIC_RECV, PKTLEN, (u8*)&rfrxbuf[processbuffer]); /* Set receive buffer to processed so it can be used again */ rfRxProcessed[processbuffer] = RX_PROCESSED; } } rfif = 0; IEN2 |= IEN2_RFIE; } }
void write(uint8_t address, char data) { //write any data byte to any single address //adds a 0 to the MSB of the address byte (WRITE mode) address |= 0x80; cbi(CSPORT,CS); delay_ms(1); txdata(address); delay_ms(1); txdata(data); delay_ms(1); sbi(CSPORT,CS); }
//! Handle a command. void handle(unsigned char app, unsigned char verb, unsigned char len){ switch(app){ case MONITOR: monitorhandle(app,verb,len); break; case SPI: spihandle(app,verb,len); break; case I2CAPP: i2chandle(app,verb,len); break; case CHIPCON: cchandle(app,verb,len); break; case JTAG: jtaghandle(app,verb,len); break; case JTAG430: //Also JTAG430X, JTAG430X2 jtag430x2handle(app,verb,len); break; default: #ifdef HANDLEOTHER HANDLEOTHER(app,verb,len); #else txdata(app,NOK,0); #endif break; } }
//! Handle a command. void handle(uint8_t const app, uint8_t const verb, uint32_t const len){ int i; //debugstr("GoodFET"); //led_off(); // find the app and call the handle fn for(i = 0; i < num_apps; i++){ if(apps[i]->app == app){ // call the app's handle fn (*(apps[i]->handle))(app, verb, len); // exit early return; } } // if we get here, then the desired app is not compiled into // this firmware debugstr("App missing."); debughex(app); txdata(app, NOK, 0); }
/* sends a debug message up to the python code to be spit out on stderr */ void debug(code u8* text) { u16 len = 0; code u8* ptr = text; while (*ptr++ != 0) len ++; txdata(0xfe, 0xf0, len, (xdata u8*)text); }
//! Handles a monitor command. void flash_handle_fn( uint8_t const app, uint8_t const verb, uint32_t const len) { switch(verb) { case 0x21: eraseflash(cmddataword[0]); txdata(app,0,0); break; case 0x22: writeflash(cmddataword[0], cmddata[2]); txdata(app,0,0); break; case 0x23: cmddata[0] = readflash(cmddataword[0]); txdata(app,0,1); break; } }
/* appMain is the application. it is called every loop through main, as does the USB handler code. * do not block if you want USB to work. */ void appMainLoop(void) { xdata u8 processbuffer; #ifdef TRANSMIT_TEST xdata u8 testPacket[14]; if (loopCnt++ == 90000) { /* Send a packet */ testPacket[0] = 0x0D; testPacket[1] = xmitCnt++; testPacket[2] = 0x48; testPacket[3] = 0x41; testPacket[4] = 0x4C; testPacket[5] = 0x4C; testPacket[6] = 0x4F; //testPacket[6] = 0x43; //testPacket[7] = 0x43; testPacket[7] = lastCode[0]; testPacket[8] = lastCode[1]; testPacket[9] = 0x31; testPacket[10] = 0x31; testPacket[11] = 0x31; testPacket[12] = 0x31; transmit(testPacket, 14); //blink(400,400); REALLYFASTBLINK(); debug("sent packet..."); loopCnt = 0; } #endif if (rfif) { lastCode[0] = 0xd; IEN2 &= ~IEN2_RFIE; if(rfif & RFIF_IRQ_DONE) { processbuffer = !rfRxCurrentBuffer; if(rfRxProcessed[processbuffer] == RX_UNPROCESSED) { txdata(0xfe, 0xf0, (u8)rfrxbuf[processbuffer][0], (u8*)&rfrxbuf[processbuffer]); /* Set receive buffer to processed so it can be used again */ rfRxProcessed[processbuffer] = RX_PROCESSED; } } rfif = 0; IEN2 |= IEN2_RFIE; } }
//! Overwrite all of RAM with 0xBEEF, then reboot. void monitor_ram_pattern(){ register int *a; //Wipe all of ram. for(a=(int*)0x1100;a<(int*)0x2500;a++){//TODO get these from the linker. *((int*)a) = 0xBEEF; } txdata(0x00,0x90,0); //Reboot asm("br &0xfffe"); }
//! handles OpenOCD commands void openocd_handle_fn(uint8_t const app, uint8_t const verb, uint32_t const len) { switch(verb) { case START: /* do nothing...*/ txdata(app,OK,0); break; case STOP: openocd_stop(); txdata(app,OK,0); break; case SETUP: openocd_setup(); txdata(app,OK,0); break; case OPENOCD_RESET: openocd_reset(cmddata[0], cmddata[1]); txdata(app,OK,0); break; case OPENOCD_READ: cmddata[0] = READMISO; txdata(app,OK,1); break; case OPENOCD_WRITE: openocd_write(cmddata[0], cmddata[1], cmddata[2]); txdata(app,OK,0); break; case OPENOCD_LED: openocd_led(cmddata[0]); txdata(app,OK,0); break; default: txdata(app,NOK,0); } }
char read(uint8_t address) { //returns the contents of any 1 byte register from any address //sets the MSB for every address byte (READ mode) char byte; address &= 0x7F; cbi(CSPORT,CS); txdata(address); byte = rxdata(); sbi(CSPORT,CS); return byte; }
TEST(Validation, ContextualCheckInputsPassesWithCoinbase) { // Create fake coinbase transaction CMutableTransaction mtx; mtx.vin.resize(1); CTransaction tx(mtx); ASSERT_TRUE(tx.IsCoinBase()); // Fake an empty view FakeCoinsViewDB fakeDB; CCoinsViewCache view(&fakeDB); for (int idx = Consensus::BASE_SPROUT; idx < Consensus::MAX_NETWORK_UPGRADES; idx++) { auto consensusBranchId = NetworkUpgradeInfo[idx].nBranchId; CValidationState state; PrecomputedTransactionData txdata(tx); EXPECT_TRUE(ContextualCheckInputs(tx, state, view, false, 0, false, txdata, Params(CBaseChainParams::MAIN).GetConsensus(), consensusBranchId)); } }
unsigned short int SHT15::txreset (unsigned short int mode) { unsigned short int i; digitalWrite (SHT15_CLK, LOW); pinMode (SHT15_DAT, OUTPUT); digitalWrite (SHT15_DAT, HIGH); for (i = 0; i < 9; i++) { digitalWrite (SHT15_CLK, HIGH); delayMicroseconds (3); digitalWrite (SHT15_CLK, LOW); delayMicroseconds (3); } txbegin (); if (mode) return txdata (0x1e); return 0; }
// mode: 0 = temperature; 1 = humidity unsigned short int SHT15::getraw (unsigned short int * p, unsigned short int mode) { unsigned short int i = 0; txbegin (); * p = 0; mode = mode ? 0x05 : 0x03; if (txdata(mode)) return 1; // write error while (i < 240) { delay (3); if (digitalRead (SHT15_DAT) == 0) { i = 0; break; } } i++; if (i) return 3; // timeout i = rxdata (1); *p = (i << 8) | rxdata (0); return 0; }
// Run CheckInputs (using pcoinsTip) on the given transaction, for all script // flags. Test that CheckInputs passes for all flags that don't overlap with // the failing_flags argument, but otherwise fails. // CHECKLOCKTIMEVERIFY and CHECKSEQUENCEVERIFY (and future NOP codes that may // get reassigned) have an interaction with DISCOURAGE_UPGRADABLE_NOPS: if // the script flags used contain DISCOURAGE_UPGRADABLE_NOPS but don't contain // CHECKLOCKTIMEVERIFY (or CHECKSEQUENCEVERIFY), but the script does contain // OP_CHECKLOCKTIMEVERIFY (or OP_CHECKSEQUENCEVERIFY), then script execution // should fail. // Capture this interaction with the upgraded_nop argument: set it when evaluating // any script flag that is implemented as an upgraded NOP code. static void ValidateCheckInputsForAllFlags(CMutableTransaction &tx, uint32_t failing_flags, bool add_to_cache) { PrecomputedTransactionData txdata(tx); // If we add many more flags, this loop can get too expensive, but we can // rewrite in the future to randomly pick a set of flags to evaluate. for (uint32_t test_flags=0; test_flags < (1U << 16); test_flags += 1) { CValidationState state; // Filter out incompatible flag choices if ((test_flags & SCRIPT_VERIFY_CLEANSTACK)) { // CLEANSTACK requires P2SH and WITNESS, see VerifyScript() in // script/interpreter.cpp test_flags |= SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS; } if ((test_flags & SCRIPT_VERIFY_WITNESS)) { // WITNESS requires P2SH test_flags |= SCRIPT_VERIFY_P2SH; } bool ret = CheckInputs(tx, state, pcoinsTip.get(), true, test_flags, true, add_to_cache, txdata, nullptr); // CheckInputs should succeed iff test_flags doesn't intersect with // failing_flags bool expected_return_value = !(test_flags & failing_flags); BOOST_CHECK_EQUAL(ret, expected_return_value); // Test the caching if (ret && add_to_cache) { // Check that we get a cache hit if the tx was valid std::vector<CScriptCheck> scriptchecks; BOOST_CHECK(CheckInputs(tx, state, pcoinsTip.get(), true, test_flags, true, add_to_cache, txdata, &scriptchecks)); BOOST_CHECK(scriptchecks.empty()); } else { // Check that we get script executions to check, if the transaction // was invalid, or we didn't add to cache. std::vector<CScriptCheck> scriptchecks; BOOST_CHECK(CheckInputs(tx, state, pcoinsTip.get(), true, test_flags, true, add_to_cache, txdata, &scriptchecks)); BOOST_CHECK_EQUAL(scriptchecks.size(), tx.vin.size()); } } }
//! Handles a monitor command. void monitorhandle(unsigned char app, unsigned char verb, unsigned char len){ switch(verb){ case PEEK: cmddata[0]=memorybyte[cmddataword[0]]; txdata(app,verb,1); break; case POKE: //Todo, make word or byte. memorybyte[cmddataword[0]]=cmddata[2]; cmddata[0]=memorybyte[cmddataword[0]]; txdata(app,verb,1); break; case MONITOR_CHANGE_BAUD: //This command, and ONLY this command, does not reply. setbaud(cmddata[0]); //txdata(app,verb,0); break; case MONITOR_RAM_PATTERN: monitor_ram_pattern();//reboots, will never return break; case MONITOR_RAM_DEPTH: cmddataword[0]=monitor_ram_depth(); txdata(app,verb,2); break; case MONITOR_DIR: P5DIR=cmddata[0]; txdata(app,verb,1); break; case MONITOR_IN: cmddata[0]=P5IN; txdata(app,verb,1); break; case MONITOR_OUT: P5OUT=cmddata[0]; txdata(app,verb,1); break; } }
//! Handles MSP430X2 JTAG commands. Forwards others to JTAG. void jtag430x2_handle_fn( uint8_t const app, uint8_t const verb, uint32_t const len) { unsigned int i,val; unsigned long at, l; //jtag430_resettap(); if(verb!=START && jtag430mode==MSP430MODE){ (*(jtag430_app.handle))(app,verb,len); return; } switch(verb){ case START: //Enter JTAG mode. //do cmddata[0]=jtag430x2_start(); //while(cmddata[0]==00 || cmddata[0]==0xFF); //MSP430 or MSP430X if(jtagid==MSP430JTAGID){ //debugstr("ERROR, using JTAG430X2 instead of JTAG430!"); jtag430mode=MSP430MODE; /* So the way this works is that a width of 20 does some backward-compatibility finagling, causing the correct value to be exchanged for addresses on 16-bit chips as well as the new MSP430X chips. (This has only been verified on the MSP430F2xx family. TODO verify for others.) */ drwidth=20; //Perform a reset and disable watchdog. jtag430_por(); jtag430_writemem(0x120,0x5a80);//disable watchdog jtag430_haltcpu(); jtag430_resettap(); txdata(app,verb,1); return; }else if(jtagid==MSP430X2JTAGID){ jtag430mode=MSP430X2MODE; drwidth=20; }else{ debugstr("JTAG version unknown."); txdata(app,NOK,1); return; } jtag430x2_fusecheck(); jtag430x2_syncpor(); jtag430_resettap(); txdata(app,verb,1); break; case JTAG430_READMEM: case PEEK: at=cmddatalong[0]; //Fetch large blocks for bulk fetches, //small blocks for individual peeks. if(len>5) l=(cmddataword[2]);//always even. else l=2; l&=~1;//clear lsbit if(l<2) l=2; txhead(app,verb,l); for(i=0;i<l;i+=2){ //jtag430_resettap(); //delay(10); val=jtag430x2_readmem(at); at+=2; serial_tx(val&0xFF); serial_tx((val&0xFF00)>>8); } break; case JTAG430_COREIP_ID: cmddataword[0]=jtag430_coreid(); txdata(app,verb,2); break; case JTAG430_DEVICE_ID: cmddatalong[0]=jtag430_deviceid(); txdata(app,verb,4); break; case JTAG430_WRITEFLASH: case JTAG430_WRITEMEM: case POKE: jtag430x2_writemem(cmddatalong[0], cmddataword[2]); cmddataword[0]=jtag430x2_readmem(cmddatalong[0]); txdata(app,verb,2); break; //unimplemented functions case JTAG430_HALTCPU: //jtag430x2_haltcpu(); debugstr("Warning, not trying to halt for lack of code."); txdata(app,verb,0); break; case JTAG430_RELEASECPU: case JTAG430_SETINSTRFETCH: case JTAG430_ERASEFLASH: case JTAG430_SETPC: debugstr("This function is not yet implemented for MSP430X2."); debughex(verb); txdata(app,NOK,0); break; default: (*(jtag_app.handle))(app,verb,len); } jtag430_resettap(); }
/* TextureXList::writeTEXTUREXData * Writes the texture list in TEXTUREX format to [texturex], using * [patch_table] for patch information. Returns true on success, * false otherwise *******************************************************************/ bool TextureXList::writeTEXTUREXData(ArchiveEntry* texturex, PatchTable& patch_table) { // Check entry was given if (!texturex) return false; if (texturex->isLocked()) return false; wxLogMessage("Writing " + getTextureXFormatString() + " format TEXTUREx entry"); /* Total size of a TEXTUREx lump, in bytes: Header: 4 + (4 * numtextures) Textures: 22 * numtextures (normal format) 14 * numtextures (nameless format) 18 * numtextures (Strife 1.1 format) Patches: 10 * sum of patchcounts (normal and nameless formats) 6 * sum of patchcounts (Strife 1.1 format) */ size_t numpatchrefs = 0; size_t numtextures = textures.size(); for (size_t i = 0; i < numtextures; ++i) { numpatchrefs += textures[i]->nPatches(); } wxLogMessage("%i patch references in %i textures", numpatchrefs, numtextures); size_t datasize = 0; size_t headersize = 4 + (4 * numtextures); switch (txformat) { case TXF_NORMAL: datasize = 4 + (26 * numtextures) + (10 * numpatchrefs); break; case TXF_NAMELESS: datasize = 4 + (18 * numtextures) + (10 * numpatchrefs); break; case TXF_STRIFE11: datasize = 4 + (22 * numtextures) + ( 6 * numpatchrefs); break; // Some compilers insist on having default cases. default: return false; } MemChunk txdata(datasize); int32_t* offsets = new int32_t[numtextures]; int32_t foo = wxINT32_SWAP_ON_BE((signed) numtextures); // Write header txdata.seek(0, SEEK_SET); SAFEFUNC(txdata.write(&foo, 4)); // Go to beginning of texture definitions SAFEFUNC(txdata.seek(4 + (numtextures*4), SEEK_SET)); // Write texture entries for (size_t i = 0; i < numtextures; ++i) { // Get texture to write CTexture* tex = textures[i]; // Set offset offsets[i] = (signed)txdata.currentPos(); // Write texture entry switch (txformat) { case TXF_NORMAL: { // Create 'normal' doom format texture definition ftdef_t txdef; memset(txdef.name, 0, 8); // Set texture name to all 0's (to ensure compatibility with XWE) strncpy(txdef.name, CHR(tex->getName().Upper()), tex->getName().Len()); txdef.flags = 0; txdef.scale[0] = (tex->getScaleX()*8); txdef.scale[1] = (tex->getScaleY()*8); txdef.width = tex->getWidth(); txdef.height = tex->getHeight(); txdef.columndir[0] = 0; txdef.columndir[1] = 0; txdef.patchcount = tex->nPatches(); // Check for WorldPanning flag if (tex->world_panning) txdef.flags |= TX_WORLDPANNING; // Write texture definition SAFEFUNC(txdata.write(&txdef, 22)); break; } case TXF_NAMELESS: { // Create nameless texture definition nltdef_t txdef; txdef.flags = 0; txdef.scale[0] = (tex->getScaleX()*8); txdef.scale[1] = (tex->getScaleY()*8); txdef.width = tex->getWidth(); txdef.height = tex->getHeight(); txdef.columndir[0] = 0; txdef.columndir[1] = 0; txdef.patchcount = tex->nPatches(); // Write texture definition SAFEFUNC(txdata.write(&txdef, 8)); break; } case TXF_STRIFE11: { // Create strife format texture definition stdef_t txdef; memset(txdef.name, 0, 8); // Set texture name to all 0's (to ensure compatibility with XWE) strncpy(txdef.name, CHR(tex->getName().Upper()), tex->getName().Len()); txdef.flags = 0; txdef.scale[0] = (tex->getScaleX()*8); txdef.scale[1] = (tex->getScaleY()*8); txdef.width = tex->getWidth(); txdef.height = tex->getHeight(); txdef.patchcount = tex->nPatches(); // Check for WorldPanning flag if (tex->world_panning) txdef.flags |= TX_WORLDPANNING; // Write texture definition SAFEFUNC(txdata.write(&txdef, 18)); break; } default: return false; } // Write patch references for (size_t k = 0; k < tex->nPatches(); ++k) { // Get patch to write CTPatch* patch = tex->getPatch(k); // Create patch definition tx_patch_t pdef; pdef.left = patch->xOffset(); pdef.top = patch->yOffset(); // Check for 'invalid' patch if (patch->getName().StartsWith("INVPATCH")) { // Get raw patch index from name string number = patch->getName(); number.Replace("INVPATCH", ""); long index; number.ToLong(&index); pdef.patch = index; } else pdef.patch = patch_table.patchIndex(patch->getName()); // Note this will be -1 if the patch doesn't exist in the patch table. This should never happen with the texture editor, though. // Write common data SAFEFUNC(txdata.write(&pdef, 6)); // In non-Strife formats, there's some added rubbish if (txformat != TXF_STRIFE11) { foo = 0; SAFEFUNC(txdata.write(&foo, 4)); } } } // Write offsets SAFEFUNC(txdata.seek(4, SEEK_SET)); SAFEFUNC(txdata.write(offsets, 4*numtextures)); // Write data to the TEXTUREx entry texturex->importMemChunk(txdata); // Update entry type EntryType::detectEntryType(texturex); // Clean up delete[] offsets; return true; }
BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup) { // Test that passing CheckInputs with one set of script flags doesn't imply // that we would pass again with a different set of flags. { LOCK(cs_main); InitScriptExecutionCache(); } CScript p2pk_scriptPubKey = CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG; CScript p2sh_scriptPubKey = GetScriptForDestination(CScriptID(p2pk_scriptPubKey)); CScript p2pkh_scriptPubKey = GetScriptForDestination(coinbaseKey.GetPubKey().GetID()); CScript p2wpkh_scriptPubKey = GetScriptForWitness(p2pkh_scriptPubKey); CBasicKeyStore keystore; keystore.AddKey(coinbaseKey); keystore.AddCScript(p2pk_scriptPubKey); // flags to test: SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY, SCRIPT_VERIFY_CHECKSEQUENCE_VERIFY, SCRIPT_VERIFY_NULLDUMMY, uncompressed pubkey thing // Create 2 outputs that match the three scripts above, spending the first // coinbase tx. CMutableTransaction spend_tx; spend_tx.nVersion = 1; spend_tx.vin.resize(1); spend_tx.vin[0].prevout.hash = m_coinbase_txns[0]->GetHash(); spend_tx.vin[0].prevout.n = 0; spend_tx.vout.resize(4); spend_tx.vout[0].nValue = 11*CENT; spend_tx.vout[0].scriptPubKey = p2sh_scriptPubKey; spend_tx.vout[1].nValue = 11*CENT; spend_tx.vout[1].scriptPubKey = p2wpkh_scriptPubKey; spend_tx.vout[2].nValue = 11*CENT; spend_tx.vout[2].scriptPubKey = CScript() << OP_CHECKLOCKTIMEVERIFY << OP_DROP << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG; spend_tx.vout[3].nValue = 11*CENT; spend_tx.vout[3].scriptPubKey = CScript() << OP_CHECKSEQUENCEVERIFY << OP_DROP << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG; // Sign, with a non-DER signature { std::vector<unsigned char> vchSig; uint256 hash = SignatureHash(p2pk_scriptPubKey, spend_tx, 0, SIGHASH_ALL, 0, SigVersion::BASE); BOOST_CHECK(coinbaseKey.Sign(hash, vchSig)); vchSig.push_back((unsigned char) 0); // padding byte makes this non-DER vchSig.push_back((unsigned char)SIGHASH_ALL); spend_tx.vin[0].scriptSig << vchSig; } // Test that invalidity under a set of flags doesn't preclude validity // under other (eg consensus) flags. // spend_tx is invalid according to DERSIG { LOCK(cs_main); CValidationState state; PrecomputedTransactionData ptd_spend_tx(spend_tx); BOOST_CHECK(!CheckInputs(spend_tx, state, pcoinsTip.get(), true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_DERSIG, true, true, ptd_spend_tx, nullptr)); // If we call again asking for scriptchecks (as happens in // ConnectBlock), we should add a script check object for this -- we're // not caching invalidity (if that changes, delete this test case). std::vector<CScriptCheck> scriptchecks; BOOST_CHECK(CheckInputs(spend_tx, state, pcoinsTip.get(), true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_DERSIG, true, true, ptd_spend_tx, &scriptchecks)); BOOST_CHECK_EQUAL(scriptchecks.size(), 1U); // Test that CheckInputs returns true iff DERSIG-enforcing flags are // not present. Don't add these checks to the cache, so that we can // test later that block validation works fine in the absence of cached // successes. ValidateCheckInputsForAllFlags(spend_tx, SCRIPT_VERIFY_DERSIG | SCRIPT_VERIFY_LOW_S | SCRIPT_VERIFY_STRICTENC, false); } // And if we produce a block with this tx, it should be valid (DERSIG not // enabled yet), even though there's no cache entry. CBlock block; block = CreateAndProcessBlock({spend_tx}, p2pk_scriptPubKey); BOOST_CHECK(chainActive.Tip()->GetBlockHash() == block.GetHash()); BOOST_CHECK(pcoinsTip->GetBestBlock() == block.GetHash()); LOCK(cs_main); // Test P2SH: construct a transaction that is valid without P2SH, and // then test validity with P2SH. { CMutableTransaction invalid_under_p2sh_tx; invalid_under_p2sh_tx.nVersion = 1; invalid_under_p2sh_tx.vin.resize(1); invalid_under_p2sh_tx.vin[0].prevout.hash = spend_tx.GetHash(); invalid_under_p2sh_tx.vin[0].prevout.n = 0; invalid_under_p2sh_tx.vout.resize(1); invalid_under_p2sh_tx.vout[0].nValue = 11*CENT; invalid_under_p2sh_tx.vout[0].scriptPubKey = p2pk_scriptPubKey; std::vector<unsigned char> vchSig2(p2pk_scriptPubKey.begin(), p2pk_scriptPubKey.end()); invalid_under_p2sh_tx.vin[0].scriptSig << vchSig2; ValidateCheckInputsForAllFlags(invalid_under_p2sh_tx, SCRIPT_VERIFY_P2SH, true); } // Test CHECKLOCKTIMEVERIFY { CMutableTransaction invalid_with_cltv_tx; invalid_with_cltv_tx.nVersion = 1; invalid_with_cltv_tx.nLockTime = 100; invalid_with_cltv_tx.vin.resize(1); invalid_with_cltv_tx.vin[0].prevout.hash = spend_tx.GetHash(); invalid_with_cltv_tx.vin[0].prevout.n = 2; invalid_with_cltv_tx.vin[0].nSequence = 0; invalid_with_cltv_tx.vout.resize(1); invalid_with_cltv_tx.vout[0].nValue = 11*CENT; invalid_with_cltv_tx.vout[0].scriptPubKey = p2pk_scriptPubKey; // Sign std::vector<unsigned char> vchSig; uint256 hash = SignatureHash(spend_tx.vout[2].scriptPubKey, invalid_with_cltv_tx, 0, SIGHASH_ALL, 0, SigVersion::BASE); BOOST_CHECK(coinbaseKey.Sign(hash, vchSig)); vchSig.push_back((unsigned char)SIGHASH_ALL); invalid_with_cltv_tx.vin[0].scriptSig = CScript() << vchSig << 101; ValidateCheckInputsForAllFlags(invalid_with_cltv_tx, SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY, true); // Make it valid, and check again invalid_with_cltv_tx.vin[0].scriptSig = CScript() << vchSig << 100; CValidationState state; PrecomputedTransactionData txdata(invalid_with_cltv_tx); BOOST_CHECK(CheckInputs(invalid_with_cltv_tx, state, pcoinsTip.get(), true, SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY, true, true, txdata, nullptr)); } // TEST CHECKSEQUENCEVERIFY { CMutableTransaction invalid_with_csv_tx; invalid_with_csv_tx.nVersion = 2; invalid_with_csv_tx.vin.resize(1); invalid_with_csv_tx.vin[0].prevout.hash = spend_tx.GetHash(); invalid_with_csv_tx.vin[0].prevout.n = 3; invalid_with_csv_tx.vin[0].nSequence = 100; invalid_with_csv_tx.vout.resize(1); invalid_with_csv_tx.vout[0].nValue = 11*CENT; invalid_with_csv_tx.vout[0].scriptPubKey = p2pk_scriptPubKey; // Sign std::vector<unsigned char> vchSig; uint256 hash = SignatureHash(spend_tx.vout[3].scriptPubKey, invalid_with_csv_tx, 0, SIGHASH_ALL, 0, SigVersion::BASE); BOOST_CHECK(coinbaseKey.Sign(hash, vchSig)); vchSig.push_back((unsigned char)SIGHASH_ALL); invalid_with_csv_tx.vin[0].scriptSig = CScript() << vchSig << 101; ValidateCheckInputsForAllFlags(invalid_with_csv_tx, SCRIPT_VERIFY_CHECKSEQUENCEVERIFY, true); // Make it valid, and check again invalid_with_csv_tx.vin[0].scriptSig = CScript() << vchSig << 100; CValidationState state; PrecomputedTransactionData txdata(invalid_with_csv_tx); BOOST_CHECK(CheckInputs(invalid_with_csv_tx, state, pcoinsTip.get(), true, SCRIPT_VERIFY_CHECKSEQUENCEVERIFY, true, true, txdata, nullptr)); } // TODO: add tests for remaining script flags // Test that passing CheckInputs with a valid witness doesn't imply success // for the same tx with a different witness. { CMutableTransaction valid_with_witness_tx; valid_with_witness_tx.nVersion = 1; valid_with_witness_tx.vin.resize(1); valid_with_witness_tx.vin[0].prevout.hash = spend_tx.GetHash(); valid_with_witness_tx.vin[0].prevout.n = 1; valid_with_witness_tx.vout.resize(1); valid_with_witness_tx.vout[0].nValue = 11*CENT; valid_with_witness_tx.vout[0].scriptPubKey = p2pk_scriptPubKey; // Sign SignatureData sigdata; ProduceSignature(keystore, MutableTransactionSignatureCreator(&valid_with_witness_tx, 0, 11*CENT, SIGHASH_ALL), spend_tx.vout[1].scriptPubKey, sigdata); UpdateTransaction(valid_with_witness_tx, 0, sigdata); // This should be valid under all script flags. ValidateCheckInputsForAllFlags(valid_with_witness_tx, 0, true); // Remove the witness, and check that it is now invalid. valid_with_witness_tx.vin[0].scriptWitness.SetNull(); ValidateCheckInputsForAllFlags(valid_with_witness_tx, SCRIPT_VERIFY_WITNESS, true); } { // Test a transaction with multiple inputs. CMutableTransaction tx; tx.nVersion = 1; tx.vin.resize(2); tx.vin[0].prevout.hash = spend_tx.GetHash(); tx.vin[0].prevout.n = 0; tx.vin[1].prevout.hash = spend_tx.GetHash(); tx.vin[1].prevout.n = 1; tx.vout.resize(1); tx.vout[0].nValue = 22*CENT; tx.vout[0].scriptPubKey = p2pk_scriptPubKey; // Sign for (int i=0; i<2; ++i) { SignatureData sigdata; ProduceSignature(keystore, MutableTransactionSignatureCreator(&tx, i, 11*CENT, SIGHASH_ALL), spend_tx.vout[i].scriptPubKey, sigdata); UpdateTransaction(tx, i, sigdata); } // This should be valid under all script flags ValidateCheckInputsForAllFlags(tx, 0, true); // Check that if the second input is invalid, but the first input is // valid, the transaction is not cached. // Invalidate vin[1] tx.vin[1].scriptWitness.SetNull(); CValidationState state; PrecomputedTransactionData txdata(tx); // This transaction is now invalid under segwit, because of the second input. BOOST_CHECK(!CheckInputs(tx, state, pcoinsTip.get(), true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, true, true, txdata, nullptr)); std::vector<CScriptCheck> scriptchecks; // Make sure this transaction was not cached (ie because the first // input was valid) BOOST_CHECK(CheckInputs(tx, state, pcoinsTip.get(), true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, true, true, txdata, &scriptchecks)); // Should get 2 script checks back -- caching is on a whole-transaction basis. BOOST_CHECK_EQUAL(scriptchecks.size(), 2U); } }
void debughex32(u32 num) { txdata(0xfe, DEBUG_CMD_HEX32, 4, (xdata u8*)&num); }
void debughex16(u16 num) { txdata(0xfe, DEBUG_CMD_HEX16, 2, (xdata u8*)&num); }
void debughex(u8 num) { txdata(0xfe, DEBUG_CMD_HEX, 1, (xdata u8*)&num); }
//! Handles a monitor command. void spihandle(unsigned char app, unsigned char verb, unsigned char len){ unsigned char i; //Raise !SS to end transaction, just in case we forgot. P5OUT|=SS; switch(verb){ //PEEK and POKE might come later. case READ: case WRITE: P5OUT&=~SS; //Drop !SS to begin transaction. for(i=0;i<len;i++) cmddata[i]=spitrans8(cmddata[i]); P5OUT|=SS; //Raise !SS to end transaction. txdata(app,verb,len); break; case SPI_JEDEC://Grab 3-byte JEDEC ID. P5OUT&=~SS; //Drop !SS to begin transaction. spitrans8(0x9f); len=3; for(i=0;i<len;i++) cmddata[i]=spitrans8(cmddata[i]); txdata(app,verb,len); P5OUT|=SS; //Raise !SS to end transaction. break; case PEEK://Grab 128 bytes from an SPI Flash ROM spiflash_peek(app,verb,len); break; case POKE://Poke up bytes from an SPI Flash ROM. spiflash_setstatus(0x02); spiflash_wrten(); P5OUT&=~SS; //Drop !SS to begin transaction. spitrans8(0x02); //Poke command. //First three bytes are address, then data. for(i=0;i<len;i++) spitrans8(cmddata[i]); P5OUT|=SS; //Raise !SS to end transaction. while(spiflash_status()&0x01)//while busy P1OUT^=1; P1OUT&=~1; txdata(app,verb,len); break; case SPI_ERASE://Erase the SPI Flash ROM. spiflash_wrten(); P5OUT&=~SS; //Drop !SS to begin transaction. spitrans8(0xC7);//Chip Erase P5OUT|=SS; //Raise !SS to end transaction. while(spiflash_status()&0x01)//while busy P1OUT^=1; P1OUT&=~1; txdata(app,verb,0); break; case SETUP: spisetup(); txdata(app,verb,0); break; } }
//! Main loop. int main(void){ volatile unsigned int i; unsigned char app, verb; unsigned long len; // MSP reboot count for reset input & reboot function located at 0xFFFE volatile unsigned int reset_count = 0; silent=0; //Don't trust globals. #if (platform == tilaunchpad) int ret=0; //ret = setjmp(warmstart);// needs to be here since context from init() would be gone warmstart: if (ret == 0) { coldstart(); // basic hardware setup, clock to TUSB3410, and enable } else if (ret == 2) { dputs("\nalmost BSL only one RTS change\n"); } else if (ret > 2) { // reset released after more than two tst transisitions // We could write a BSL, a nice exercise for a Sunday afternoon. dputs("\nBSL\n"); //call_BSL(); // once you are done uncomment ;-) } else { // we come here after DTR high (release reset) dputs("\nWarmstart\n"); } #endif #if (platform == donbfet) extern void donbfet_reboot(void); void (*reboot_function)(void) = donbfet_reboot; #elif (platform == zigduino) extern void zigduino_reboot(void); void (*reboot_function)(void) = zigduino_reboot; #else void (*reboot_function)(void) = (void *) 0xFFFE; #endif init(); txstring(MONITOR,OK,"http://goodfet.sf.net/"); //txstring(0xab,0xcd,"http://goodfet.sf.net/"); //Command loop. There's no end! while(1){ //Magic 3 app = serial_rx(); // If the app is the reset byte (0x80) increment and loop if (app == RESET){ reset_count++; if (reset_count > 4){ // We could trigger the WDT with either: // WDTCTL = 0; // or // WDTCTL = WDTPW + WDTCNTCL + WDTSSEL + 0x00; // but instead we'll jump to our reboot function pointer (*reboot_function)(); debugstr("Rebooting not supported on this platform."); } continue; }else { reset_count = 0; } verb = serial_rx(); len = rxword(); //Read data, looking for buffer overflow. if(len <= CMDDATALEN){ for(i = 0; i < len; i++) cmddata[i] = serial_rx(); handle(app,verb,len); }else { //Listen to the blaberring. for(i = 0; i < len; i++) serial_rx(); //Reply with an error. debugstr("Buffer length exceeded."); txdata(MONITOR,NOK,0); } } }
//! Handles an i2c command. void i2c_handle_fn( uint8_t const app, uint8_t const verb, uint32_t const len) { unsigned char i; unsigned long l; switch(verb) { case READ: l = len; if(l > 0) //optional parameter of length l=cmddata[0]; if(!l) //default value of 1 l=1; I2C_Start(); for(i=0; i < l; i++) cmddata[i]=I2C_Read(i<l?1:0); I2C_Stop(); txdata(app,verb,l); break; case WRITE: I2C_Start(); cmddata[0] = cmddata[0] << 1; for(i=0; i<len; i++) { if (!I2C_Write(cmddata[i])) //if NACK break; } I2C_Stop(); cmddata[0] = i; txdata(app,verb,1); break; case PEEK: l = cmddata[0]; I2C_Start(); unsigned char address = cmddata[1] << 1; I2C_Write(address); for(i=2; i < len; i++){ I2C_Write(cmddata[i]); } I2C_Start(); I2C_Write(address|1); // spit out the target address again and flip the read bit I2CDELAY(1); // XXX We should wait for clock to go high here XXX for(i=0; i < l; i++) cmddata[i]=I2C_Read(i+1<l?1:0); // If the next i is still less than l, then ACK I2C_Stop(); txdata(app,verb,l); break; case POKE: break; case START: I2C_Start(); txdata(app,verb,0); break; case STOP: I2C_Stop(); txdata(app,verb,0); break; case SETUP: I2C_Init(); txdata(app,verb,0); break; } }
// ----------------------------------------------------------------------------- // Writes the texture list in TEXTUREX format to [texturex], using [patch_table] // for patch information. // Returns true on success, false otherwise // ----------------------------------------------------------------------------- bool TextureXList::writeTEXTUREXData(ArchiveEntry* texturex, const PatchTable& patch_table) { // Check entry was given if (!texturex) return false; if (texturex->isLocked()) return false; Log::info("Writing " + textureXFormatString() + " format TEXTUREx entry"); /* Total size of a TEXTUREx lump, in bytes: Header: 4 + (4 * numtextures) Textures: 22 * numtextures (normal format) 14 * numtextures (nameless format) 18 * numtextures (Strife 1.1 format) Patches: 10 * sum of patchcounts (normal and nameless formats) 6 * sum of patchcounts (Strife 1.1 format) */ size_t numpatchrefs = 0; size_t numtextures = textures_.size(); for (size_t i = 0; i < numtextures; ++i) { numpatchrefs += textures_[i]->nPatches(); } Log::info("{} patch references in {} textures", numpatchrefs, numtextures); size_t datasize = 0; size_t headersize = 4 + (4 * numtextures); switch (txformat_) { case Format::Normal: datasize = 4 + (26 * numtextures) + (10 * numpatchrefs); break; case Format::Nameless: datasize = 4 + (18 * numtextures) + (10 * numpatchrefs); break; case Format::Strife11: datasize = 4 + (22 * numtextures) + (6 * numpatchrefs); break; // Some compilers insist on having default cases. default: return false; } MemChunk txdata(datasize); vector<int32_t> offsets(numtextures); int32_t foo = wxINT32_SWAP_ON_BE((signed)numtextures); // Write header txdata.seek(0, SEEK_SET); SAFEFUNC(txdata.write(&foo, 4)); // Go to beginning of texture definitions SAFEFUNC(txdata.seek(4 + (numtextures * 4), SEEK_SET)); // Write texture entries for (size_t i = 0; i < numtextures; ++i) { // Get texture to write auto tex = textures_[i].get(); // Set offset offsets[i] = (signed)txdata.currentPos(); // Write texture entry switch (txformat_) { case Format::Normal: { // Create 'normal' doom format texture definition FullTexDef txdef; memset(txdef.name, 0, 8); // Set texture name to all 0's (to ensure compatibility with XWE) strncpy(txdef.name, tex->name().data(), tex->name().size()); for (auto& c : txdef.name) c = toupper(c); txdef.flags = 0; txdef.scale[0] = (tex->scaleX() * 8); txdef.scale[1] = (tex->scaleY() * 8); txdef.width = tex->width(); txdef.height = tex->height(); txdef.columndir[0] = 0; txdef.columndir[1] = 0; txdef.patchcount = tex->nPatches(); // Check for WorldPanning flag if (tex->world_panning_) txdef.flags |= Flags::WorldPanning; // Write texture definition SAFEFUNC(txdata.write(&txdef, 22)); break; } case Format::Nameless: { // Create nameless texture definition NamelessTexDef txdef; txdef.flags = 0; txdef.scale[0] = (tex->scaleX() * 8); txdef.scale[1] = (tex->scaleY() * 8); txdef.width = tex->width(); txdef.height = tex->height(); txdef.columndir[0] = 0; txdef.columndir[1] = 0; txdef.patchcount = tex->nPatches(); // Write texture definition SAFEFUNC(txdata.write(&txdef, 8)); break; } case Format::Strife11: { // Create strife format texture definition StrifeTexDef txdef; memset(txdef.name, 0, 8); // Set texture name to all 0's (to ensure compatibility with XWE) strncpy(txdef.name, tex->name().data(), tex->name().size()); for (auto& c : txdef.name) c = toupper(c); txdef.flags = 0; txdef.scale[0] = (tex->scaleX() * 8); txdef.scale[1] = (tex->scaleY() * 8); txdef.width = tex->width(); txdef.height = tex->height(); txdef.patchcount = tex->nPatches(); // Check for WorldPanning flag if (tex->world_panning_) txdef.flags |= Flags::WorldPanning; // Write texture definition SAFEFUNC(txdata.write(&txdef, 18)); break; } default: return false; } // Write patch references for (size_t k = 0; k < tex->nPatches(); ++k) { // Get patch to write auto patch = tex->patch(k); // Create patch definition Patch pdef; pdef.left = patch->xOffset(); pdef.top = patch->yOffset(); // Check for 'invalid' patch if (StrUtil::startsWith(patch->name(), "INVPATCH")) { // Get raw patch index from name std::string_view number = patch->name(); number.remove_prefix(8); pdef.patch = StrUtil::asInt(number); } else pdef.patch = patch_table.patchIndex( patch->name()); // Note this will be -1 if the patch doesn't exist in the patch table. This // should never happen with the texture editor, though. // Write common data SAFEFUNC(txdata.write(&pdef, 6)); // In non-Strife formats, there's some added rubbish if (txformat_ != Format::Strife11) { foo = 0; SAFEFUNC(txdata.write(&foo, 4)); } } } // Write offsets SAFEFUNC(txdata.seek(4, SEEK_SET)); SAFEFUNC(txdata.write(offsets.data(), 4 * numtextures)); // Write data to the TEXTUREx entry texturex->importMemChunk(txdata); // Update entry type EntryType::detectEntryType(texturex); return true; }