int nrf_rcv_pkt_poll_dec(int maxsize, uint8_t * pkt, uint32_t const key[4]){ int len; uint16_t cmpcrc; len=nrf_rcv_pkt_poll(maxsize,pkt); if(len <=0) return len; // if(key==NULL) return len; cmpcrc=crc16(pkt,len-2); if(key!=NULL) xxtea_decode_words((uint32_t*)pkt,len/4,key); cmpcrc=crc16(pkt,len-2); if(cmpcrc != (pkt[len-2] <<8 | pkt[len-1])) { return -3; // CRC failed }; return len; };
uint8_t execute_file (const char * fname){ FRESULT res; FIL file; UINT readbytes; void (*dst)(void); /* XXX: why doesn't this work? sram_top contains garbage? dst=(void (*)(void)) (sram_top); lcdPrint("T:"); lcdPrintIntHex(dst); lcdNl(); */ dst=(void (*)(void)) (0x10002000 - RAMCODE); res=f_open(&file, fname, FA_OPEN_EXISTING|FA_READ); //lcdPrint("open: "); //lcdPrintln(f_get_rc_string(res)); //lcdRefresh(); if(res){ return -1; }; res = f_read(&file, (char *)dst, RAMCODE, &readbytes); //lcdPrint("read: "); //lcdPrintln(f_get_rc_string(res)); //lcdRefresh(); if(res){ return -1; }; #ifdef ENCRYPT_L0DABLE uint32_t *data; uint32_t len; uint32_t mac[4]; data = (uint32_t*)dst; len = readbytes/4; if( readbytes & 0xF || readbytes <= 0x10){ lcdClear(); lcdPrint("!size"); lcdRefresh(); getInputWait(); getInputWaitRelease(); return -1; } xxtea_cbcmac(mac, (uint32_t*)dst, len-4, l0dable_sign_key); if( data[len-4] != mac[0] || data[len-3] != mac[1] || data[len-2] != mac[2] || data[len-1] != mac[3] ){ lcdClear(); lcdPrint("!mac"); //lcdPrintIntHex(mac[0]); lcdNl(); //lcdPrintIntHex(mac[1]); lcdNl(); //lcdPrintIntHex(mac[2]); lcdNl(); //lcdPrintIntHex(mac[3]); lcdNl(); lcdRefresh(); getInputWait(); getInputWaitRelease(); return -1; } data = (uint32_t*)dst; len = readbytes/4; xxtea_decode_words(data, len-4, l0dable_crypt_key); #endif dst=(void (*)(void)) ((uint32_t)(dst) | 1); // Enable Thumb mode! dst(); return 0; };
// High-Level: int nrf_rcv_pkt_time_encr(int maxtime, int maxsize, uint8_t * pkt, uint32_t const key[4]){ uint8_t len; uint8_t status=0; uint16_t cmpcrc; nrf_write_reg(R_CONFIG, R_CONFIG_PRIM_RX| // Receive mode R_CONFIG_PWR_UP| // Power on R_CONFIG_EN_CRC // CRC on, single byte ); nrf_cmd(C_FLUSH_RX); nrf_write_reg(R_STATUS,0); CE_HIGH(); for(int i=0;i<maxsize;i++) pkt[i] = 0x00; // Sanity: clear packet buffer #define LOOPY 10 for (;maxtime >= LOOPY;maxtime-=LOOPY){ delayms(LOOPY); status =nrf_cmd_status(C_NOP); if( (status & R_STATUS_RX_DR) == R_STATUS_RX_DR){ if( (status & R_STATUS_RX_P_NO) == R_STATUS_RX_FIFO_EMPTY){ nrf_cmd(C_FLUSH_RX); delayms(1); nrf_write_reg(R_STATUS,0); continue; }else{ // Get/Check packet... nrf_read_long(C_R_RX_PL_WID,1,&len); if(len>32 || len==0){ continue; return -2; // no packet error }; if(len>maxsize){ continue; return -1; // packet too large }; nrf_read_pkt(len,pkt); if(key != NULL) xxtea_decode_words((uint32_t*)pkt,len/4,key); cmpcrc=crc16(pkt,len-2); if(cmpcrc != (pkt[len-2] <<8 | pkt[len-1])) { continue; return -3; // CRC failed }; break; }; }; }; CE_LOW(); CS_HIGH(); if(maxtime<LOOPY) return 0; // timeout return len; };