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 + -
显示快捷键?