/* * Network bootloader library * Could be / is being extended to handle more network based commands * Uses wiz5500 library */ // uses wiz5500.c // Port for network bootloader #define NETLOADER_PORT 3220 // Socket to listen to (0-7) #define NETLOADER_SOCKET 0 // Checks if p starts with cmd // Returns 1 if true, 0 otherwise word NETLOADER_frameCompare(char* p, char* cmd) { word i = 0; while (cmd[i] != 0) { if (cmd[i] != p[i]) { return 0; } i++; } return 1; } word NETLOADER_wordPosition = 0; word NETLOADER_currentByteShift = 24; // Appends bytes from buffer to words in run address void NETLOADER_appendBufferToRunAddress(char* b, word len) { char* dst = (char*) RUN_ADDR; word i; for (i = 0; i < len; i++) { char readByte = b[i]; // Read 4 bytes into one word, from left to right readByte = readByte << NETLOADER_currentByteShift; dst[NETLOADER_wordPosition] = dst[NETLOADER_wordPosition] + readByte; if (NETLOADER_currentByteShift == 0) { NETLOADER_currentByteShift = 24; NETLOADER_wordPosition++; dst[NETLOADER_wordPosition] = 0; } else { NETLOADER_currentByteShift -= 8; } } } word NETLOADER_getContentLength(char* rbuf, word rsize) { word contentLengthStr[32]; word i = 5; // content length always at 5 char c = rbuf[i]; while (i < rsize && c != ':') { contentLengthStr[i-5] = c; i++; c = rbuf[i]; } contentLengthStr[i-5] = 0; // terminate return strToInt(contentLengthStr); } void NETLOADER_getFileName(char* rbuf, word rsize, char* fileNameStr) { word i = 0; char c = rbuf[i]; while (i < rsize && c != ':') { i++; c = rbuf[i]; } i++; // skip the : word x = 0; c = rbuf[i]; while (i 0) { GFX_PrintcConsole(0x8); // backspace i--; } if (strlen(dbuf) != 0) { GFX_PrintcConsole(0x8); // backspace } itoa(NETLOADER_percentageDone(contentLength, contentLengthOrig), dbuf); GFX_PrintConsole(dbuf); GFX_PrintcConsole('%'); contentLength -= rsize; if (downloadToFile) { FS_writeFile(rbuf, rsize); } else { NETLOADER_appendBufferToRunAddress(rbuf, rsize); } // all data downloaded if (contentLength == 0) { wizWriteDataFromMemory(s, "THX!", 4); wizCmd(s, WIZNET_CR_DISCON); // remove progress prints word i = strlen(dbuf); while (i > 0) { GFX_PrintcConsole(0x8); // backspace i--; } GFX_PrintcConsole(0x8); // backspace if (downloadToFile) { FS_close(); // clear the shell SHELL_clearCommand(); SHELL_print_prompt(); } else { NETLOADER_runProgramFromMemory(); } return; } } } } } // Initialize network bootloader on socket s void NETLOADER_init(word s) { // Open socket in TCP Server mode wizInitSocketTCP(s, NETLOADER_PORT); } // Check for a change in the socket status // Handles change if exists word NETLOADER_loop(word s) { // Get status for socket s word sxStatus = wizGetSockReg8(s, WIZNET_SnSR); if (sxStatus == WIZNET_SOCK_CLOSED) { // Open the socket when closed wizInitSocketTCP(s, NETLOADER_PORT); } else if (sxStatus == WIZNET_SOCK_ESTABLISHED) { // Handle session when a connection is established NETLOADER_handleSession(s); } else if (sxStatus == WIZNET_SOCK_LISTEN) { // Keep on listening return 1; } else if (sxStatus == WIZNET_SOCK_SYNSENT || sxStatus == WIZNET_SOCK_SYNRECV || sxStatus == WIZNET_SOCK_FIN_WAIT || sxStatus == WIZNET_SOCK_TIME_WAIT) { // Do nothing in these cases return 2; } else { // In other cases, reset the socket wizInitSocketTCP(s, NETLOADER_PORT); } return 0; }