📄 deluge_app.c
字号:
app->outgoingCachePage = page; stateTransition(app, DELUGE_STATE_TX); #ifdef DELUGE_KEEP_STATS if (deluge_recordstats) packet_counts[DELUGE_STATS_COUNT-2][0]++; // cache hit #endif aqshell_send(AQSHELL_CACHEHIT, NULL, 0); } else { // No // Have we already partially recieved this page? if (request->page != app->dcb.incomingPage) { // No, abandon any partially cached page app->dcb.incomingPage = request->page; app->incomingPackets[0] = 0; app->incomingPackets[1] = 0; app->incomingPackets[2] = 0; app->nPacketsRequested = 0; app->cachedPackets[0] = 0; app->cachedPackets[1] = 0; app->cachedPackets[2] = 0; #ifdef DELUGE_KEEP_STATS if (deluge_recordstats) packet_counts[DELUGE_STATS_COUNT-2][1]++; // cache miss #endif aqshell_send(AQSHELL_CACHEMISS, NULL, 0); } else { #ifdef DELUGE_KEEP_STATS if (deluge_recordstats) packet_counts[DELUGE_STATS_COUNT-2][3]++; // cache hit past forward #endif aqshell_send(AQSHELL_CACHEHITOLDFORWARD, NULL, 0); } // Invalidate current cache entry at this location app->cache_map[app->incomingCachePage] = -1; app->outgoingCachePage = app->incomingCachePage; /*#ifdef DELUGE_SYMMETRIC_LINKS // Make sure the requester isn't in our list of potential parents uint8_t i; for (i=0; i<DELUGE_NEIGHBOR_COUNT; i++) if (request->id==app->neighbors[i]) app->symdtbs[i] = 255; // Find the node with a symmetric link and the best DTB if (nextSymmetric(app) != 255) { app->nRequests = 0; stateTransition(app, DELUGE_STATE_FORWARD); } #else*/ app->nRequests = 0; stateTransition(app, DELUGE_STATE_FORWARD); //#endif } #else // Is this the page we have cached? if (request->page != app->dcb.incomingPage) { char name[4] = { 'a', 'q', '0'+app->index, 0 }; // Open a new cache file for wear-balancing app->image_file = mos_file_create(name, (uint32_t)DELUGE_PAGE_SIZE); app->dcb.incomingPage = request->page; app->incomingPackets[0] = 0; app->incomingPackets[1] = 0; app->incomingPackets[2] = 0; app->nPacketsRequested = 0; app->cachedPackets[0] = 0; app->cachedPackets[1] = 0; app->cachedPackets[2] = 0; } /*#ifdef DELUGE_SYMMETRIC_LINKS // Make sure the requester isn't in our list of potential parents uint8_t i; for (i=0; i<DELUGE_NEIGHBOR_COUNT; i++) if (request->id==app->neighbors[i]) app->symdtbs[i] = 255; // Find the node with a symmetric link and the best DTB if (nextSymmetric(app) != 255) { app->nRequests = 0; stateTransition(app, DELUGE_STATE_FORWARD); } #else*/ app->nRequests = 0; stateTransition(app, DELUGE_STATE_FORWARD); //#endif #endif } #endif } else { // Rule M.5(i) app->heardRequest = 2; } } else { // start new round immediately stateTransition(app, DELUGE_STATE_MAINTAIN); } mos_mutex_unlock(&app->delugeLock); } break; case DELUGE_STATE_RX: { clearTimeout(app); setRequestTimeout(app, DELUGE_STATE_RX); } break; case DELUGE_STATE_TX: case DELUGE_STATE_FORWARD: { mos_mutex_lock(&app->delugeLock); if (request->version == app->dcb.version && request->page == app->outgoingPage && request->to == mos_node_id_get()) { // Rule T.1 uint8_t ih = mos_disable_ints(); app->outgoingPackets[0] |= request->packets[0]; app->outgoingPackets[1] |= request->packets[1]; app->outgoingPackets[2] |= request->packets[2]; mos_enable_ints(ih); #ifdef DELUGE_FORWARD_REQUESTS_IMMEDIATELY if (app->state == DELUGE_STATE_FORWARD) { // handle this request immediately stateTransition(app, DELUGE_STATE_FORWARD); #ifdef DELUGE_KEEP_STATS if (deluge_recordstats) packet_counts[DELUGE_STATS_COUNT-2][2]++; // cache hit forward #endif aqshell_send(AQSHELL_CACHEHITFORWARD, NULL, 0); } #endif /*DELUGE_FORWARD_REQUESTS_IMMEDIATELY*/ } else if (app->state == DELUGE_STATE_FORWARD) { clearTimeout(app); setRequestTimeout(app, DELUGE_STATE_FORWARD); } mos_mutex_unlock(&app->delugeLock); } break; } /*switch(app->state)*/}void handleData(deluge_app* app, deluge_foot_data* data, uint8_t* packet){ mos_mutex_lock(&app->delugeLock); checkNeighbor(app, data->id); mos_mutex_unlock(&app->delugeLock); uint8_t completedPage = 0; uint8_t completedPageCached = 0; mos_mutex_lock(&app->delugeLock); // Read data packets in any state if (data->version == app->dcb.version && data->page == app->dcb.incomingPage && (app->incomingPackets[data->packet/16] & (1<<(data->packet&15)))) { #ifdef DELUGE_NO_FORWARD int8_t page = app->dcb.incomingPage; #elif DELUGE_CACHE_PAGES > 1 int8_t page = (app->index == 0)? app->dcb.incomingPage : app->incomingCachePage; #else int8_t page = (app->index == 0)? app->dcb.incomingPage : 0; #endif uint32_t addr = (uint32_t)data->packet*DELUGE_PACKET_SIZE + (uint32_t)page*DELUGE_PAGE_SIZE; // Last two bytes of last packet have page CRC if (data->packet == DELUGE_PACKETS_PER_PAGE-1) { app->incomingcrc = *(uint16_t*)&(packet[DELUGE_PACKET_SIZE-2]); mos_file_write(packet, app->image_file, addr, DELUGE_PACKET_SIZE-2); dev_ioctl(DEV_AVR_EEPROM, DEV_LOCK); dev_ioctl (DEV_AVR_EEPROM, DEV_SEEK, DELUGE_PAGE_CRC_ADDR+(app->dcb.incomingPage*2)); dev_write(DEV_AVR_EEPROM, (uint8_t *)&(app->incomingcrc), 2); dev_ioctl(DEV_AVR_EEPROM, DEV_UNLOCK); } else { mos_file_write(packet, app->image_file, addr, DELUGE_PACKET_SIZE); } app->incomingPackets[data->packet/16] &= ~(1<<(data->packet&15)); app->cachedPackets[data->packet/16] |= (1<<(data->packet&15)); if (app->nPacketsRequested > 0) app->nPacketsRequested--; //deluge_saveState(app); if (app->incomingPackets[0] == 0 && app->incomingPackets[1] == 0 && app->incomingPackets[2] == 0) { if ( #ifndef DELUGE_NO_FORWARD app->index == 0 #else 1 #endif ) { page = app->dcb.incomingPage; addr = (uint32_t)page*DELUGE_PAGE_SIZE; uint32_t crc_len = (app->dcb.incomingPage == app->dcb.goalPage-1)? app->dcb.codeSize % (uint32_t)DELUGE_PAGE_SIZE : (uint32_t)DELUGE_PAGE_SIZE; uint16_t crc = mos_file_crc(app->image_file, addr, crc_len); if (app->incomingcrc == crc) { #ifdef DELUGE_PRINT_EVENT printf_P(sPageDone, app->dcb.incomingPage); printf_P(sDisplayTime); // display time #endif aqshell_send(AQSHELL_COMPLETEPAGE, (uint8_t*)data, 2); // version and page moveToNextPage(app); app->incomingPackets[0] = -1; app->incomingPackets[1] = -1; app->incomingPackets[2] = -1; app->nPacketsRequested = DELUGE_PACKETS_PER_PAGE; completedPage = 1; deluge_saveState(app); if (app->dcb.incomingPage == app->dcb.goalPage) { //dev_ioctl(DEV_ATMEL_FLASH, DEV_FLUSH); crc = mos_file_crc(app->image_file, (uint32_t)0, app->image_file->length); if (app->dcb.programcrc == crc) { #ifdef DELUGE_COMMANDER sendFinished(app, &spkt, deluge_portmap[app->index]); #endif aqshell_send(AQSHELL_COMPLETEPROG, NULL, 0); #ifndef DELUGE_NO_REPROGRAM #ifdef DELUGE_NO_FORWARD if (app->index == 0) #endif // doesn't return runReprogram(app); #endif } #ifdef DELUGE_NO_FORWARD else if (app->index != 0) { printf_P(sProgErr, crc, app->dcb.programcrc); // start over from the beginning app->dcb.highPage = 0; app->dcb.incomingPage = 0; app->incomingPackets[0] = -1; app->incomingPackets[1] = -1; app->incomingPackets[2] = -1; app->nPacketsRequested = DELUGE_PACKETS_PER_PAGE; uint8_t i; for (i=0; i<sizeof(app->dcb.pagesNeeded); i++) app->dcb.pagesNeeded[i] = 0xFF; deluge_saveState(app); } #endif else { printf_P(sProgErr, crc, app->dcb.programcrc); // start over from the first page that fails its CRC findBadPages(app); app->incomingPackets[0] = -1; app->incomingPackets[1] = -1; app->incomingPackets[2] = -1; app->nPacketsRequested = DELUGE_PACKETS_PER_PAGE; deluge_saveState(app); } } } else { printf_P(sPageErr, crc, app->incomingcrc); // start over app->incomingPackets[0] = -1; app->incomingPackets[1] = -1; app->incomingPackets[2] = -1; app->nPacketsRequested = DELUGE_PACKETS_PER_PAGE; } } #ifndef DELUGE_NO_FORWARD else if (app->index != 0) { completedPage = 1; #if DELUGE_CACHE_PAGES > 1 // If we happened to have downloaded a whole page if (app->cachedPackets[0] == -1 && app->cachedPackets[1] == -1 && app->cachedPackets[2] == -1) { #if DELUGE_CACHE_PAGES > 1 page = (app->index == 0)? app->dcb.incomingPage : app->incomingCachePage; #else page = (app->index == 0)? app->dcb.incomingPage : 0; #endif addr = (uint32_t)page*DELUGE_PAGE_SIZE; uint32_t crc_len = (app->dcb.incomingPage == app->dcb.goalPage-1)? app->dcb.codeSize % (uint32_t)DELUGE_PAGE_SIZE : (uint32_t)DELUGE_PAGE_SIZE; uint16_t crc = mos_file_crc(app->image_file, addr, crc_len); if (app->incomingcrc == crc) { #ifdef DELUGE_PRINT_EVENT printf_P(sPageDone, app->dcb.incomingPage); printf_P(sDisplayTime); // display time #endif saveIncomingCachePage(app, app->dcb.incomingPage); completedPageCached = 1; } else { printf_P(sPageErr, crc, app->incomingcrc); // assume all cached packets are bad app->cachedPackets[0] = 0; app->cachedPackets[1] = 0; app->cachedPackets[2] = 0; } } #endif deluge_saveState(app); } #endif } } mos_mutex_unlock(&app->delugeLock); switch (app->state) { case DELUGE_STATE_MAINTAIN: case DELUGE_STATE_MAINTAIN2: { mos_mutex_lock(&app->delugeLock); app->detectedInconsistency = 1; if (data->version == app->dcb.version && data->page <= app->dcb.highPage) { // Rule M.5(ii) app->heardData = 1; } // start new round immediately stateTransition(app, DELUGE_STATE_MAINTAIN); mos_mutex_unlock(&app->delugeLock); } break; case DELUGE_STATE_RX: { if (completedPage) { // Rule R.3 // start new round immediately stateTransition(app, DELUGE_STATE_MAINTAIN); } else { clearTimeout(app); setRequestTimeout(app, DELUGE_STATE_RX); } } break; case DELUGE_STATE_TX: break; case DELUGE_STATE_FORWARD: { clearTimeout(app); if (completedPage) { // finish filling forwarded request #if DELUGE_CACHE_PAGES > 1 if (completedPageCached) { // outgoingCachePage is already set stateTransition(app, DELUGE_STATE_TX); } else #endif stateTransition(app, DELUGE_STATE_FORWARD); } else { #ifdef DELUGE_FORWARD_DATA_IMMEDIATELY stateTransition(app, DELUGE_STATE_FORWARD); #else setRequestTimeout(app, DELUGE_STATE_FORWARD); #endif /* DELUGE_FORWARD_DATA_IMMEDIATELY */ } } break; }}/* Public interface functions: */int8_t deluge_app_staticinit(){ srandom(mos_node_id_get()); return 0;}int8_t deluge_app_init(deluge_app* app, int8_t index){ mos_mutex_init(&app->delugeLock); app->index = index; table[index].app = app; loadState(app); if (app->index == 0) { app->image_file = mos_file_open("prg"); app->incomingPackets[0] = -1; app->incomingPackets[1] = -1; app->incomingPackets[2] = -1; app->nPacketsRequested = DELUGE_PACKETS_PER_PAGE; } else { char name[4] = { 'a', 'q', '0'+app->index, 0 }; #ifdef DELUGE_NO_FORWARD app->image_file = mos_file_create(name, (uint32_t)0); app->incomingPackets[0] = -1; app->incomingPackets[1] = -1; app->incomingPackets[2] = -1; app->nPacketsRequested = DELUGE_PACKETS_PER_PAGE; #else app->image_file = mos_file_create(name, (uint32_t)DELUGE_PAGE_SIZE*(uint32_t)DELUGE_CACHE_PAGES); app->incomingPackets[0] = 0; app->incomingPackets[1] = 0; app->incomingPackets[2] = 0; app->nPacketsRequested = 0; #endif #if DELUGE_CACHE_PAGES > 1 int8_t i; for (i=0; i<DELUGE_CACHE_PAGES; i++) app->cache_map[i] = -1; app->outgoingCachePage = 0; app->incomingCachePage = 0; app->cacheSize = 4; #endif app->cachedPackets[0] = 0; app->cachedPackets[1] = 0; app->cachedPackets[2] = 0; } app->detectedInconsistency = 0; app->heardObsolete = 0; app->heardRequest = 0; app->heardData = 0; app->outgoingPackets[0] = 0; app->outgoingPackets[1] = 0; app->outgoingPackets[2] = 0; app->nRequests = 0; //table[app->index].roundT = DELUGE_T_L; app->txDelay = 0; #ifdef DELUGE_SYMMETRIC_LINKS uint8_t i; for (i = 0; i<DELUGE_NEIGHBOR_COUNT; i++) { app->neighbors[i] = 0xFFFF; //app->symdtbs[i] = 0xFF; } app->nextNeighbor = 0; #endif if (app->index == 0 && app->dcb.highPage == app->dcb.goalPage) { app->dtb = 0; } else { app->dtb = 0xFF; } stateTransition(app, DELUGE_STATE_MAINTAIN); return 0;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -