void main(int argc, char *argv[]) { char *devdir; int i, rv, netfd, bsize; int datafd; #ifndef plan9 void (*oldhandler)(); #endif devdir = nil; /* make connection */ if (argc != 2) { fprint(stderr, "usage: %s network!destination!service\n", argv[0]); exits("incorrect number of arguments"); } /* read options line from stdin into lnbuf */ i = readline(0); /* read stdin into tempfile to get size */ datafd = tempfile(); bsize = prereadfile(datafd); /* network connection is opened after data is in to avoid timeout */ if ((netfd=dial(argv[1], 0, 0, 0)) < 0) { fprint(stderr, "dialing %s\n", devdir); perror("dial"); exits("can't dial"); } /* write out the options we read above */ if (write(netfd, lnbuf, i) != i) { error(0, "write error while sending options\n"); exits("write error while sending options"); } /* send the size of the file to be sent */ sprint(lnbuf, "%d\n", bsize); i = strlen(lnbuf); if ((rv=write(netfd, lnbuf, i)) != i) { perror("write error while sending size"); error(0, "write returned %d\n", rv); exits("write error while sending size"); } if (seek(datafd, 0L, 0) < 0) { error(0, "error seeking temp file\n"); exits("seek error"); } /* mirror performance in readfile() in lpdaemon */ #ifdef plan9 atnotify(alarmhandler, 1); #else oldhandler = signal(SIGALRM, alarmhandler); #endif dbgstate = 1; if(!recvACK(netfd)) { error(0, "failed to receive ACK before sending data\n"); exits("recv ack1 failed"); } dbgstate = 2; if ((i=pass(datafd, netfd, bsize)) != 0) { NAK(netfd); error(0, "failed to send %d bytes\n", i); exits("send data failed"); } ACK(netfd); dbgstate = 3; if(!recvACK(netfd)) { error(0, "failed to receive ACK after sending data\n"); exits("recv ack2 failed"); } /* get response, as from lp -q */ dbgstate = 4; while((rv=read(netfd, jobbuf, RDSIZE)) > 0) { if((write(1, jobbuf, rv)) != rv) { error(0, "write error while sending to stdout\n"); exits("write error while sending to stdout"); } } dbgstate = 5; #ifdef plan9 atnotify(alarmhandler, 0); /* close down network connections and go away */ exits(""); #else signal(SIGALRM, oldhandler); exit(0); #endif }
//======================================================= // FUNCTION: recv_timer // PURPOSE: Called by the RXTimeoutHandler //======================================================= void recv_timer(MobileNode *node) { char *dst; unsigned duration_us; char tmpbuf[64]; //If it is a MAC-level frame (RTS,CTS,ACK). if (node->nodeMac->pktRx->frame_body == NULL) { dst = GetRa(node->nodeMac->pktRx); //printf("<<<< Got a Mac-Layer frame \n"); } //If it is an ABOVE layer level frame (DATA). else { dst = GetDa(node->nodeMac->pktRx); //printf("<<<< Got a frame from the layer above \n"); } //If the frame arrives while the transmission, it can not be awared //by the node and should be dropped sliently. The EIFS deferral //will not be activated because of the absence of the awareness //for the erroneous received frame. if (GetTxActiveSign(node) == TRUE) { node->nodeStats->DropForInTx += 1; Dot11FrameFree(node->nodeMac->pktRx); node->nodeMac->pktRx = NULL; //********************************FOR TEST ONLY***********************************// //if (MacAddrIsSame(dst, node->nodeMac->mac_addr) == TRUE) { //PrintLine (); //printf("NODE %d: PACKET HAS ERROR : RECV THE PACKET WHEN SENDING PACKET. DROPED.\n",node->Id); //PrintLine (); //} rx_resume(node); CheckBFTimer(node); return; } //Handle frame with receiving collision errors. if ( GetRxStatus(node) == MAC_COLL ) { node->nodeStats->DropForCollision += 1; switch(GetFcSubtype(node->nodeMac->pktRx)) { case MAC_SUBTYPE_RTS: node->nodeStats->RtsDropForCollision += 1; break; case MAC_SUBTYPE_CTS: node->nodeStats->CtsDropForCollision += 1; break; case MAC_SUBTYPE_ACK: node->nodeStats->AckDropForCollision += 1; break; case MAC_SUBTYPE_DATA: node->nodeStats->DataDropForCollision += 1; break; default: printf("[recv_timer]:: Error, Invalid frame subtype!\n"); exit(1); } Dot11FrameFree(node->nodeMac->pktRx); node->nodeMac->pktRx = NULL; //********************************FOR TEST ONLY***********************************// //if (MacAddrIsSame(dst, node->nodeMac->mac_addr) == TRUE) { //PrintLine (); //printf("NODE %d: PACKET HAS ERROR : COLLISION HAPPENED. DROPED.\n",node->Id); //PrintLine (); //} rx_resume(node); PktErrHandler(node); return; } //Handle frame with power fading errors if( PktRxHasFadError(node) == TRUE ) { node->nodeStats->DropForLowRxPwr += 1; //********************************FOR TEST ONLY***********************************// //if (MacAddrIsSame(dst, node->nodeMac->mac_addr) == TRUE) { // PrintLine (); // printf("NODE %d: PACKET HAS ERROR : RECV POWER IS TOO LOW. DROPED.\n",node->Id); // PrintLine (); //} Dot11FrameFree(node->nodeMac->pktRx); node->nodeMac->pktRx = NULL; rx_resume(node); PktErrHandler(node); return; } //Handle frame with transmission collision errors. if( PktRxHasColError(node) == TRUE ) { node->nodeStats->DropForInTx += 1; Dot11FrameFree(node->nodeMac->pktRx); node->nodeMac->pktRx = NULL; //********************************FOR TEST ONLY***********************************// //if (MacAddrIsSame(dst, node->nodeMac->mac_addr) == TRUE) { //PrintLine (); //printf("NODE %d: PACKET HAS ERROR : RECV THE PACKET WHEN SENDING PACKET. DROPED.\n",node->Id); //PrintLine (); //} rx_resume(node); PktErrHandler(node); return; } //Handle frame with awgn noise errors. if (PktRxHasNoiseError(node) == TRUE ) { node->nodeStats->DropForNoiseErr += 1; SetBFWaitTime(node, GetEIFS()); Dot11FrameFree(node->nodeMac->pktRx); node->nodeMac->pktRx = NULL; //********************************FOR TEST ONLY***********************************// //if (MacAddrIsSame(dst, node->nodeMac->mac_addr) == TRUE) { //PrintLine (); //printf("NODE %d: PACKET HAS ERROR : THE PACKET HAS TOO MUCH NOISE. DROPED.\n",node->Id); //PrintLine (); //} rx_resume(node); PktErrHandler(node); return; } // If the received frame is not addressed itself, update the NAV timer. // IEEE 802.11 specs, section 9.2.5.6 if ((MacAddrIsSame(dst, node->nodeMac->mac_addr)) == FALSE) { //printf("Received frame is not addressed itself\n"); duration_us = GetDuration(node->nodeMac->pktRx); Set_Nav(node, UsecToNsec(duration_us)); } //printf("Dst MAC %s \n", MAC2Colon(tmpbuf, dst)); //printf("Node MAC %s \n", MAC2Colon(tmpbuf, node->nodeMac->mac_addr)); // If the received frame is neither addressed itself or a broadcast // frame, drop it. if(((MacAddrIsSame(dst, node->nodeMac->mac_addr)) == FALSE) && CheckIfIsBroadCastPkt(node->nodeMac->pktRx) == FALSE) { node->nodeStats->NotForMeRxed += 1; Dot11FrameFree(node->nodeMac->pktRx); node->nodeMac->pktRx = NULL; //********************************FOR TEST ONLY***********************************// //PrintLine (); //printf("NODE %d: PACKET IS NOT FOR ME. DROPED.\n",node->Id); //PrintLine (); rx_resume(node); CheckBFTimer(node); return; } switch(GetFctype(node->nodeMac->pktRx)) { case MAC_TYPE_MANAGEMENT: printf("[recv_timer]:: MAC_TYPE_MANAGEMENT type is not implemented now!\n"); break; case MAC_TYPE_CONTROL: switch(GetFcSubtype(node->nodeMac->pktRx)) { case MAC_SUBTYPE_RTS: node->nodeStats->RtsRxed += 1; recvRTS(node); break; case MAC_SUBTYPE_CTS: node->nodeStats->CtsRxed += 1; recvCTS(node); break; case MAC_SUBTYPE_ACK: node->nodeStats->AckRxed += 1; recvACK(node); break; default: printf("[recv_timer]:: Error, Invalid frame subtype!\n"); exit(1); } break; case MAC_TYPE_DATA: switch(GetFcSubtype(node->nodeMac->pktRx)) { case MAC_SUBTYPE_DATA: node->nodeStats->DataRxed += 1; recvDATA(node); break; default: printf("[recv_timer]:: Error, Invalid frame subtype!\n"); exit(1); break; } break; default: printf("[recv_timer]:: Error, Invalid frame type!\n"); exit(1); break; } // Only the RTS, CTS and ACK need to be free here. // For DATA frame, the pktRx is set to be NULL by recvDATA() and // the DATA frame is passed to the LLC layer. if (node->nodeMac->pktRx != NULL) { Dot11FrameFree(node->nodeMac->pktRx); node->nodeMac->pktRx = NULL; } rx_resume(node); CheckBFTimer(node); }