UDPFileTransferClient-Server / window.c
window.c
Raw
#include <string.h>
#include <arpa/inet.h>

#include "safeUtil.h"
#include "window.h"
#include "pdu.h"


Window createWindow(int winSize) {
    Window win;
    win.windowSize = winSize;
    win.table = sMalloc(sizeof(windowEntry) * winSize);
    win.lower = 0;
    win.upper = winSize;
    win.current = 0;

    // Loop and fill table with invalid entries
    int i = 0;
    for (; i < winSize; i++) {
        win.table[i] = createEntry();
    }

    return win;
}


// void createWindow(int winSize, Window *win) {
//     //Window win;
//     win->windowSize = winSize;
//     win->table = sMalloc(sizeof(windowEntry) * winSize);
//     win->lower = 0;
//     win->upper = winSize;
//     win->current = 0;

//     // Loop and fill table with invalid entries
//     int i = 0;
//     for (; i < winSize; i++) {
//         (win->table)[i] = createEntry();
//     }

//     //return win;
// }

windowEntry createEntry() {
    windowEntry ent;
    ent.isValid = false;
    ent.sequenceNum = 0;
    ent.packetLength = 0;
    return ent;
}

windowEntry createValidEntry(bool valid, int seqNum, int pktLen) {
    windowEntry ent;
    ent.isValid = valid;
    ent.sequenceNum = seqNum;
    ent.packetLength = pktLen;
    return ent;
}

windowEntry createValidPDUEntry(int seqNum, uint8_t *pkt, int pktLen) {
    windowEntry ent;
    ent.isValid = true;
    ent.sequenceNum = seqNum;
    //memcpy(ent.PDU, &pkt[HEADER_LEN], pktLen - HEADER_LEN);
    // copy the WHOLE packet in
    memcpy(ent.PDU, pkt, pktLen);
    ent.packetLength = pktLen;
    return ent;
}

void addPDUToWindow (Window *win, uint8_t *pdu, int pktLen) {
    // create the entry
    uint32_t seqNum = 0;
    memcpy(&seqNum, &pdu[0], sizeof(seqNum));
    seqNum = ntohl(seqNum);
    windowEntry we = createValidPDUEntry(seqNum, pdu, pktLen);

    // Add it to the window
     addEntry(win, we);
}

void addEntry (Window * win, windowEntry we) {
    int index = we.sequenceNum % (*win).windowSize;
    (win->table)[index] = we;
    (win->current)++;
}

windowEntry getEntry (Window win, int seqNum) {
    int index = seqNum % win.windowSize;
    return win.table[index];
}

// TODO: may need to change this in case the lowest packet is ever
// invalid. 
windowEntry getLowestEntry(Window win) {
    windowEntry we = getEntry(win, win.lower);
    return we;
}

// To hopefully sort out the weird memory bugs I'm getting
void copyPDULocal(Window *win, uint8_t *local, int *localSize, int index) {
    //printf("Copy from the window to a local pointer -> : %d, %s\n", (win->table)[index].packetLength, &((win->table)[index].PDU[7]));
    memcpy(local, (win->table)[index].PDU, (win->table)[index].packetLength);
    *localSize = (win->table)[index].packetLength;
}

// marks an entry invalid to sort out memory bugs
void markEntryInvalid(Window *win, int index) {
    (win->table)[index].isValid = false;
}


// sets lower to new RR value, update upper
// seq numbers lower to RR are now invalid 
void handleRR (Window *win, int rr) {
    int i = 0;
    // lower becomes new rr value, upper is lower + winsize
    (*win).lower = rr;
    (*win).upper = (*win).lower + (*win).windowSize;

    // Loop through all entries, if seqnum < RR, mark invalid
    for(; i < (*win).windowSize; i++) {
        if ((*win).table[i].sequenceNum < rr) {
            (*win).table[i].isValid = false;
        }
    }
}


windowEntry handleSREJ (Window win, int srej) {
    windowEntry we = getEntry(win, srej);
    return we;
}


void printEntry (windowEntry we) {
    printf("\nPDU from window: seq num: %d pduSize: %d\n", we.sequenceNum, we.packetLength);
}

bool isWindowOpen (Window win) {
    if (win.current == win.upper) {
        return false;
    }
    return true;
}

void printWindowMetaData(Window win) {
    printf("Window Data - Window Size: %d, lower: %d, Upper: %d, Current: %d window open?: %d\n", 
            win.windowSize, win.lower, win.upper, win.current, isWindowOpen(win));
}

void printWindow(Window win) {
    int i = 0;
    printf("Window size is: %d\n", win.windowSize);
    for (; i < win.windowSize; i++) {
        if (win.table[i].isValid) {
            //printf("memory address for entry variable at %d is %p\n", i, &(win.table[i]));
            printf("\t%d sequenceNumber: %d pduSize: %d\n", i, win.table[i].sequenceNum, 
                    win.table[i].packetLength);
        
        } else {
            printf("\t%d not valid\n", i);
        }
    }
}