ENEL400 / L2Frame

Dependents:   AlohaTransceiver

Committer:
rba90
Date:
Thu Jul 14 04:47:43 2016 +0000
Revision:
1:b714fce6e23b
Parent:
0:bd0c4fdc6833
Child:
2:849128cfddb8
Fix a bug where negative offset is given

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rba90 0:bd0c4fdc6833 1 #include "AlohaFrame.h"
rba90 0:bd0c4fdc6833 2 #include "crc.h"
rba90 0:bd0c4fdc6833 3 #include <string.h>
rba90 0:bd0c4fdc6833 4
rba90 0:bd0c4fdc6833 5 #ifdef _DEBUG
rba90 0:bd0c4fdc6833 6 #include <cassert>
rba90 0:bd0c4fdc6833 7 #endif
rba90 0:bd0c4fdc6833 8
rba90 0:bd0c4fdc6833 9 #define CRC_BASE_IDX 3
rba90 1:b714fce6e23b 10 #define FIXED_BYTE MAX_FRAME_SZ - MAX_PAYLOAD_SZ
rba90 0:bd0c4fdc6833 11
rba90 0:bd0c4fdc6833 12 AlohaFrame::AlohaFrame()
rba90 0:bd0c4fdc6833 13 {
rba90 0:bd0c4fdc6833 14 // init variables
rba90 0:bd0c4fdc6833 15 memset(_buffer, 0x0, sizeof(_buffer));
rba90 0:bd0c4fdc6833 16 _isVerified = false;
rba90 0:bd0c4fdc6833 17 }
rba90 0:bd0c4fdc6833 18
rba90 0:bd0c4fdc6833 19 AlohaFrame::AlohaFrame(uint8_t *data, uint8_t sz)
rba90 0:bd0c4fdc6833 20 {
rba90 0:bd0c4fdc6833 21 // the user takes the responsibility of making sure
rba90 0:bd0c4fdc6833 22 // they have sufficient memory for data buffer
rba90 0:bd0c4fdc6833 23
rba90 0:bd0c4fdc6833 24 // copy data to internal buffer
rba90 0:bd0c4fdc6833 25 memcpy(_buffer, data, sz);
rba90 0:bd0c4fdc6833 26
rba90 0:bd0c4fdc6833 27 // set verify flag
rba90 0:bd0c4fdc6833 28 _isVerified = false;
rba90 0:bd0c4fdc6833 29 }
rba90 0:bd0c4fdc6833 30
rba90 0:bd0c4fdc6833 31
rba90 0:bd0c4fdc6833 32 AlohaFrame::~AlohaFrame()
rba90 0:bd0c4fdc6833 33 {
rba90 0:bd0c4fdc6833 34 }
rba90 0:bd0c4fdc6833 35
rba90 0:bd0c4fdc6833 36 void AlohaFrame::generateCrc()
rba90 0:bd0c4fdc6833 37 {
rba90 0:bd0c4fdc6833 38 uint8_t crc_idx = CRC_BASE_IDX + getPayloadLength();
rba90 0:bd0c4fdc6833 39
rba90 0:bd0c4fdc6833 40 _buffer[crc_idx] = crc8(_buffer, crc_idx);
rba90 0:bd0c4fdc6833 41
rba90 0:bd0c4fdc6833 42 // set verify flag
rba90 0:bd0c4fdc6833 43 _isVerified = true;
rba90 0:bd0c4fdc6833 44 }
rba90 0:bd0c4fdc6833 45
rba90 0:bd0c4fdc6833 46 bool AlohaFrame::verify()
rba90 0:bd0c4fdc6833 47 {
rba90 0:bd0c4fdc6833 48 uint8_t crc_idx = CRC_BASE_IDX + getPayloadLength();
rba90 0:bd0c4fdc6833 49
rba90 0:bd0c4fdc6833 50 if (_isVerified)
rba90 0:bd0c4fdc6833 51 {
rba90 0:bd0c4fdc6833 52 return true;
rba90 0:bd0c4fdc6833 53 }
rba90 0:bd0c4fdc6833 54 else
rba90 0:bd0c4fdc6833 55 {
rba90 0:bd0c4fdc6833 56 return _buffer[crc_idx] == crc8(_buffer, crc_idx);
rba90 0:bd0c4fdc6833 57 }
rba90 0:bd0c4fdc6833 58 }
rba90 0:bd0c4fdc6833 59
rba90 0:bd0c4fdc6833 60 uint8_t AlohaFrame::serialize(uint8_t *buffer)
rba90 0:bd0c4fdc6833 61 {
rba90 0:bd0c4fdc6833 62 uint8_t total_length = FIXED_BYTE + getPayloadLength();
rba90 0:bd0c4fdc6833 63
rba90 0:bd0c4fdc6833 64 memcpy(buffer, _buffer, total_length);
rba90 0:bd0c4fdc6833 65
rba90 0:bd0c4fdc6833 66 return total_length;
rba90 0:bd0c4fdc6833 67 }
rba90 0:bd0c4fdc6833 68
rba90 0:bd0c4fdc6833 69 void AlohaFrame::setType(uint8_t type)
rba90 0:bd0c4fdc6833 70 {
rba90 0:bd0c4fdc6833 71 // clear upper 4 bits
rba90 0:bd0c4fdc6833 72 _buffer[0] &= 0x0f;
rba90 0:bd0c4fdc6833 73
rba90 0:bd0c4fdc6833 74 // set bits
rba90 0:bd0c4fdc6833 75 _buffer[0] |= type << 4;
rba90 0:bd0c4fdc6833 76
rba90 0:bd0c4fdc6833 77 // set verify flag
rba90 0:bd0c4fdc6833 78 _isVerified = false;
rba90 0:bd0c4fdc6833 79 }
rba90 0:bd0c4fdc6833 80
rba90 0:bd0c4fdc6833 81 void AlohaFrame::setPayloadLength(uint8_t length)
rba90 0:bd0c4fdc6833 82 {
rba90 0:bd0c4fdc6833 83 // clear lower 4 bits
rba90 0:bd0c4fdc6833 84 _buffer[0] &= 0xf0;
rba90 0:bd0c4fdc6833 85
rba90 0:bd0c4fdc6833 86 // set bits
rba90 0:bd0c4fdc6833 87 _buffer[0] |= length & 0x0f;
rba90 0:bd0c4fdc6833 88
rba90 0:bd0c4fdc6833 89 // set verify flag
rba90 0:bd0c4fdc6833 90 _isVerified = false;
rba90 0:bd0c4fdc6833 91 }
rba90 0:bd0c4fdc6833 92
rba90 0:bd0c4fdc6833 93 void AlohaFrame::setSourceAddress(uint8_t sa)
rba90 0:bd0c4fdc6833 94 {
rba90 0:bd0c4fdc6833 95 // clear upper 4 bits
rba90 0:bd0c4fdc6833 96 _buffer[1] &= 0x0f;
rba90 0:bd0c4fdc6833 97
rba90 0:bd0c4fdc6833 98 // set bits
rba90 0:bd0c4fdc6833 99 _buffer[1] |= sa << 4;
rba90 0:bd0c4fdc6833 100
rba90 0:bd0c4fdc6833 101 // set verify flag
rba90 0:bd0c4fdc6833 102 _isVerified = false;
rba90 0:bd0c4fdc6833 103 }
rba90 0:bd0c4fdc6833 104
rba90 0:bd0c4fdc6833 105 void AlohaFrame::setDestinationAddress(uint8_t da)
rba90 0:bd0c4fdc6833 106 {
rba90 0:bd0c4fdc6833 107 // clear lower 4 bits
rba90 0:bd0c4fdc6833 108 _buffer[1] &= 0xf0;
rba90 0:bd0c4fdc6833 109
rba90 0:bd0c4fdc6833 110 // set bits
rba90 0:bd0c4fdc6833 111 _buffer[1] |= da & 0x0f;
rba90 0:bd0c4fdc6833 112
rba90 0:bd0c4fdc6833 113 // set verify flag
rba90 0:bd0c4fdc6833 114 _isVerified = false;
rba90 0:bd0c4fdc6833 115 }
rba90 0:bd0c4fdc6833 116
rba90 0:bd0c4fdc6833 117 void AlohaFrame::setFullMessageFlag(uint8_t fmf)
rba90 0:bd0c4fdc6833 118 {
rba90 0:bd0c4fdc6833 119 // clear upper 1 bits
rba90 0:bd0c4fdc6833 120 _buffer[2] &= 0x7f;
rba90 0:bd0c4fdc6833 121
rba90 0:bd0c4fdc6833 122 // set bits
rba90 0:bd0c4fdc6833 123 _buffer[2] |= fmf << 7;
rba90 0:bd0c4fdc6833 124
rba90 0:bd0c4fdc6833 125 // set verify flag
rba90 0:bd0c4fdc6833 126 _isVerified = false;
rba90 0:bd0c4fdc6833 127 }
rba90 0:bd0c4fdc6833 128
rba90 0:bd0c4fdc6833 129 void AlohaFrame::setSequenceID(uint8_t seqid)
rba90 0:bd0c4fdc6833 130 {
rba90 0:bd0c4fdc6833 131 // clear lower 7 bits
rba90 0:bd0c4fdc6833 132 _buffer[2] &= 0x80;
rba90 0:bd0c4fdc6833 133
rba90 0:bd0c4fdc6833 134 // set bits
rba90 0:bd0c4fdc6833 135 _buffer[2] |= seqid & 0x7f;
rba90 0:bd0c4fdc6833 136
rba90 0:bd0c4fdc6833 137 // set verify flag
rba90 0:bd0c4fdc6833 138 _isVerified = false;
rba90 0:bd0c4fdc6833 139 }
rba90 0:bd0c4fdc6833 140
rba90 0:bd0c4fdc6833 141 void AlohaFrame::setPayload(uint8_t payload, uint8_t idx)
rba90 0:bd0c4fdc6833 142 {
rba90 0:bd0c4fdc6833 143 // set payload based on index
rba90 0:bd0c4fdc6833 144 _buffer[CRC_BASE_IDX + idx] = payload;
rba90 0:bd0c4fdc6833 145
rba90 0:bd0c4fdc6833 146 // set verify flag
rba90 0:bd0c4fdc6833 147 _isVerified = false;
rba90 0:bd0c4fdc6833 148 }
rba90 0:bd0c4fdc6833 149
rba90 0:bd0c4fdc6833 150 uint8_t AlohaFrame::getType()
rba90 0:bd0c4fdc6833 151 {
rba90 0:bd0c4fdc6833 152 return (_buffer[0] & 0xf0) >> 4;
rba90 0:bd0c4fdc6833 153 }
rba90 0:bd0c4fdc6833 154
rba90 0:bd0c4fdc6833 155 uint8_t AlohaFrame::getPayloadLength()
rba90 0:bd0c4fdc6833 156 {
rba90 0:bd0c4fdc6833 157 return _buffer[0] & 0x0f;
rba90 0:bd0c4fdc6833 158 }
rba90 0:bd0c4fdc6833 159
rba90 0:bd0c4fdc6833 160 uint8_t AlohaFrame::getSourceAddress()
rba90 0:bd0c4fdc6833 161 {
rba90 0:bd0c4fdc6833 162 return (_buffer[1] & 0xf0) >> 4;
rba90 0:bd0c4fdc6833 163 }
rba90 0:bd0c4fdc6833 164
rba90 0:bd0c4fdc6833 165 uint8_t AlohaFrame::getDestinationAddress()
rba90 0:bd0c4fdc6833 166 {
rba90 0:bd0c4fdc6833 167 return _buffer[1] & 0x0f;
rba90 0:bd0c4fdc6833 168 }
rba90 0:bd0c4fdc6833 169
rba90 0:bd0c4fdc6833 170 uint8_t AlohaFrame::getFullMessageFlag()
rba90 0:bd0c4fdc6833 171 {
rba90 0:bd0c4fdc6833 172 return (_buffer[2] & 0x80) >> 7;
rba90 0:bd0c4fdc6833 173 }
rba90 0:bd0c4fdc6833 174
rba90 0:bd0c4fdc6833 175 uint8_t AlohaFrame::getSequenceID()
rba90 0:bd0c4fdc6833 176 {
rba90 0:bd0c4fdc6833 177 return _buffer[2] & 0x7f;
rba90 0:bd0c4fdc6833 178 }
rba90 0:bd0c4fdc6833 179
rba90 0:bd0c4fdc6833 180 uint8_t AlohaFrame::getPayload(uint8_t idx)
rba90 0:bd0c4fdc6833 181 {
rba90 0:bd0c4fdc6833 182 return _buffer[CRC_BASE_IDX + idx];
rba90 0:bd0c4fdc6833 183 }
rba90 0:bd0c4fdc6833 184
rba90 0:bd0c4fdc6833 185 uint8_t AlohaFrame::getCrc()
rba90 0:bd0c4fdc6833 186 {
rba90 0:bd0c4fdc6833 187 uint8_t crc_idx = CRC_BASE_IDX + getPayloadLength();
rba90 0:bd0c4fdc6833 188
rba90 0:bd0c4fdc6833 189 if (_isVerified)
rba90 0:bd0c4fdc6833 190 {
rba90 0:bd0c4fdc6833 191 return _buffer[crc_idx];
rba90 0:bd0c4fdc6833 192 }
rba90 0:bd0c4fdc6833 193 else
rba90 0:bd0c4fdc6833 194 {
rba90 0:bd0c4fdc6833 195 return crc8(_buffer, crc_idx);
rba90 0:bd0c4fdc6833 196 }
rba90 0:bd0c4fdc6833 197 }
rba90 0:bd0c4fdc6833 198
rba90 0:bd0c4fdc6833 199 #ifdef _DEBUG
rba90 0:bd0c4fdc6833 200 void AlohaFrame::unit_test()
rba90 0:bd0c4fdc6833 201 {
rba90 0:bd0c4fdc6833 202 // value test
rba90 0:bd0c4fdc6833 203 AlohaFrame testObject;
rba90 0:bd0c4fdc6833 204
rba90 0:bd0c4fdc6833 205 testObject.setType(0x0);
rba90 0:bd0c4fdc6833 206 testObject.setPayloadLength(0x3);
rba90 0:bd0c4fdc6833 207 testObject.setSourceAddress(0x2);
rba90 0:bd0c4fdc6833 208 testObject.setDestinationAddress(0x3);
rba90 0:bd0c4fdc6833 209 testObject.setFullMessageFlag(0x1);
rba90 0:bd0c4fdc6833 210 testObject.setSequenceID(0x4);
rba90 0:bd0c4fdc6833 211 testObject.setPayload(0x56, 0);
rba90 0:bd0c4fdc6833 212 testObject.setPayload(0x67, 1);
rba90 0:bd0c4fdc6833 213 testObject.setPayload(0x89, 2);
rba90 0:bd0c4fdc6833 214
rba90 0:bd0c4fdc6833 215 assert(0x0 == testObject.getType());
rba90 0:bd0c4fdc6833 216 assert(0x3 == testObject.getPayloadLength());
rba90 0:bd0c4fdc6833 217 assert(0x2 == testObject.getSourceAddress());
rba90 0:bd0c4fdc6833 218 assert(0x3 == testObject.getDestinationAddress());
rba90 0:bd0c4fdc6833 219 assert(0x1 == testObject.getFullMessageFlag());
rba90 0:bd0c4fdc6833 220 assert(0x4 == testObject.getSequenceID());
rba90 0:bd0c4fdc6833 221 assert(0x56 == testObject.getPayload(0));
rba90 0:bd0c4fdc6833 222 assert(0x67 == testObject.getPayload(1));
rba90 0:bd0c4fdc6833 223 assert(0x89 == testObject.getPayload(2));
rba90 0:bd0c4fdc6833 224
rba90 0:bd0c4fdc6833 225 assert(false == testObject.verify());
rba90 0:bd0c4fdc6833 226 testObject.generateCrc();
rba90 0:bd0c4fdc6833 227 assert(true == testObject.verify());
rba90 0:bd0c4fdc6833 228 assert(0xa1 == testObject.getCrc());
rba90 0:bd0c4fdc6833 229
rba90 0:bd0c4fdc6833 230 // value test round 2
rba90 0:bd0c4fdc6833 231 uint8_t testString[] = { 0x03, 0x23, 0x84, 0x56, 0x67, 0x89, 0xa1 };
rba90 0:bd0c4fdc6833 232 AlohaFrame testObject2(testString, 7);
rba90 0:bd0c4fdc6833 233
rba90 0:bd0c4fdc6833 234 assert(0x0 == testObject2.getType());
rba90 0:bd0c4fdc6833 235 assert(0x3 == testObject2.getPayloadLength());
rba90 0:bd0c4fdc6833 236 assert(0x2 == testObject2.getSourceAddress());
rba90 0:bd0c4fdc6833 237 assert(0x3 == testObject2.getDestinationAddress());
rba90 0:bd0c4fdc6833 238 assert(0x1 == testObject2.getFullMessageFlag());
rba90 0:bd0c4fdc6833 239 assert(0x4 == testObject2.getSequenceID());
rba90 0:bd0c4fdc6833 240 assert(0x56 == testObject2.getPayload(0));
rba90 0:bd0c4fdc6833 241 assert(0x67 == testObject2.getPayload(1));
rba90 0:bd0c4fdc6833 242 assert(0x89 == testObject2.getPayload(2));
rba90 0:bd0c4fdc6833 243
rba90 0:bd0c4fdc6833 244 assert(true == testObject2.verify());
rba90 0:bd0c4fdc6833 245 testObject2.generateCrc();
rba90 0:bd0c4fdc6833 246 assert(true == testObject2.verify());
rba90 0:bd0c4fdc6833 247 assert(0xa1 == testObject2.getCrc());
rba90 0:bd0c4fdc6833 248 }
rba90 0:bd0c4fdc6833 249 #endif