SegmentTransposeCommand::SegmentTransposeCommand(SegmentSelection selection, bool changeKey, int steps, int semitones, bool transposeSegmentBack) : MacroCommand(tr("Change segment transposition")) { //SegmentSelection selection(m_view->getSelection()); for (SegmentSelection::iterator i = selection.begin(); i != selection.end(); ++i) { Segment &segment = **i; processSegment(segment, changeKey, steps, semitones, transposeSegmentBack); } }
void Server::incomingConnection( const qintptr socketHandle ) { QThread* workerThread = new QThread( this ); ServerWorker* worker = new ServerWorker( socketHandle ); worker->moveToThread( workerThread ); connect( workerThread, SIGNAL( started( )), worker, SLOT( initConnection( ))); connect( worker, SIGNAL( connectionClosed( )), workerThread, SLOT( quit( ))); // Make sure the thread will be deleted connect( workerThread, SIGNAL( finished( )), worker, SLOT( deleteLater( ))); connect( workerThread, SIGNAL( finished( )), workerThread, SLOT( deleteLater( ))); // public signals/slots, forwarding from/to worker connect( worker, SIGNAL( registerToEvents( QString, bool, deflect::EventReceiver* )), this, SIGNAL( registerToEvents( QString, bool, deflect::EventReceiver* ))); connect( this, SIGNAL( _pixelStreamerClosed( QString )), worker, SLOT( closeConnection( QString ))); connect( this, SIGNAL( _eventRegistrationReply( QString, bool )), worker, SLOT( replyToEventRegistration( QString, bool ))); // Commands connect( worker, SIGNAL( receivedCommand( QString, QString )), &_impl->commandHandler, SLOT( process( QString, QString ))); // PixelStreamDispatcher connect( worker, SIGNAL( addStreamSource( QString, size_t )), &_impl->pixelStreamDispatcher, SLOT(addSource( QString, size_t ))); connect( worker, SIGNAL( receivedSegement( QString, size_t, deflect::Segment )), &_impl->pixelStreamDispatcher, SLOT( processSegment( QString, size_t, deflect::Segment ))); connect( worker, SIGNAL( receivedFrameFinished( QString, size_t )), &_impl->pixelStreamDispatcher, SLOT( processFrameFinished( QString, size_t ))); connect( worker, SIGNAL( removeStreamSource( QString, size_t )), &_impl->pixelStreamDispatcher, SLOT( removeSource( QString, size_t ))); workerThread->start(); }
SegmentTransposeCommand::SegmentTransposeCommand(Segment &segment, bool changeKey, int steps, int semitones, bool transposeSegmentBack) : MacroCommand(tr("Change segment transposition")) { processSegment(segment, changeKey, steps, semitones, transposeSegmentBack); }
/** * Perform one time step of Temporal Pooling for this Region. * * From the Numenta Docs: * The input to this code is activeColumns(t), as computed by the spatial pooler. * The code computes the active and predictive state for each cell at the * current timestep, t. The boolean OR of the active and predictive states * for each cell forms the output of the temporal pooler for the next level. * * Phase 1: compute the active state, activeState(t), for each cell. * The first phase calculates the activeState for each cell that is in a winning column. * For those columns, the code further selects one cell per column as the * learning cell (learnState). The logic is as follows: if the bottom-up * input was predicted by any cell (i.e. its predictiveState output was 1 due * to a sequence segment), then those cells become active (lines 23-27). * If that segment became active from cells chosen with learnState on, this * cell is selected as the learning cell (lines 28-30). If the bottom-up input * was not predicted, then all cells in the col become active (lines 32-34). * In addition, the best matching cell is chosen as the learning cell (lines 36-41) * and a new segment is added to that cell. * * Phase 2: compute the predicted state, predictiveState(t), for each cell. * The second phase calculates the predictive state for each cell. A cell will turn on * its predictive state output if one of its segments becomes active, i.e. if * enough of its lateral inputs are currently active due to feed-forward input. * In this case, the cell queues up the following changes: a) reinforcement of the * currently active segment (lines 47-48), and b) reinforcement of a segment that * could have predicted this activation, i.e. a segment that has a (potentially weak) * match to activity during the previous time step (lines 50-53). * * Phase 3: update synapses. * The third and last phase actually carries out learning. In this phase segment * updates that have been queued up are actually implemented once we get feed-forward * input and the cell is chosen as a learning cell (lines 56-57). Otherwise, if the * cell ever stops predicting for any reason, we negatively reinforce the segments * (lines 58-60). */ void performTemporalPooling(Region* region) { /*Phase 1: Compute cell active states and segment learning updates //18. for c in activeColumns(t) //19. //20. buPredicted = false //21. lcChosen = false //22. for i = 0 to cellsPerColumn - 1 //23. if predictiveState(c, i, t-1) == true then //24. s = getActiveSegment(c, i, t-1, activeState) //25. if s.sequenceSegment == true then //26. buPredicted = true //27. activeState(c, i, t) = 1 //28. if segmentActive(s, t-1, learnState) then //29. lcChosen = true //30. learnState(c, i, t) = 1 //31. //32. if buPredicted == false then //33. for i = 0 to cellsPerColumn - 1 //34. activeState(c, i, t) = 1 //35. //36. if lcChosen == false then //37. i,s = getBestMatchingCell(c, t-1) //38. learnState(c, i, t) = 1 //39. sUpdate = getSegmentActiveSynapses (c, i, s, t-1, true) //40. sUpdate.sequenceSegment = true //41. segmentUpdateList.add(sUpdate)*/ int i; #pragma omp parallel for for(i=0; i<region->numCols; ++i) { Column* col = &(region->columns[i]); if(col->isActive) { bool buPredicted = false; bool learningCellChosen = false; int c; for(c=0; c<col->numCells; ++c) { Cell* cell = &(col->cells[c]); if(cell->wasPredicted) { Segment* segment = getPreviousActiveSegment(cell); if(segment!=NULL && segment->isSequence) { buPredicted = true; cell->isActive = true; if(region->temporalLearning && wasSegmentActiveFromLearning(segment)) { learningCellChosen = true; cell->isLearning = true; } } } } if(!buPredicted) { for(c=0; c<col->numCells; ++c) col->cells[c].isActive = true; } if(region->temporalLearning && !learningCellChosen) { /*printf("bestSeg for (%d %d)\n", col->cx(), col->cy());*/ Segment* bestSeg = NULL; Segment** bestSegPtr = &bestSeg; int bestSegID = -1; Cell* bestCell = getBestMatchingCell(col, bestSegPtr, &bestSegID, 1, true); bestCell->isLearning = true; bestSeg = *bestSegPtr; /* * 1) need to processSegment before step1 * 2) need a processSynapse and store wasActive to fix * since asking wasSynapseActive is using isSynapseConnected */ /*segUpdate is added internally to Cell's update list*/ SegmentUpdateInfo* segmentToUpdate = updateSegmentActiveSynapses(bestCell, true, bestSegID, true); segmentToUpdate->numPredictionSteps = 1;/*sequence segment*/ /*#bestSeg may be partial-sort-of match, but it could dec-perm //#other syns from different step if cell overlaps... // //#try better minOverlap to prevent bad boosting? //#try to disable learning if predictions match heavily? // //#Do we need to enforce max segments per cell?*/ } } } /*Phase2 //42. for c, i in cells //43. for s in segments(c, i) //44. if segmentActive(s, t, activeState) then //45. predictiveState(c, i, t) = 1 //46. //47. activeUpdate = getSegmentActiveSynapses (c, i, s, t, false) //48. segmentUpdateList.add(activeUpdate) //49. //50. predSegment = getBestMatchingSegment(c, i, t-1) //51. predUpdate = getSegmentActiveSynapses( //52. c, i, predSegment, t-1, true) //53. segmentUpdateList.add(predUpdate)*/ #pragma omp parallel for for(i=0; i<region->numCols; ++i) { int c,s; for(c=0; c<region->columns[i].numCells; ++c) { Cell* cell = &(region->columns[i].cells[c]); /*process all segments on the cell to cache the activity for later*/ for(s=0; s<cell->numSegments; ++s) processSegment(&(cell->segments[s])); for(s=0; s<cell->numSegments; ++s) { Segment* seg = &(cell->segments[s]); if(seg->isActive) { setCellPredicting(cell, true); /*a) reinforcement of the currently active segment*/ if(region->temporalLearning) { /*add segment update to this cell //printf("updateSegment (%d,%d) is ",_columns[i].cx(), _columns[i].cy());*/ updateSegmentActiveSynapses(cell, false, s, false); } break; } } /*b) reinforcement of a segment that could have predicted // this activation, i.e. a segment that has a (potentially weak) // match to activity during the previous time step (lines 50-53).*/ if(region->temporalLearning && cell->isPredicting) { /*printf("predSegment is ");*/ int predSegID = -1; Segment* predSegment = getBestMatchingPreviousSegment(cell, &predSegID); /*either update existing or add new segment for this cell considering //only segments matching the number of prediction steps of the //best currently active segment for this cell*/ SegmentUpdateInfo* predSegUpdate = updateSegmentActiveSynapses(cell, true, predSegID, true); if(predSegment==NULL) predSegUpdate->numPredictionSteps = cell->predictionSteps+1; } } } /*Phase3 //54. for c, i in cells //55. if learnState(c, i, t) == 1 then //56. adaptSegments (segmentUpdateList(c, i), true) //57. segmentUpdateList(c, i).delete() //58. else if predictiveState(c, i, t) == 0 and predictiveState(c, i, t-1)==1 then //59. adaptSegments (segmentUpdateList(c,i), false) //60. segmentUpdateList(c, i).delete()*/ if(!region->temporalLearning) return; #pragma omp parallel for for(i=0; i<region->numCols; ++i) { int c; for(c=0; c<region->columns[i].numCells; ++c) { Cell* cell = &(region->columns[i].cells[c]); if(cell->isLearning) { applyCellSegmentUpdates(cell, true); } else if(!cell->isPredicting && cell->wasPredicted) { applyCellSegmentUpdates(cell, false); } } } }
/** * Region Initialization (from Numenta docs): * Prior to receiving any inputs, the region is initialized by computing a list of initial * potential synapses for each column. This consists of a random set of inputs selected * from the input space. Each input is represented by a synapse and assigned a random * permanence value. The random permanence values are chosen with two criteria. * First, the values are chosen to be in a small range around connectedPerm (the minimum * permanence value at which a synapse is considered "connected"). This enables potential * synapses to become connected (or disconnected) after a small number of training * iterations. Second, each column has a natural center over the input region, and the * permanence values have a bias towards this center (they have higher values near * the center). * * In addition to this I have added a concept of Locality Radius, which is an * additional parameter to control how far away synapse connections can be made * instead of allowing connections anywhere. The reason for this is that in the * case of video images I wanted to experiment with forcing each Column to only * learn on a small section of the total input to more effectively learn lines or * corners in a small section without being 'distracted' by learning larger patterns * in the overall input space (which hopefully higher hierarchical Regions would * handle more successfully). Passing in 0 for locality radius will mean no restriction * which will more closely follow the Numenta doc if desired. * * @param inputSize: (x,y) size of input data matrix from the external source. * @param colGridSize: (x,y) number of Columns to create to represent this Region. * @param pctInputPerCol: Percent of input bits each Column has potential synapses for. * @param pctMinOverlap: Minimum percent of column's synapses for column to be considered. * @param localityRadius: Furthest number of columns away to allow distal synapses. * @param pctLocalActivity: Approximate percent of Columns within average receptive * field radius to be winners after inhibition. * @param cellsPerCol: Number of (temporal context) cells to use for each Column. * @param segActiveThreshold: Number of active synapses to activate a segment. * @param newSynapseCount: number of new distal synapses added if none activated during * learning. * @param inputData the array to be used for input data bits. The contents * of this array must be externally updated between time steps (between * calls to Region.runOnce()). * @return a pointer to a newly allocated Region structure (NULL if any malloc calls * have failed). */ Region* newRegion(int inputSizeX, int inputSizeY, int colGridSizeX, int colGridSizeY, float pctInputPerCol, float pctMinOverlap, int localityRadius, float pctLocalActivity, int cellsPerCol, int segActiveThreshold, int newSynapseCount, char* inputData) { Region* region = malloc(sizeof(Region)); if(region==NULL) return NULL; region->inputWidth = inputSizeX; region->inputHeight = inputSizeY; region->nInput = region->inputWidth * region->inputHeight; region->iters = 0; region->inputData = inputData; region->localityRadius = localityRadius; region->cellsPerCol = cellsPerCol; region->segActiveThreshold = segActiveThreshold; region->newSynapseCount = newSynapseCount; region->pctInputPerCol = pctInputPerCol; region->pctMinOverlap = pctMinOverlap; region->pctLocalActivity = pctLocalActivity; region->spatialHardcoded = false; region->spatialLearning = true; region->temporalLearning = true; /*Reduce the number of columns and map centers of input x,y correctly. //column grid will be relative to size of input grid in both dimensions*/ region->width = colGridSizeX; region->height = colGridSizeY; region->numCols = region->width*region->height; region->xSpace = (region->inputWidth-1*1.0) / fmaxf(1.0,(region->width-1)); region->ySpace = (region->inputHeight-1*1.0) / fmaxf(1.0,(region->height-1)); /*Create the columns based on the size of the input data to connect to.*/ region->columns = malloc(region->numCols * sizeof(Column)); if(region->columns==NULL) return NULL; int cx,cy; for(cx=0; cx<region->width; ++cx) { for(cy=0; cy<region->height; ++cy) { int srcPosX = roundf(cx*region->xSpace); int srcPosY = roundf(cy*region->ySpace); initColumn(&(region->columns[(cy*region->width)+cx]), region, srcPosX,srcPosY, cx,cy); } } /* #size the output array as double grid for 4-cell, else just pad the first // #array dimension for 2 or 3 cell (and same size if just 1-cell) // if cellsPerCol==4: // outShape = (len(self.columnGrid)*2, len(self.columnGrid[0])*2) // else: // outShape = (len(self.columnGrid)*cellsPerCol, len(self.columnGrid[0])) // self.outData = numpy.zeros(outShape, dtype=numpy.uint8)*/ /*how far apart are 2 Columns in terms of input space; calc radius from that*/ float inputRadiusf = region->localityRadius*region->xSpace; /*Now connect all potentialSynapses for the Columns*/ int synapsesPerSegment = 1; if(region->localityRadius==0) synapsesPerSegment = (region->inputWidth*region->inputHeight) * pctInputPerCol; else synapsesPerSegment = (inputRadiusf*inputRadiusf) * pctInputPerCol; /*The minimum number of inputs that must be active for a column to be //considered during the inhibition step.*/ region->minOverlap = synapsesPerSegment * pctMinOverlap; /*int longerSide = max(_inputWidth, _inputHeight); //random.seed(42) #same connections each time for easier debugging*/ /* create array of InputCells and array to hold subset of InputCells for * selecting random subsets within radius of spatial pooler columns */ int i,s,x,y; int nc = region->nInput; region->inputCells = malloc(nc * sizeof(Cell)); Cell** ssInputCells = malloc(nc * sizeof(Cell*)); Cell** randCells = malloc(synapsesPerSegment * sizeof(Cell*)); for(i=0; i<nc; ++i) { initInputCell(&(region->inputCells[i]), region, i); ssInputCells[i] = &(region->inputCells[i]); } int inputRadius = roundf(inputRadiusf); int minY = 0; int maxY = region->inputHeight-1; int minX = 0; int maxX = region->inputWidth-1; for(i=0; i<region->numCols; ++i) { if(region->spatialHardcoded) /*no proximal synpases for hardcoded case*/ break; Column* col = &(region->columns[i]); /*restrict synapse connections if localityRadius is non-zero*/ if(region->localityRadius > 0) { minY = max(0, col->iy-inputRadius); maxY = min(region->inputHeight-1, col->iy+inputRadius); minX = max(0, col->ix-inputRadius); maxX = min(region->inputWidth-1, col->ix+inputRadius); /*repopulate inputCells with cells within locality radius*/ s=0; for(x=minX; x<=maxX; ++x) { for(y=minY; y<=maxY; ++y) { int index = (y*region->inputWidth)+x; ssInputCells[s++] = &(region->inputCells[index]); } } nc = s; } /*connect initial proximal synapses. //ensure we sample unique input positions to connect synapses to*/ randomSample(ssInputCells, nc, randCells, synapsesPerSegment); /*printf("Column %d (%d, %d) connected to: ", i, col->cx, col->cy);*/ for(s=0; s<synapsesPerSegment; ++s) { Cell* icell = randCells[s]; /*printf("%d ", icell->index);*/ if(FULL_DEFAULT_SPATIAL_PERMANENCE) { createSynapse(col->proximalSegment, icell, MAX_PERM); } else { /*default to all synapses having connected + 1/3. Unused synapses will * be decremented away over time. This is easier than having half the * synapses disconnected since it's harder for them to become connected * when first learning.*/ int permanence = CONNECTED_PERM + (CONNECTED_PERM/3); createSynapse(col->proximalSegment, icell, permanence); } } /*printf("\n");*/ processSegment(col->proximalSegment); /*calculate initial synapse connections*/ /* This is code suggested by the Numenta doc. I use fixed default permanence * instead to make initial learning faster/easier (based on my experiments). // Util.createRandomSubset(allPos, randPos, synapsesPerSegment, rand); // for(Point pt : randPos) { // InputCell icell = new InputCell( // pt.x, pt.y, (pt.y*_inputHeight)+pt.x, _inputData); // if(FULL_DEFAULT_SPATIAL_PERMANENCE) // col.addProximalSynapse(icell, 1.0f); // else { // double permanence = Synapse.CONNECTED_PERM + // (Synapse.PERMANENCE_INC*rand.nextGaussian()); // permanence = Math.max(0.0, permanence); // double dx = col.ix()-pt.x; // double dy = col.iy()-pt.y; // double distance = Math.sqrt((dx*dx) + (dy*dy)); // double ex = distance / (longerSide*RAD_BIAS_STD_DEV); // double localityBias = (RAD_BIAS_PEAK/0.4) * Math.exp((ex*ex)/-2); // col.addProximalSynapse(icell, (float)(permanence*localityBias)); // } // }*/ } free(randCells); free(ssInputCells); if(!region->spatialHardcoded) region->inhibitionRadius = averageReceptiveFieldSize(region); else region->inhibitionRadius = 0; /*desiredLocalActivity A parameter controlling the number of columns that will be*/ float dla = 0; if(region->localityRadius==0) dla = region->inhibitionRadius * region->pctLocalActivity; else dla = (region->localityRadius*region->localityRadius) * region->pctLocalActivity; region->desiredLocalActivity = max(2, round(dla)); if(DEBUG) { printf("\nRegion Created (ANSI C)"); printf("\ncolumnGrid = (%d, %d)", colGridSizeX, colGridSizeY); printf("\nxSpace, ySpace = %f %f", region->xSpace, region->ySpace); printf("\ninputRadius = %d", inputRadius); printf("\ninitial inhibitionRadius = %f", region->inhibitionRadius); printf("\ndesiredLocalActivity = %d", region->desiredLocalActivity); printf("\nsynapsesPerProximalSegment = %d", synapsesPerSegment); printf("\nminOverlap = %g", region->minOverlap); printf("\nconPerm,permInc = %i %i\n", CONNECTED_PERM, PERMANENCE_INC); } return region; }
int main (){ int sock_main, sock_timer; struct sockaddr_in main, timer; char buf[TCP_SEGMENT_SIZE]; char hostname[128]; gethostname (hostname, sizeof(hostname)); hp = gethostbyname(hostname); sock_main = socket (AF_INET, SOCK_DGRAM, 0); if (sock_main < 0){ perror("opening UDP socket for main use"); exit(1); } bzero ((char*)&main, sizeof (main)); main.sin_family = AF_INET; main.sin_port = TCPD_PORT; bcopy((void *)hp->h_addr_list[0], (void *)&main.sin_addr, hp->h_length); if (bind(sock_main, (struct sockaddr *)&main, sizeof(main)) < 0){ perror("getting socket name of main TCPD port"); exit(2); } printf("TCPD MAIN SOCKET : PORT = %d ADDR = %d\n",main.sin_port,main.sin_addr.s_addr); bzero((char*)&timer, sizeof(timer)); timer.sin_family = AF_INET; timer.sin_port = TIMER_PORT; bcopy((void *)hp->h_addr_list[0], (void *)&timer.sin_addr, hp->h_length); /* TODO : Initialize send and receive windows */ sendWindow.low = 100; sendWindow.high = sendWindow.low + WINDOW_SIZE * TCP_MSS; recvWindow.low = 100; recvWindow.high = recvWindow.low + WINDOW_SIZE * TCP_MSS; while (1){ int type = 0; void *ptr = NULL; int send_bytes = 0; int sock = 0; int rlen = 0; int i = 0; TCP_segment ts; TCP_segment ts_recv; TCP_segment* tsp; struct sockaddr_in name; /* printf("Inside child process to receive data\n"); */ printf("\n\n"); /* Initialize buffer to all zeroes */ bzero(buf, TCP_MSS); /* Receive data from UDP port */ rlen = recvSegment((TCP_segment *)&ts, sock_main, main); /* Get segment type (LOCAL, REMOTE or TIMER) */ type = getSegmentType (ts); /* printf("Segment Type = %d len = %d\n",type,rlen); */ /* Segment received from local application process */ if (type == LOCAL_SEGMENT) { printf("Received local segment len = %d\n",rlen); printf("sBufCount = %d\n",sBufCount); printf("Send window : (%d, %d)\n",sendWindow.low, sendWindow.high); /* Receiving destination address when a CONNECT is called*/ if (ts.hdr.seq == DEST_INFO) { memcpy ((void*)&dest, (void*)&(ts.data), sizeof(struct sockaddr_in)); printf("Received destination info from app\n"); continue; } /* Receiving source address when a BIND is called*/ else if (ts.hdr.seq == SRC_INFO) { memcpy ((void*)&src, (void*)&(ts.data), sizeof(struct sockaddr_in)); printf("Received source info from app port = %d\n",src.sin_port); continue; } /* memcpy((void*)&buf[0], (void*)&ts.data, rlen-TCP_HEADER_SIZE); for (i = 0; i < rlen-TCP_HEADER_SIZE; ++i) printf("%d", buf[i]); printf("Recv bytes = %d\n",rlen-TCP_HEADER_SIZE); */ if (sBufCount == BUFFER_SIZE) continue; /* sBufCount++; */ /* Construct TCP segment with received data */ ts = constructSegment((void*)&ts.data, rlen-TCP_HEADER_SIZE); /* Sequence number gets incremented by * 1 for each byte sent */ nextSeq = nextSeq + rlen-TCP_HEADER_SIZE; /* Add segment to send buffer */ /* TODO: Revisit buffer overflow logic here */ memcpy((void*)&buf, (void*) &ts.data, rlen); /* for (i = 0; i < rlen; ++i) printf("%c"); printf("\n"); */ sBufPtr = addToBuffer (sBufPtr, &sBufCount, ts, rlen); /* Send from send buffer */ sendFromSendBuffer (sBufPtr, sock_main, dest, timer, SEND_ALL, NULL); } /* Segment received from remote process */ else if (type == REMOTE_SEGMENT) { printf("Received remote segment len = %d\n",rlen); printf("Recv window : (%d, %d)\n",recvWindow.low, recvWindow.high); /* TODO : Checksum here */ /* printf("seq = %d crc = %d len = %d\n",ts.hdr.seq,ts.hdr.sum, rlen); memcpy((void*)&buf[0], (void*)&ts, rlen); for (i = 0; i < TCP_HEADER_SIZE; ++i) printf("%d",buf[i]); printf("\n"); */ /* Check if segment has valid checksum */ if (!isValidChecksum(&ts, rlen)){ printf("Checksum FAILURE\n"); continue; } printf("Checksum SUCCESS\n"); /* Check if ACK flag is set */ if (isACK(&ts)){ /* TODO :Handle ACK for already ACKed segments here */ printf("Received ACK no = %d\n", ts.hdr.ack); /* Remove ACKed segment from buffer */ sBufPtr = removeFromSendBuffer(sBufPtr, sock_main, timer, ts.hdr.ack); /* Maintain ACK Count and compute RTO */ ackCount += 1; computeRTO (); continue; } /* Check if segment has valid checksum */ /* if (!isValidChecksum(&ts, rlen)){ printf("Checksum FAILURE"); continue; } printf("Checksum SUCCESS\n"); */ /* Process received segment and return ptr to data*/ ptr = processSegment((TCP_segment *)&ts, rlen); setACKFlag(&ts); /* TODO : How ACK set?*/ ts.hdr.ack = ts.hdr.seq + rlen-TCP_HEADER_SIZE; if (isWithinWindow(recvWindow, ts.hdr.seq+rlen-TCP_HEADER_SIZE)|| (ts.hdr.seq < recvWindow.low)){ int seq = ts.hdr.seq; printf("Sending ACK for seq = %d\n",ts.hdr.seq); ts.hdr.seq = nextSeq; ts.hdr.urp = 0; ts.hdr.sum = 0; memcpy((void*)&buf, (void*)&ts, TCP_HEADER_SIZE); ts.hdr.sum = computeChecksum(&buf[0], TCP_HEADER_SIZE, &(ts.hdr.sum)); /* printf("Checksum for ACK seq : %d crc : %d len : %d\n",ts.hdr.seq, ts.hdr.sum, TCP_HEADER_SIZE); for (i = 0; i < TCP_HEADER_SIZE; ++i) printf("%d",buf[i]); printf("\n"); */ /*ts.hdr.urp = REMOTE_SEGMENT;*/ /* for (i = 0; i < TCP_HEADER_SIZE; ++i) printf("%d",buf[i]); printf("\n"); */ /* Sending ACK to remote process */ sendSegment(&ts, TCP_HEADER_SIZE, sock_main, replyaddr); nextSeq = nextSeq + TCP_HEADER_SIZE; ts.hdr.seq = seq; } /*printf("Sent ACK for seq = %d to dest = %d\n",ts.hdr.seq, replyaddr.sin_addr.s_addr); */ if (!isWithinWindow(recvWindow, ts.hdr.seq+rlen-TCP_HEADER_SIZE) || nextExpectedSeq > ts.hdr.seq){ printf("Not within recv window seq = %d\n",ts.hdr.seq); continue; } printf("rBufCount = %d\n",rBufCount); /* if (rBufPtr != NULL) printf("RB : headseq = %d nes = %d\n",rBufPtr->ts.hdr.seq, nextExpectedSeq); if (rBufPtr != NULL && rBufPtr->ts.hdr.seq < nextExpectedSeq){ printf("EXITING.......... \n"); exit(1); } */ /* if (nextExpectedSeq < recvWindow.low){ printf("EXITING..\n"); exit(1); } */ if (rBufCount == BUFFER_SIZE) continue; /*rBufCount++; */ /* TODO: Temporary hack to avoid recv buffer */ /*sendData(&ts, rlen, sock_main, src); continue; */ /* Add segment to receive buffer */ rBufPtr = addToBuffer (rBufPtr, &rBufCount, ts, rlen); if (rBufPtr == NULL){ printf("rbufptr = NULL post adding\n"); continue; } /* Update receive window */ updateWindow(&recvWindow, ts.hdr.seq, rlen-TCP_HEADER_SIZE); /* Send data to local process */ rBufPtr = sendFromRecvBuffer(rBufPtr, sock_main, src); } else if (type == TIMER_SEGMENT){ TCP_buffer* ptr = NULL; printf("Received timer segment len = %d\n",rlen); memcpy((void*)&ptr, (void*)&(ts.data), sizeof(ptr)); /* Update RTO on timeout. Message from timer * implies timeout. */ computeRTO(); /* Retransmit segment to remote process */ sendFromSendBuffer (sBufPtr, sock_main, dest, timer, SEND_ONE, ptr); } } return 0; }