📄 tsma.pc
字号:
* msg, contains the acknowledgment being sent * * RETURN: None * * ASSUMPTIONS: None */void MacTsmaSendAck(GlomoNode *node, GlomoMacTsma *tsma, Message *msg){ MacTsmaHeader *hdr = (MacTsmaHeader *)msg->packet; MacTsmaHeader ack; Message *radioMsg = GLOMO_MsgAlloc(node, 0, 0, 0); /* Allocate space. */ GLOMO_MsgPacketAlloc(node, radioMsg, sizeof(MacTsmaHeader)); /* Initialize acknowledgment. */ ack.sourceAddr = node->nodeAddr; ack.destAddr = hdr->sourceAddr; ack.type = TSMA_ACK; ack.seqNum = hdr->seqNum; /* Copy acknowledgment into message. */ memcpy(radioMsg->packet, &(ack), sizeof(MacTsmaHeader)); /* Transition into proper state. */ MacTsmaChangeState(node, tsma, MAC_TSMA_XMT_UACK); /* Send message to radio layer. */ GLOMO_RadioStartTransmittingPacket( node, tsma->myGlomoMac->interfaceIndex, radioMsg, ack.destAddr, FALSE, 0);}/* * NAME: MacTsmaPacketSent * * PURPOSE: Determine type of frame that was sent, and take appropriate * actions. * * PARAMETERS: node, node that sent a frame * msg, contains the frame sent event * * RETURN: None * * ASSUMPTIONS: None */void MacTsmaPacketSent(GlomoNode *node, GlomoMacTsma *tsma){ Message *newMsg; BOOL retval; switch (tsma->currentState) { case MAC_TSMA_XMT_UACK: { /* * ACKNOWLEDGMENT SENT: */ #ifdef TSMA_DEBUG if (node->nodeAddr == MONITOR_ID) { char clockStr[GLOMO_MAX_STRING_LENGTH]; ctoa(simclock(), clockStr); printf("Time(%s) acknowledgment frame sent\n", clockStr); } #endif /* * After sending an acknowledgment, we must begin to * service our own packets. */ /* Check to see if the queue is empty. */ CheckForPacketToTransmit(node, tsma); break; } case MAC_TSMA_XMT_UPKT: { /* * UNICAST PACKET SENT: */ #ifdef TSMA_DEBUG if (node->nodeAddr == MONITOR_ID) { char clockStr[GLOMO_MAX_STRING_LENGTH]; ctoa(simclock(), clockStr); printf("Time(%s) unicast frame sent\n", clockStr); } #endif /* * Once a unicast frame is sent, we must wait for a * corresponding acknowledgement from the destination. */ MacTsmaChangeState(node, tsma, MAC_TSMA_WF_UACK); /* Update the packet repetitions for the frame. */ ++tsma->pktReps; break; } case MAC_TSMA_XMT_BPKT: { /* * BROADCAST FRAME SENT: */ #ifdef TSMA_DEBUG if (node->nodeAddr == MONITOR_ID) { char clockStr[GLOMO_MAX_STRING_LENGTH]; ctoa(simclock(), clockStr); printf("Time(%s) broadcast frame sent\n", clockStr); } #endif /* * Once a broadcast frame has been transmitted maxRep times, * we are ready to service the next network frame in the * queue. */ tsma->pktReps++; if (tsma->pktReps >= tsma->maxReps) { /* Remove current outgoing frame */ assert(tsma->currentOutgoingFrame != NULL); GLOMO_MsgFree(node, tsma->currentOutgoingFrame); tsma->currentOutgoingFrame = NULL; #ifdef TSMA_DEBUG if (node->nodeAddr == MONITOR_ID) { char clockStr[GLOMO_MAX_STRING_LENGTH]; ctoa(simclock(), clockStr); printf("Time(%s) finished with current broadcast frame\n", clockStr); } #endif /* Update broadcast counter. */ ++tsma->pktsSentBroadcast; /* Update sequence number. */ ++tsma->seqNum; /* Reset frame repetitions. */ tsma->pktReps = 0; /* Check to see if queue is now empty. */ CheckForPacketToTransmit(node, tsma); } else { /* * This frame must be repeated again. Wait for the * next transmission slot. */ MacTsmaChangeState(node, tsma, MAC_TSMA_WF_BSLOT); } break; } default: { char clockStr[GLOMO_MAX_STRING_LENGTH]; ctoa(simclock(), clockStr); printf("Time(%s) node %d sent unknown packet type\n", clockStr, node->nodeAddr); assert(FALSE); abort(); } }}/* * NAME: MacTsmaHandlePromiscuousMode * * PURPOSE: Supports promiscuous mode, sending remote frames to * upper layers. * * PARAMETERS: node, node handling remote frame * msg, contains remote frame * * RETURN: None * * ASSUMPTIONS: None */void MacTsmaHandlePromiscuousMode( GlomoNode *node, GlomoMacTsma *tsma, Message *msg){ GLOMO_MsgRemoveHeader(node, msg, sizeof(MacTsmaHeader)); NetworkIpSneakPeekAtMacPacket(node, msg); GLOMO_MsgAddHeader(node, msg, sizeof(MacTsmaHeader));}/* * NAME: MacTsmaRetransmitPkt * * PURPOSE: Retransmit unicast frame. * * PARAMETERS: node, node sending retransmission * * RETURN: None * * ASSUMPTIONS: None */void MacTsmaRetransmitPkt(GlomoNode *node, GlomoMacTsma *tsma){ #ifdef TSMA_DEBUG if (node->nodeAddr == MONITOR_ID) { char clockStr[GLOMO_MAX_STRING_LENGTH]; ctoa(simclock(), clockStr); printf("Time(%s) acknowledgment not received, ", clockStr); } #endif /* Check to see if maximum repetitions has been reached. */ if (tsma->pktReps >= tsma->maxReps) { /* Drop current frame, and move on to the next. */ assert(tsma->currentOutgoingFrame != NULL); GLOMO_MsgFree(node, tsma->currentOutgoingFrame); tsma->currentOutgoingFrame = NULL; /* Reset frame repetitions. */ tsma->pktReps = 0; /* Check for Outgoing packets */ CheckForPacketToTransmit(node, tsma); } else { /* Frame can be resent in the next transmission slot. */ #ifdef TSMA_DEBUG if (node->nodeAddr == MONITOR_ID) { printf("retransmitting frame.\n"); } #endif MacTsmaChangeState(node, tsma, MAC_TSMA_WF_USLOT); }}/* * NAME: MacTsmaPrintStats * * PURPOSE: Print MAC layer statistics. * * PARAMETERS: node, node for which stats are collected * * RETURN: None * * ASSUMPTIONS: None */void MacTsmaPrintStats(GlomoNode *node, GlomoMacTsma *tsma){ char buf[GLOMO_MAX_STRING_LENGTH]; sprintf(buf, "Number of packets from network: %d\n", tsma->pktsToSend); GLOMO_PrintStat(node, "MacTSMA", buf); sprintf(buf, "Number of packets lost due to buffer overflow: %d\n", tsma->pktsLostOverflow); GLOMO_PrintStat(node, "MacTSMA", buf); sprintf(buf, "Number of UNICAST packets output to the channel: %d\n", tsma->pktsSentUnicast); GLOMO_PrintStat(node, "MacTSMA", buf); sprintf(buf, "Number of BROADCAST packets output to the channel: %d\n", tsma->pktsSentBroadcast); GLOMO_PrintStat(node, "MacTSMA", buf); sprintf(buf, "Number of UNICAST packets received clearly: %d\n", tsma->pktsGotUnicast); GLOMO_PrintStat(node, "MacTSMA", buf); sprintf(buf, "Number of BROADCAST packets received clearly: %d\n", tsma->pktsGotBroadcast); GLOMO_PrintStat(node, "MacTSMA", buf);}/* * NAME: MacTsmaBeginSlot * * PURPOSE: Simulate next slot * * PARAMETERS: node, node handling next slot * * RETURN: None * * ASSUMPTIONS: None */void MacTsmaBeginSlot(GlomoNode *node, GlomoMacTsma *tsma){ BOOL retval; /* Advance slot counter. */ tsma->currentSlot = (tsma->currentSlot+1) % tsma->frameLength; #ifdef TSMA_DEBUG if (node->nodeAddr == MONITOR_ID) { char clockStr[GLOMO_MAX_STRING_LENGTH]; ctoa(simclock(), clockStr); printf("%d:Time(%s) new slot beginning %d %d\n", node->nodeAddr, clockStr, tsma->currentState, tsma->currentSlot); } #endif switch (tsma->currentState) { case MAC_TSMA_READY: { /* Make sure that there are no packets in the queue. */ if ((tsma->currentOutgoingFrame != NULL) || (!NetworkIpOutputQueueIsEmpty( node, tsma->myGlomoMac->interfaceIndex))) { char clockStr[GLOMO_MAX_STRING_LENGTH]; ctoa(simclock(), clockStr); printf("Time(%s) node %d in READY state with buffered frames!\n", clockStr, node->nodeAddr); assert(FALSE); abort(); } /* Nothing else to do. */ break; } case MAC_TSMA_WF_USLOT: { /* Determine if node has permission to transmit in this slot. */ retval = MacTsmaTransmit(node, tsma); if (retval == TRUE) { /* Transmit unicast packet. */ MacTsmaSendUnicastPkt(node, tsma); } break; } case MAC_TSMA_WF_BSLOT: { /* Determine if node has permission to transmit in this slot. */ retval = MacTsmaTransmit(node, tsma); if (retval == TRUE) { /* Transmit broadcast packet. */ MacTsmaSendBroadcastPkt(node, tsma); } break; } case MAC_TSMA_XMT_UPKT: case MAC_TSMA_XMT_BPKT: case MAC_TSMA_XMT_UACK: { /* The slot size is too small! */ char clockStr[GLOMO_MAX_STRING_LENGTH]; ctoa(simclock(), clockStr); printf("Time(%s) node %d still transmitting at beginning of slot!\n", clockStr, node->nodeAddr); assert(FALSE); abort(); break; } case MAC_TSMA_WF_UACK: { /* No acknowledgment received. Retransmit unicast packet. */ MacTsmaRetransmitPkt(node, tsma); break; } default: { /* Illegal state! */ char clockStr[GLOMO_MAX_STRING_LENGTH]; ctoa(simclock(), clockStr); printf("Time(%s) node %d in an unknown state!\n", clockStr, node->nodeAddr); assert(FALSE); abort(); } }}/* * NAME: MacTsmaProcBroadcastPkt * * PURPOSE: Process incoming broadcast frame. * * PARAMETERS: node, node receiving broadcast frame * msg, contains the broadcast frame * * RETURN: None * * ASSUMPTIONS: None */void MacTsmaProcBroadcastPkt(GlomoNode *node, GlomoMacTsma *tsma, Message *msg){ MacTsmaHeader *hdr = (MacTsmaHeader *)msg->packet; #ifdef TSMA_DEBUG if (node->nodeAddr == MONITOR_ID) { char clockStr[GLOMO_MAX_STRING_LENGTH]; ctoa(simclock(), clockStr); printf("Time(%s) received broadcast frame from node %d\n", clockStr, hdr->sourceAddr); } #endif /* Filter out duplicate broadcast packets. */ if (hdr->seqNum > tsma->pktIds[hdr->sourceAddr]) { /* Register frame identifier. */ tsma->pktIds[hdr->sourceAddr] = hdr->seqNum; /* Send frame to network layer. */ MacTsmaPassPkt(node, tsma, msg); /* Update broadcast counter. */ ++tsma->pktsGotBroadcast; } else if (hdr->seqNum == tsma->pktIds[hdr->sourceAddr]) { /* * This is a duplicate broadcast packet which * should be ignored. */ #ifdef TSMA_DEBUG if (node->nodeAddr == MONITOR_ID) { printf("\tIgnoring duplicate broadcast frame.\n"); } #endif GLOMO_MsgFree(node, msg); } else { /* Invalid identifier. */ char clockStr[GLOMO_MAX_STRING_LENGTH]; ctoa(simclock(), clockStr); printf("Time(%s) %d received frame from %d with invalid seqNum\n", clockStr, node->nodeAddr, hdr->sourceAddr); assert(FALSE); abort(); }}/* * NAME: MacTsmaProcUnicastPkt * * PURPOSE: Process incoming unicast frame. * * PARAMETERS: node, node receiving the unicast frame * msg, contains the unicast frame
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -