/**************************************************************************//** * \brief Write a single sector to the flash card * * Attempt to write a full sector (including computed checksum) * * Provides a clean read wrapper separating the rest of the codebase from * the MMC library. * * \param sectorNum The sector number to read in (0 to 4194303 * for a 2GB MMC card with 512B sector sizes). * \param[in,out] sector Pointer to sector to write. Will have a newly * computed checksum written into it. Most * likely you will be casting a more specific * sector type or a simple array to this * interface * \retval 0 success * \retval -1 failure (MMC library returned an error) * \see secureFlashWrite() for more thorough write validation *****************************************************************************/ int flashWrite(unsigned long sectorNum, struct Sector *sector) { sector->checksum = fletcherChecksum(sector->data, SECTOR_CRC_SIZE, 0); if(mmcWriteSector(sectorNum, (unsigned char *) sector) == MMC_SUCCESS) { return FLASH_SUCCESS; } else { return FLASH_FAIL; } }
/**************************************************************************//** * \brief Write a sector and read it back to verify correctness * * Write a sector and, if successful, read it back to verify that it passes * a checksum check and has the same checksum as before After #WRITE_RETRIES * failed write-verify attempts exit * * \param sectorNum The sector number to read in (0 to 4194303 * for a 2GB MMC card with 512B sector sizes). * \param[in,out] sector Pointer to sector to write. Will have a newly * computed checksum written into it. Most * likely you will be casting a more specific * sector type or a simple array to this * interface * \retval 0 success * \retval -1 failure *****************************************************************************/ int secureFlashWrite(unsigned long sectorNum, struct Sector *sector){ int postChecksum = 0; struct Sector tmpSector; int i = 0; sector->checksum = fletcherChecksum(sector->data, SECTOR_CRC_SIZE, 0); for( i = 0; i < WRITE_RETRIES; i++) { if(mmcWriteSector(sectorNum, (unsigned char *) sector)==MMC_SUCCESS) { mmcReadSector(sectorNum, (unsigned char *) &tmpSector); postChecksum = fletcherChecksum(tmpSector.data, SECTOR_CRC_SIZE, 0); if(tmpSector.checksum == postChecksum && // Read-back data passes checksum sector->checksum == postChecksum) { // && Read-back matches original return FLASH_SUCCESS; } } } // If checksums do not agree and we have tried multiple times, then.. return FLASH_TIMEOUT; // Return failure }
/**************************************************************************//** * \brief Read a sector and verify the checksum * * Read a sector and, if successful, verify its checksum as well. After * #READ_RETRIES failed read-verify attempts exit * * \param sectorNum The sector number to read in (0 to 4194303 for a * 2GB MMC card with 512B sector sizes). * \param[out] sector Pointer to a sector structure to fill. Most * likely you will be casting a more specific sector * type or a simple array to this interface * \retval 0 success * \retval -1 failure *****************************************************************************/ int secureFlashRead(unsigned long sectorNum, struct Sector *sector){ int calcChecksum = 0; int i = 0; for( i = 0; i < READ_RETRIES; i++) // Attempt to read the card multiple times { if(flashRead(sectorNum, sector) == 0) { calcChecksum = fletcherChecksum(sector->data, SECTOR_CRC_SIZE, 0); if(sector->checksum == calcChecksum){ return FLASH_SUCCESS; } } } if(i >= READ_RETRIES) return FLASH_TIMEOUT; // If checksums do not agree return fail return FLASH_SUCCESS; }
int main() { if (initSockets() != 0) { fprintf(stderr, "cannot initialize sockets\n"); exit(EXIT_FAILURE); } SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0); if (!isSocketValid(sock)) { fprintf(stderr, "cannot create socket\n"); quitSockets(); exit(EXIT_FAILURE); } int opt = 1; setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&opt, sizeof(opt)); struct sockaddr_in socketInfo; socketInfo.sin_family = AF_INET; socketInfo.sin_addr.s_addr = INADDR_ANY; socketInfo.sin_port = htons(PORT); if (bind(sock, (const struct sockaddr*) &socketInfo, sizeof(socketInfo)) == -1) { fprintf(stderr, "cannot bind socket\n"); closeSocket(sock); quitSockets(); exit(EXIT_FAILURE); } if (setTimeout(sock, TIME_OUT) != 0) { fprintf(stderr, "cannot set socket timeout\n"); closeSocket(sock); quitSockets(); exit(EXIT_FAILURE); } int count = 0; int corruptCount = 0; int outOfOrderCount = 0; char buf[MAX_BLOCK_SIZE]; double recvStart = 0; int prevPacketNum = -1; while(1){ int result = recvfrom(sock, buf, MAX_BLOCK_SIZE, 0, NULL, NULL); if (result == -1) { //timed out if (count > 0) { double seconds = (getSeconds() - recvStart) - TIME_OUT; if (seconds < 0) { seconds = 0; } recvStart = 0; printf("blocks received: %d\n", count); printf("corrupted: %d\n", corruptCount); printf("out of order: %d\n", outOfOrderCount); printf("time to send (seconds): %f\n", seconds); count = 0; corruptCount = 0; outOfOrderCount = 0; prevPacketNum = -1; } } else { if (recvStart == 0) { recvStart = getSeconds(); } unsigned short checksum; memcpy(&checksum, buf, sizeof(short)); if (checksum == fletcherChecksum(buf+sizeof(short), result-sizeof(short))){ int packetNum; memcpy(&packetNum, buf + sizeof(short), sizeof(int)); if (packetNum != prevPacketNum+1) { outOfOrderCount++; } prevPacketNum = packetNum; } else { corruptCount++; } count++; } } closeSocket(sock); quitSockets(); exit(EXIT_SUCCESS); }