ENEL400 / L2Frame

Dependents:   AlohaTransceiver

AlohaFrame.cpp

Committer:
rba90
Date:
2016-07-14
Revision:
1:b714fce6e23b
Parent:
0:bd0c4fdc6833
Child:
2:849128cfddb8

File content as of revision 1:b714fce6e23b:

#include "AlohaFrame.h"
#include "crc.h"
#include <string.h>

#ifdef _DEBUG
#include <cassert>
#endif

#define CRC_BASE_IDX 3
#define FIXED_BYTE MAX_FRAME_SZ - MAX_PAYLOAD_SZ

AlohaFrame::AlohaFrame()
{
    // init variables
    memset(_buffer, 0x0, sizeof(_buffer));
    _isVerified = false;
}

AlohaFrame::AlohaFrame(uint8_t *data, uint8_t sz)
{
    // the user takes the responsibility of making sure
    // they have sufficient memory for data buffer

    // copy data to internal buffer
    memcpy(_buffer, data, sz);

    // set verify flag
    _isVerified = false;
}


AlohaFrame::~AlohaFrame()
{
}

void AlohaFrame::generateCrc()
{
    uint8_t crc_idx = CRC_BASE_IDX + getPayloadLength();

    _buffer[crc_idx] = crc8(_buffer, crc_idx);

    // set verify flag
    _isVerified = true;
}

bool AlohaFrame::verify()
{
    uint8_t crc_idx = CRC_BASE_IDX + getPayloadLength();

    if (_isVerified)
    {
        return true;
    }
    else
    {
        return _buffer[crc_idx] == crc8(_buffer, crc_idx);
    }
}   

uint8_t AlohaFrame::serialize(uint8_t *buffer)
{
    uint8_t total_length = FIXED_BYTE + getPayloadLength();

    memcpy(buffer, _buffer, total_length);

    return total_length;
}

void AlohaFrame::setType(uint8_t type)
{
    // clear upper 4 bits
    _buffer[0] &= 0x0f;

    // set bits
    _buffer[0] |= type << 4;

    // set verify flag
    _isVerified = false;
}

void AlohaFrame::setPayloadLength(uint8_t length)
{
    // clear lower 4 bits
    _buffer[0] &= 0xf0;

    // set bits
    _buffer[0] |= length & 0x0f;

    // set verify flag
    _isVerified = false;
}

void AlohaFrame::setSourceAddress(uint8_t sa)
{
    // clear upper 4 bits
    _buffer[1] &= 0x0f;

    // set bits
    _buffer[1] |= sa << 4;

    // set verify flag
    _isVerified = false;
}

void AlohaFrame::setDestinationAddress(uint8_t da)
{
    // clear lower 4 bits
    _buffer[1] &= 0xf0;

    // set bits
    _buffer[1] |= da & 0x0f;

    // set verify flag
    _isVerified = false;
}

void AlohaFrame::setFullMessageFlag(uint8_t fmf)
{
    // clear upper 1 bits
    _buffer[2] &= 0x7f;

    // set bits
    _buffer[2] |= fmf << 7;

    // set verify flag
    _isVerified = false;
}

void AlohaFrame::setSequenceID(uint8_t seqid)
{
    // clear lower 7 bits
    _buffer[2] &= 0x80;

    // set bits
    _buffer[2] |= seqid & 0x7f;

    // set verify flag
    _isVerified = false;
}

void AlohaFrame::setPayload(uint8_t payload, uint8_t idx)
{
    // set payload based on index
    _buffer[CRC_BASE_IDX + idx] = payload;

    // set verify flag
    _isVerified = false;
}

uint8_t AlohaFrame::getType()
{
    return (_buffer[0] & 0xf0) >> 4;
}

uint8_t AlohaFrame::getPayloadLength()
{
    return _buffer[0] & 0x0f;
}

uint8_t AlohaFrame::getSourceAddress()
{
    return (_buffer[1] & 0xf0) >> 4;
}

uint8_t AlohaFrame::getDestinationAddress()
{
    return _buffer[1] & 0x0f;
}

uint8_t AlohaFrame::getFullMessageFlag()
{
    return (_buffer[2] & 0x80) >> 7;
}

uint8_t AlohaFrame::getSequenceID()
{
    return _buffer[2] & 0x7f;
}

uint8_t AlohaFrame::getPayload(uint8_t idx)
{
    return _buffer[CRC_BASE_IDX + idx];
}

uint8_t AlohaFrame::getCrc()
{
    uint8_t crc_idx = CRC_BASE_IDX + getPayloadLength();

    if (_isVerified)
    {
        return _buffer[crc_idx];
    }
    else
    {
        return crc8(_buffer, crc_idx);
    }
}

#ifdef _DEBUG
void AlohaFrame::unit_test()
{
    // value test
    AlohaFrame testObject;

    testObject.setType(0x0);
    testObject.setPayloadLength(0x3);
    testObject.setSourceAddress(0x2);
    testObject.setDestinationAddress(0x3);
    testObject.setFullMessageFlag(0x1);
    testObject.setSequenceID(0x4);
    testObject.setPayload(0x56, 0);
    testObject.setPayload(0x67, 1);
    testObject.setPayload(0x89, 2);

    assert(0x0 == testObject.getType());
    assert(0x3 == testObject.getPayloadLength());
    assert(0x2 == testObject.getSourceAddress());
    assert(0x3 == testObject.getDestinationAddress());
    assert(0x1 == testObject.getFullMessageFlag());
    assert(0x4 == testObject.getSequenceID());
    assert(0x56 == testObject.getPayload(0));
    assert(0x67 == testObject.getPayload(1));
    assert(0x89 == testObject.getPayload(2));

    assert(false == testObject.verify());
    testObject.generateCrc();
    assert(true == testObject.verify());
    assert(0xa1 == testObject.getCrc());

    // value test round 2
    uint8_t testString[] = { 0x03, 0x23, 0x84, 0x56, 0x67, 0x89, 0xa1 };
    AlohaFrame testObject2(testString, 7);
    
    assert(0x0 == testObject2.getType());
    assert(0x3 == testObject2.getPayloadLength());
    assert(0x2 == testObject2.getSourceAddress());
    assert(0x3 == testObject2.getDestinationAddress());
    assert(0x1 == testObject2.getFullMessageFlag());
    assert(0x4 == testObject2.getSequenceID());
    assert(0x56 == testObject2.getPayload(0));
    assert(0x67 == testObject2.getPayload(1));
    assert(0x89 == testObject2.getPayload(2));

    assert(true == testObject2.verify());
    testObject2.generateCrc();
    assert(true == testObject2.verify());
    assert(0xa1 == testObject2.getCrc());
}
#endif