📄 maca.pc
字号:
* * ASSUMPTION: node != NULL. */static void MacMacaDataXmit(GlomoNode *node, GlomoMacMaca *maca, int tag) { Message *msg; MacaHeader *hdr; NODE_ADDR nextHopAddress; assert(maca->state == MACA_S_XMIT); NetworkIpOutputQueueDequeuePacketForAPriority( node, maca->myGlomoMac->interfaceIndex, maca->currentPriority, &msg, &nextHopAddress); if (msg == NULL) { #ifdef QDEBUG printf("MACA: Queue should not be empty...\n"); #endif return; } GLOMO_MsgAddHeader(node, msg, sizeof(MacaHeader)); hdr = (MacaHeader *) msg->packet; hdr->frameType = tag; hdr->payloadSize = msg->packetSize - sizeof(MacaHeader); hdr->sourceAddr = node->nodeAddr; hdr->destAddr = nextHopAddress; hdr->priority = maca->currentPriority; maca->currentPriority = -1; if (tag == MACA_UNICAST) { maca->pktsSentUnicast++; MacMacaSetState(node, maca, MACA_S_IN_XMITING_UNICAST); } else if (tag == MACA_BROADCAST) { maca->pktsSentBroadcast++; MacMacaSetState(node, maca, MACA_S_IN_XMITING_BROADCAST); } GLOMO_RadioStartTransmittingPacket( node, maca->myGlomoMac->interfaceIndex, msg, hdr->destAddr, FALSE, 0);}/* * NAME: MacMacaBackoff. * * PURPOSE: Backing off sending data at a later time. * * PARAMETERS: node, node that is backing off. * * RETURN: None. * * ASSUMPTION: node != NULL. */static void MacMacaBackoff(GlomoNode *node, GlomoMacMaca *maca) { clocktype randomTime; assert(maca->state == MACA_S_BACKOFF); randomTime = (pc_nrand(node->seed) % maca->BOmin) + 1; maca->BOmin = maca->BOmin * 2; if (maca->BOmin > maca->BOmax) { maca->BOmin = maca->BOmax; } maca->BOtimes++; MacMacaSetTimer(node, maca, MACA_T_BACKOFF, randomTime); }/* * NAME: MacMacaPassive. * * PURPOSE: In passive mode, check whether there is a local packet. * If YES, send RTS; else return; * * PARAMETERS: node, node that is in passive state. * * RETURN: None. * * ASSUMPTION: node != NULL. */static void MacMacaPassive(GlomoNode *node, GlomoMacMaca *maca){ char clockStr[GLOMO_MAX_STRING_LENGTH]; Message *tmpPktPtr; NODE_ADDR nextHopAddress; NetworkQueueingPriorityType priority; if (maca->state != MACA_S_PASSIVE) return; if (NetworkIpOutputQueueIsEmpty( node, maca->myGlomoMac->interfaceIndex)) { maca->currentPriority = -1; return; } NetworkIpOutputQueueTopPacket( node, maca->myGlomoMac->interfaceIndex, &tmpPktPtr, &nextHopAddress, &priority); maca->currentPriority = priority; if (nextHopAddress != ANY_DEST) { MacMacaSetState(node, maca, MACA_S_RTS); MacMacaRts(node, maca); } else { if (RadioStatus(node, maca) == RADIO_IDLE) { MacMacaSetState(node, maca, MACA_S_XMIT); MacMacaDataXmit(node, maca, MACA_BROADCAST); } else { MacMacaSetState(node, maca, MACA_S_BACKOFF); MacMacaBackoff(node, maca); } }}/* * NAME: MacMacaNetworkLayerHasPacketToSend. * * PURPOSE: Starts process to send a packet. * * RETURN: None. * */void MacMacaNetworkLayerHasPacketToSend(GlomoNode* node, GlomoMacMaca* maca){ MacMacaPassive(node, maca);}/* * NAME: MacMacaRemote. * * PURPOSE: Handle incoming frames. * * PARAMETERS: node, node handling incoming frame. * msg, the incoming frame. * * RETURN: None. * * ASSUMPTION: node != NULL. */static void MacMacaRemote(GlomoNode *node, GlomoMacMaca *maca, Message *msg){ NODE_ADDR receiverAddr; NODE_ADDR sourceAddr, destAddr; int frameType, payloadSize; clocktype holdForCtsData = 0, holdForData = 0; MacaHeader *hdr = (MacaHeader *) msg->packet; receiverAddr = node->nodeAddr; sourceAddr = hdr->sourceAddr; destAddr = hdr->destAddr; frameType = hdr->frameType; payloadSize = hdr->payloadSize; switch (frameType) { case MACA_RTS: if (receiverAddr == destAddr) { /* local RTS */ maca->RtsPacketGot++; MacMacaSendCts(node, maca, sourceAddr, payloadSize); } else { /* Overheard RTS */ /* Hold until other's CTS and DATA to be finished */ holdForCtsData = ((sizeof(MacaHeader) + payloadSize + sizeof(MacaHeader)) * SECOND) / maca->myGlomoMac->bandwidth + (3 * MAC_DELAY) + (2 * RADIO_PHY_DELAY) + (2 * SYNCHRONIZATION_TIME) + (2 * maca->myGlomoMac->propDelay) + MACA_EXTRA_DELAY; MacMacaSetTimer(node, maca, MACA_T_REMOTE, holdForCtsData); maca->NoisyPacketGot++; } GLOMO_MsgFree(node, msg); break; case MACA_CTS: { /* * Determines how long a remote node backoffs to allow * other nodes to send and receive data packets. The * bigger the different between this value and the actual * time for other nodes to send and receive a data packet, * the more unfairness occurs for this node since the other * nodes will be allowed to transmit before this node. */ holdForData = ((payloadSize + sizeof(MacaHeader)) * SECOND) / maca->myGlomoMac->bandwidth + MAC_DELAY + SYNCHRONIZATION_TIME + RADIO_PHY_DELAY + maca->myGlomoMac->propDelay + MACA_EXTRA_DELAY; MacMacaSetTimer(node, maca, MACA_T_REMOTE, holdForData); maca->NoisyPacketGot++; GLOMO_MsgFree(node, msg); break; } case MACA_UNICAST: { /* yield for some time */ if (receiverAddr == destAddr) { MacMacaGetData(node, maca, msg); } else { if (maca->myGlomoMac->promiscuousMode == TRUE) { MacMacaHandlePromiscuousMode(node, maca, msg); } GLOMO_MsgFree(node, msg); } MacMacaSetState(node, maca, MACA_S_PASSIVE); MacMacaPassive(node, maca); break; } case MACA_BROADCAST: { /* yield for some time */ /* if local data */ if (destAddr == ANY_DEST) { MacMacaGetData(node, maca, msg); } else { GLOMO_MsgFree(node, msg); } MacMacaSetState(node, maca, MACA_S_YIELD); MacMacaYield(node, maca, MACA_VACATION); break; } default: assert(FALSE); break; } /* end of switch */}/* * FUNCTION MacMacaInit * PURPOSE Initialization function for MACA protocol of MAC layer. * Parameters: * node: node being initialized. * nodeInput: structure containing contents of input file */void MacMacaInit( GlomoNode *node, int interfaceIndex, const GlomoNodeInput *nodeInput){ char clockStr[GLOMO_MAX_STRING_LENGTH]; int retVal; GlomoMacMaca *maca = (GlomoMacMaca *) pc_malloc(sizeof(GlomoMacMaca)); char buf[GLOMO_MAX_STRING_LENGTH]; assert(maca != NULL); memset(maca, 0, sizeof(GlomoMacMaca)); maca->myGlomoMac = node->macData[interfaceIndex]; maca->myGlomoMac->macVar = (void *)maca; maca->state = MACA_S_PASSIVE; maca->BOmin = MACA_BO_MIN; maca->BOmax = MACA_BO_MAX; maca->BOtimes = 0; maca->timer.flag = MACA_TIMER_OFF | MACA_T_UNDEFINED; maca->timer.seq = 0; maca->pktsToSend = 0; maca->pktsLostOverflow = 0; maca->pktsSentUnicast = 0; maca->pktsSentBroadcast = 0; maca->pktsGotUnicast = 0; maca->pktsGotBroadcast = 0; maca->RtsPacketSent = 0; maca->CtsPacketSent = 0; maca->RtsPacketGot = 0; maca->CtsPacketGot = 0; maca->NoisyPacketGot = 0; maca->currentPriority = -1;}/* * FUNCTION MacMacaFinalize * PURPOSE Called at the end of simulation to collect the results of * the simulation of the MAC layer MACA protocol. * * Parameter: * node: node for which results are to be collected. */void MacMacaFinalize(GlomoNode *node, int interfaceIndex){ GlomoMacMaca *maca = (GlomoMacMaca *)node->macData[interfaceIndex]->macVar; if (maca->myGlomoMac->macStats == TRUE) { MacMacaPrintStats(node, maca); }}void MacMacaReceivePacketFromRadio( GlomoNode* node, GlomoMacMaca* maca, Message* msg) { MacaHeader *hdr = (MacaHeader *) msg->packet; int frameType = hdr->frameType; if ((hdr->destAddr == node->nodeAddr) || (hdr->destAddr == ANY_DEST)) { maca->currentPriority = hdr->priority; } switch(maca->state) { case MACA_S_RTS: { if ((hdr->destAddr == node->nodeAddr) && (frameType == MACA_CTS)) { /* Local CTS */ maca->CtsPacketGot++; MacMacaCancelTimer(node, maca, MACA_T_RTS); MacMacaSetState(node, maca, MACA_S_XMIT); MacMacaDataXmit(node, maca, MACA_UNICAST); GLOMO_MsgFree(node, msg); } /* Fall through */ else { MacMacaCancelTimer(node, maca, MACA_T_RTS); MacMacaSetState(node, maca, MACA_S_REMOTE); MacMacaRemote(node, maca, msg); maca->NoisyPacketGot++; } break; } case MACA_S_YIELD: case MACA_S_PASSIVE: case MACA_S_BACKOFF: case MACA_S_REMOTE: { MacMacaCancelTimer(node, maca, MACA_T_UNDEFINED); MacMacaSetState(node, maca, MACA_S_REMOTE); MacMacaRemote(node, maca, msg); break; } case MACA_S_IN_XMITING_RTS: { /* * Receives mesg from radio even though in transmit mode. * This can possibly happen due to simultaneous messages. * The radio layer receives a mesg from the channel and * sends it up to the MAC layer at the same time as the * MAC layer sends down the RTS message */ /* * Since the messages are simultaneous, we can assume that * the RTS message is sent before the incoming message * is received. Thus we lose the incoming packet. */ GLOMO_MsgFree(node, msg); break; } case MACA_S_XMIT: case MACA_S_IN_XMITING_CTS: case MACA_S_IN_XMITING_UNICAST: case MACA_S_IN_XMITING_BROADCAST: GLOMO_MsgFree(node, msg); assert(FALSE); break; default:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -