Untitled

 avatar
unknown
c_cpp
a year ago
8.7 kB
6
Indexable
#include "header.h"
 
unsigned char* serialize(struct packet* p) {
    int size = sizeof(struct packet);
 
    unsigned char* buffer;
    buffer = (unsigned char*)calloc(size, sizeof(unsigned char));
 
    int ptr = 0;
 
    // version and header length
    buffer[ptr++] = (p->version << 4) | p->headerLength;;
 
    // total length
    buffer[ptr++] = p->totalLength;
 
    //source and dest dept and first 2 bits of checksum
    int checkSumIdx1 = ptr;
    buffer[ptr++] = (p->srcDept << 5) | (p->destDept << 2);
    
    int checkSumIdx2 = ptr;
    ptr++;
    // //last 6 bits of checksum
    // buffer[ptr++] = (p->checkSum & 0xFF);
 
    //hops, type and ack
    buffer[ptr++] = (p->hops << 5) | (p->type << 2) | p->ACK;
 
    //source and dest campus
    if (p->headerLength == 6) {
        buffer[ptr++] = (p->srcCampus << 4) | p->destCampus;
    }

    //data
    strcpy(buffer + ptr, p->data, BUFFER_SIZE);
    
    checkSum = checksumCalc(buffer);
    buffer[checkSumIdx1] |= ((checkSum >> 8) & 0b11);
    buffer[checkSumIdx2] = (checkSum & 0xFF);
 
    return buffer;
}
 
struct packet* deserialize(unsigned char* buffer) {
    struct packet* p;
    p = (struct packet*)malloc(sizeof(struct packet));
 
    int ptr = 0;
    
    // version and header length
    p->version = buffer[ptr] >> 4;
    p->headerLength = buffer[ptr] & 0b1111;
    ptr++;
 
    // total length
    p->totalLength = buffer[ptr];
    ptr++;
 
    //source and dest dept and first 2 bits of checksum
    p->srcDept = buffer[ptr] >> 5;
    p->destDept = (buffer[ptr] >> 2) & 0b111;
    p->checkSum = (buffer[ptr] & 0b11) << 8;
    ptr++;
 
    //last 8 bits of checksum
    p->checkSum |= buffer[ptr];
    ptr++;
 
    //hops, type and ack
    p->hops = buffer[ptr] >> 5;
    p->type = (buffer[ptr] >> 2) & 0b111;
    p->ACK = buffer[ptr] & 0b11;
    ptr++;
 
    //source and dest campus
    if (p->headerLength == 6) {
        p->srcCampus = buffer[ptr] >> 4;
        p->destCampus = buffer[ptr] & 0b1111;
        ptr++;
    }
 
    //data
    memcpy(p->data, buffer + ptr, BUFFER_SIZE);
 
    return p;
}
 
int checksumCalc(unsigned char* buffer){
    int checksum = 0;
    int ptr = 0;
 
    // version and header length
    checksum += buffer[ptr];
    ptr++;
 
    // total length
    checksum += buffer[ptr];
    ptr++;
 
    //source and dest dept, except first 2 bits of checksum
    checksum += (buffer[ptr] >> 2);
    ptr++;
 
    // ignore the last 8 bits of checksum
    ptr++;
 
    // hops, type and ack
    checksum += buffer[ptr];
    ptr++;
 
    //source and dest campus
    if (buffer[1] == 6) {
        checksum += buffer[ptr];
        ptr++;
    }
 
    //data
    for (int i = 0; i < BUFFER_SIZE; i++){
        checksum += buffer[ptr];
        ptr++;
    }
 
    // 2's complement
    checksum = ~checksum + 1;
 
    return checksum;
}
 
unsigned char* getPacket(char* input, int srcCampus, int srcDept, int* validDept[3], int numOfValidDept[3]){
    int number = input[0] - '0';
    struct packet* p;
 
    if (number == 1 || number == 2){
        p = generateUnicastPacket(input, srcCampus, srcDept, validDept, numOfValidDept);
    }
    else if (number == 3 || number == 4){
        p = generateBroadcastPacket(input, srcCampus, srcDept, validDept, numOfValidDept);
    }
    else if (number == 5){
        p = generateControlPacket(input, srcCampus, srcDept, validDept, numOfValidDept);
    }
    else{
        return NULL;
    }
 
    unsigned char* buffer = (unsigned char*)malloc(sizeof(struct packet));
    buffer = serialize(p);
 
    return buffer;
}
 
unsigned char* generateUnicastPacket(char* input, int srcCampus, int srcDept, int* validDept[3], int numOfValidDept[3]){
    int number = input[0] - '0';
    
    int destCampus = -1, destDept = -1;
    char payload[BUFFER_SIZE];
    
    if (number == 1){
        sscanf(input, "%*[^.].%*[^:]:%*[^:]:%*[^\n]", NULL, &destCampus, &destDept, payload);
    }
    else if (number == 2) {
        sscanf(input, "%*[^.].%*[^:]:%*[^\n]", NULL, &destDept, payload);
    }
 
    // check if srcDept is valid for srcCampus
    bool found = false;
    for (int i = 0; i < numOfValidDept[srcCampus]; i++){
        if (validDept[srcCampus][i] == srcDept){
            found = true;
            break;
        }
    }
    if (!found){
        return NULL;
    }
 
    // check if destDept is valid for destCampus
    // if destCampus is -1, then is destDept valid for srcCampus
    found = false;
    if (destCampus != -1){
        for (int i = 0; i < numOfValidDept[destCampus]; i++){
            if (validDept[destCampus][i] == destDept){
                found = true;
                break;
            }
        }
    }
    else{
        for (int i = 0; i < numOfValidDept[srcCampus]; i++){
            if (validDept[srcCampus][i] == destDept){
                found = true;
                break;
            }
        }
    }
 
    if (!found){
        return NULL;
    }
 
    // set the packet
    struct packet* p = (struct packet*)malloc(sizeof(struct packet));
 
    // version
    p->version = 2;
 
    // header length
    if (destCampus == -1){
        //intra-campus
        p->headerLength = 5;
    }
    else{
        //inter-campus
        p->headerLength = 6;
    }
 
    // src and dest dept
    p->srcDept = srcDept;
    p->destDept = destDept;
 
    // src and dest campus
    p->srcCampus = srcCampus;
    if (p->headerLength == 5){
        //intra-campus
        p->destCampus = 0;
    }
    else{
        //inter-campus
        p->destCampus = destCampus;
    }
 
    // dont cares - hops, ack and type
    p->hops = 0;
    p->type = 0;
    p->ACK = 0;
 
    strcpy(p->data, payload);
 
    // total length
    p->totalLength = p->headerLength + strlen(p->data);
 
    // checksum
    // p->checkSum = checksumCalc(serialize(p)) & ((1 << 10) - 1);
 
    return serialize(p);
}
 
unsigned char* generateBroadcastPacket(char* input, int srcCampus, int srcDept, int* validDept[3], int numOfValidDept[3]){
    int number = input[0] - '0';
    
    char payload[BUFFER_SIZE];
    sscanf(input, "%*[^.].%*[^\n]", NULL, payload);
 
    // check if srcDept is valid for srcCampus
    bool found = false;
    for (int i = 0; i < numOfValidDept[srcCampus]; i++){
        if (validDept[srcCampus][i] == srcDept){
            found = true;
            break;
        }
    }
    if (!found){
        return NULL;
    }
 
    struct packet* p = (struct packet*)malloc(sizeof(struct packet));
    p->version = 2;
    
    if (number == 3){
        p->headerLength = 5;
    }
    else if (number == 4){
        p->headerLength = 6;
    }
 
    p->srcDept = srcDept;
    // p->destDept = 0;
 
    p->srcCampus = srcCampus;
    if (number == 3){
        p->destCampus = 0b111;
    }
    else if (number == 4){
        p->destCampus = 0b1111;
    }
 
    // dont cares - hops, ack and type
    p->hops = 0;
    p->type = 0;
    p->ACK = 0;
 
    strcpy(p->data, payload);
 
    // total length
    p->totalLength = p->headerLength + strlen(p->data);
 
    // checksum
    // p->checkSum = checksumCalc(serialize(p)) & ((1 << 10) - 1);
 
    return serialize(p);
}
 
unsigned char* generateControlPacket(char* input, int srcCampus, int srcDept, int* validDept[3], int numOfValidDept[3]){
    // check if srcDept is valid for srcCampus
    bool found = false;
    for (int i = 0; i < numOfValidDept[srcCampus]; i++){
        if (validDept[srcCampus][i] == srcDept){
            found = true;
            break;
        }
    }
    if (!found){
        return NULL;
    }
 
    struct packet* p = (struct packet*)malloc(sizeof(struct packet));
    // set the packet
 
    // version
    p->version = 2;
    
    // header length - DOUBT
    p->headerLength = 5;
 
    // src and dest dept - DOUBT
    p->srcDept = srcDept;
    p->destDept = 0;
 
    // src and dest campus - DOUBT
    p->srcCampus = srcCampus;
    p->destCampus = 0;
 
    // dont cares - hops, ack
    p->hops = 0;
    p->ACK = 0;
 
    // type
    if (strncmp(input + 2, "EXIT", 4) == 0){
        p->type = 1;
    }
    else if (strncmp(input + 2, "LIST", 4) == 0){
        p->type = 2;
    }
 
    // total length
    p->totalLength = p->headerLength + 4;
    
    // checksum
    // p->checkSum = checksumCalc(serialize(p)) & ((1 << 10) - 1);
 
    return serialize(p);
}
Editor is loading...
Leave a Comment