mvirus.nc
来自「tinyos最新版」· NC 代码 · 共 644 行 · 第 1/2 页
NC
644 行
size += (MVIRUS_CHUNK_SIZE - 1); size /= MVIRUS_CHUNK_SIZE; for (idx = 0; idx < size; idx++) { if (bitEntry(needBitmask, idx)) { count++; } } if (count == 0) { dbg(DBG_USR3, "MVirus: Tried to select capsule chunk to send, but none were needed. Returning -1.\n"); return -1; } count = (call Random.rand() % count) + 1; for (idx = 0; idx < size; idx++) { if (bitEntry(needBitmask, idx)) { count--; } if (count == 0) { dbg(DBG_USR3, "MVirus: Select capsule chunk %i to send.\n", (int)idx); return (int8_t)idx; } } dbg(DBG_USR3, "MVirus: Tried to select capsule chunk to send, but encountered an error due to miscount. Returning -1.\n"); return -1; } void sendCapsulePacket() { if (sendBusy) { dbg(DBG_USR3, "MVirus: Tried to send capsule, but send busy.\n"); return; } else { int8_t idx = getRandomChunkIndex(currentCapsule); if (idx >= 0) { MateCapsuleChunkMsg* chunk = (MateCapsuleChunkMsg*)sendPtr->data; uint8_t* chunkPtr = (uint8_t*)capsules[currentCapsule]; chunkPtr += MVIRUS_CHUNK_SIZE * idx; memcpy(chunk->chunk, chunkPtr, MVIRUS_CHUNK_SIZE); chunk->capsuleNum = currentCapsule; chunk->piece = idx; chunk->version = capsules[currentCapsule]->version; if (call CapsuleChunkSend.send(TOS_BCAST_ADDR, sizeof(MateCapsuleChunkMsg), sendPtr) == SUCCESS) { dbg(DBG_USR3, "MVirus: Sent chunk %i of capsule %i.%i.\n", (int)idx, (int)currentCapsule, (int)currentVersion); sendBusy = TRUE; removeNeededBit(idx); } else { dbg(DBG_USR3, "MVirus: Sending chunk %i of capsule %i.%i FAILED.\n", (int)idx, (int)currentCapsule, (int)currentVersion); } } else { dbg(DBG_USR3, "MVirus: Tried to send capsule, but nothing to send. Return to maintain state.\n"); toMaintainState(); } } } void sendVersionPacket() { if (sendBusy) {return;} if (state == MVIRUS_MAINTAIN || state == MVIRUS_RESPOND) { int i; MateVersionMsg* versionMsg = (MateVersionMsg*)sendPtr->data; for (i = 0; i < MATE_CAPSULE_NUM; i++) { versionMsg->versions[i] = capsules[i]->version; } dbg(DBG_USR3, "MVirus: In state %i, sending version vector.\n", (int)state); if (call VersionSend.send(TOS_BCAST_ADDR, sizeof(MateVersionMsg), sendPtr) == SUCCESS) { sendBusy = TRUE; } } else if (state == MVIRUS_REQUEST) { MateCapsuleStatusMsg* statusMsg = (MateCapsuleStatusMsg*)sendPtr->data; statusMsg->capsuleNum = currentCapsule; statusMsg->version = currentVersion; memcpy(statusMsg->bitmask, needBitmask, MVIRUS_BITMASK_SIZE); dbg(DBG_USR3, "MVirus: In state %i, sending bitmask:\n", (int)state); printNeedBitmask(); if (call CapsuleStatusSend.send(TOS_BCAST_ADDR, sizeof(MateCapsuleStatusMsg), sendPtr) == SUCCESS) { sendBusy = TRUE; } } else { dbg(DBG_USR3|DBG_ERROR, "MVirus: In invalid state for sending version packet: %i\n", (int)state); return; } } TOS_MsgPtr receiveVector(TOS_MsgPtr msg) { uint8_t capsuleNum; int8_t comparison = 0; // msg is: -1 older, 0 same, 1 newer MateVersionMsg* versions = (MateVersionMsg*)msg->data; if (state == MVIRUS_REQUEST) { return msg; } for (capsuleNum = 0; capsuleNum < MATE_CAPSULE_NUM; capsuleNum++) { if (capsules[capsuleNum] != NULL) { if(versions->versions[capsuleNum] > capsules[capsuleNum]->version) { comparison = 1; break; } else if (versions->versions[capsuleNum] < capsules[capsuleNum]->version) { comparison = -1; break; } } } // Requests are given precedence over responses: there's no // point updating someone to something that's out of date. if (comparison == 0) { versionTimer.numHeard++; } else if (comparison == 1) { if (state != MVIRUS_REQUEST) { memset(needBitmask, 0xff, MVIRUS_BITMASK_SIZE); toRequestState(capsuleNum, versions->versions[capsuleNum]); } } else if (comparison == -1) { if (state == MVIRUS_MAINTAIN) { memset(needBitmask, 0xff, MVIRUS_BITMASK_SIZE); toResponseState(capsuleNum); } } return msg; } task void checkNeedTask() { uint8_t i; for (i = 0; i < MVIRUS_BITMASK_SIZE; i++) { if (needBitmask[i] != 0) { return; } } dbg(DBG_USR3|DBG_TEMP, "MVirus: all chunks for %i.%i received, move to maintain state @%s.\n", (int)currentCapsule, (int)currentVersion, currentTime()); signal Virus.capsuleInstalled(capsules[currentCapsule]); toMaintainState(); } void installChunk(MateCapsuleChunkMsg* chunk) { uint8_t* destPtr = (uint8_t*)capsules[chunk->capsuleNum]; destPtr += chunk->piece * MVIRUS_CHUNK_SIZE; dbg(DBG_USR3, "MVirus: Copying chunk %i of capsule %i version %i.\n", chunk->piece, chunk->capsuleNum, chunk->version); memcpy(destPtr, chunk->chunk, MVIRUS_CHUNK_SIZE); // Remove that bit entry if (chunk->piece == 0) { // If it's the chunk metadata, clear out bits clearInvalidBits(); } removeNeededBit(chunk->piece); printNeedBitmask(); post checkNeedTask(); } void chunkReceive(MateCapsuleChunkMsg* chunk) { capsuleTimer.numHeard++; dbg(DBG_USR3, "MVirus: Received chunk %i of capsule %i.%i @%s.\n", (int)chunk->piece, (int)chunk->capsuleNum, (int)chunk->version, currentTime()); if (state == MVIRUS_REQUEST) { if (chunk->capsuleNum == currentCapsule && chunk->version == currentVersion && bitEntry(needBitmask, chunk->piece)) { installChunk(chunk); versionTimer.interval = MVIRUS_VERSION_TAU_MIN; newCounter(&versionTimer); } else if (chunk->capsuleNum == currentCapsule && chunk->version > currentVersion) { toRequestState(chunk->capsuleNum, chunk->version); installChunk(chunk); versionTimer.interval = MVIRUS_VERSION_TAU_MIN; newCounter(&versionTimer); } } else if (state == MVIRUS_MAINTAIN) { if (chunk->version > capsules[chunk->capsuleNum]->version) { toRequestState(chunk->capsuleNum, chunk->version); installChunk(chunk); versionTimer.interval = MVIRUS_VERSION_TAU_MIN; newCounter(&versionTimer); } } } event TOS_MsgPtr CapsuleChunkReceive.receive(TOS_MsgPtr msg) { MateCapsuleChunkMsg* chunk = (MateCapsuleChunkMsg*)msg->data; dbg(DBG_USR3|DBG_TEMP, "MVirus: Received chunk broadcast.\n"); chunkReceive(chunk); return msg; } event TOS_MsgPtr CapsuleChunkRouteReceive.receive(TOS_MsgPtr msg, void* payload, uint16_t payloadLen) { if (payloadLen == sizeof(MateCapsuleChunkMsg)) { MateCapsuleChunkMsg* chunk = (MateCapsuleChunkMsg*)payload; dbg(DBG_USR3|DBG_TEMP, "MVirus: Received routed chunk.\n"); chunkReceive(chunk); } else { dbg(DBG_USR3|DBG_TEMP, "MVirus: Intercepted routed chunk of improper size (%i not %i).\n", payloadLen, sizeof(MateCapsuleChunkMsg)); } return msg; } event result_t CapsuleChunkRouteIntercept.intercept(TOS_MsgPtr msg, void* payload, uint16_t payloadLen) { if (payloadLen == sizeof(MateCapsuleChunkMsg)) { MateCapsuleChunkMsg* chunk = (MateCapsuleChunkMsg*)payload; if (msg->addr == TOS_LOCAL_ADDRESS) { dbg(DBG_USR3|DBG_TEMP, "MVirus: Intercepted routed chunk.\n"); } else { dbg(DBG_USR3|DBG_TEMP, "MVirus: Snooped routed chunk for %i.\n", (int)msg->addr); } chunkReceive(chunk); } else { dbg(DBG_USR3|DBG_TEMP, "MVirus: Intercepted routed chunk of improper size (%i not %i).\n", payloadLen, sizeof(MateCapsuleChunkMsg)); } return SUCCESS; } event TOS_MsgPtr CapsuleStatusReceive.receive(TOS_MsgPtr msg) { MateCapsuleStatusMsg* statusMsg = (MateCapsuleStatusMsg*)msg->data; b_capsule_version version = statusMsg->version; uint8_t which = statusMsg->capsuleNum; dbg(DBG_USR3, "MVirus: Received status message for %i.%i @%s\n", (int)which, (int)version, currentTime()); // If I'm requesting this capsule already... if ((state == MVIRUS_REQUEST) && (currentCapsule == which)) { // and this version, increment my counter. if (currentVersion == version) { versionTimer.numHeard++; } // and an older version, request the new version. else if (currentVersion < version) { toRequestState(which, version); } } // If I'm idle or responding, and need this capsule, // start requesting it. else if (((state == MVIRUS_MAINTAIN) || (state == MVIRUS_RESPOND)) && (capsules[which]->version < version)) { toRequestState(which, version); } // If I'm idle and have this capsule, respond with parts of it. else if (state == MVIRUS_MAINTAIN && (capsules[which]->version == version)) { memcpy(needBitmask, statusMsg->bitmask, MVIRUS_BITMASK_SIZE); toResponseState(which); } // If I'm responding, then add these to the parts I know are needed. if ((state == MVIRUS_RESPOND) && (currentCapsule == which) && (currentCapsule == version)) { int i; for (i = 0; i < MVIRUS_BITMASK_SIZE; i++) { needBitmask[i] |= statusMsg->bitmask[i]; } } return msg; } event TOS_MsgPtr VersionReceive.receive(TOS_MsgPtr msg) { dbg(DBG_USR3, "MVirus: Received version vector @%s.\n", currentTime()); return receiveVector(msg); } event result_t CapsuleStatusSend.sendDone(TOS_MsgPtr msg, result_t success) { if (msg == sendPtr) { sendBusy = FALSE; dbg(DBG_USR3, "MVirus: CapsuleStatus send done event handled @%s.\n", currentTime()); } return SUCCESS; } event result_t CapsuleChunkSend.sendDone(TOS_MsgPtr msg, result_t success) { if (msg == sendPtr) { sendBusy = FALSE; dbg(DBG_USR3, "MVirus: CapsuleChunk send done event handled @%s.\n", currentTime()); } return SUCCESS; } event result_t VersionSend.sendDone(TOS_MsgPtr msg, result_t success) { if (msg == sendPtr) { sendBusy = FALSE; dbg(DBG_USR3, "MVirus: Version send done event handled @%s.\n", currentTime()); } return SUCCESS; } event result_t VersionTimer.fired() { post versionTimerTask(); return SUCCESS; } event result_t CapsuleTimer.fired() { post capsuleTimerTask(); return SUCCESS; } }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?