You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
278 lines
8.8 KiB
278 lines
8.8 KiB
/******************************************************************************
|
|
*
|
|
* Copyright (C) 2018 ST Microelectronics S.A.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at:
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*
|
|
*
|
|
******************************************************************************/
|
|
|
|
#include "Tpdu.h"
|
|
|
|
#include "Iso13239CRC.h"
|
|
|
|
/*******************************************************************************
|
|
**
|
|
** Function Tpdu_toByteArray
|
|
**
|
|
** Description Forms a byte array representing the given TPDU.
|
|
**
|
|
** Parameters structTpdu - TPDU struct to be converted to byte array.
|
|
** baTpdu - Memory position where to store the formed
|
|
** byte array.
|
|
**
|
|
** Returns length of the formed array, -1 if there is an error.
|
|
**
|
|
*******************************************************************************/
|
|
uint16_t Tpdu_toByteArray(Tpdu *structTpdu, uint8_t *baTpdu) {
|
|
// NAD - Copy the nad into the nad array position
|
|
baTpdu[NAD_OFFSET_IN_TPDU] = structTpdu->nad;
|
|
|
|
// PCB - Copy the pcb into the pcb array position
|
|
baTpdu[PCB_OFFSET_IN_TPDU] = structTpdu->pcb;
|
|
|
|
// Length - Copy the length into the length array position
|
|
baTpdu[LEN_OFFSET_IN_TPDU] = structTpdu->len;
|
|
|
|
// Data - Copy the data into the data array position
|
|
uint8_t i;
|
|
for (i = 0; i < structTpdu->len; i++) {
|
|
baTpdu[DATA_OFFSET_IN_TPDU + i] = structTpdu->data[i];
|
|
}
|
|
|
|
// Compute where the checksum shall be stored.
|
|
uint16_t checksumOffsetInTpdu = DATA_OFFSET_IN_TPDU + structTpdu->len;
|
|
|
|
uint16_t length;
|
|
uint8_t checksum[2];
|
|
switch (ATP.checksumType) {
|
|
case LRC:
|
|
Tpdu_getChecksumBytes(structTpdu, checksum);
|
|
baTpdu[checksumOffsetInTpdu] = checksum[0];
|
|
length = checksumOffsetInTpdu + 1;
|
|
break;
|
|
case CRC:
|
|
default:
|
|
Tpdu_getChecksumBytes(structTpdu, checksum);
|
|
baTpdu[checksumOffsetInTpdu] = checksum[0];
|
|
baTpdu[checksumOffsetInTpdu + 1] = checksum[1];
|
|
length = checksumOffsetInTpdu + 2;
|
|
break;
|
|
}
|
|
|
|
return length;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
**
|
|
** Function Tpdu_isChecksumOk
|
|
**
|
|
** Description Checks that the checksum in the TPDU is as expected.
|
|
**
|
|
** Parameters tpdu - TPDU whose checksum needs to be checked.
|
|
**
|
|
** Returns true if checksum is ok, false otherwise.
|
|
**
|
|
*******************************************************************************/
|
|
bool Tpdu_isChecksumOk(Tpdu *tpdu) {
|
|
switch (ATP.checksumType) {
|
|
case LRC:
|
|
// TODO: implement
|
|
return false;
|
|
case CRC:;
|
|
uint8_t buffer[TPDU_MAX_LENGTH];
|
|
Tpdu_toByteArray(tpdu, buffer);
|
|
if (tpdu->checksum ==
|
|
computeCrc(buffer, (TPDU_PROLOGUE_LENGTH + tpdu->len))) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*******************************************************************************
|
|
**
|
|
** Function Tpdu_formTpdu
|
|
**
|
|
** Description Forms a TPDU with the specified fields.
|
|
**
|
|
** Parameters nad - NAD byte of the TPDU.
|
|
** pcb - PCB byte of the TPDU.
|
|
** len - Length of the data
|
|
** data - data of the TPDU
|
|
** tpdu - output TPDU struct
|
|
**
|
|
** Returns 0 if everything went ok, -1 otherwise.
|
|
**
|
|
*******************************************************************************/
|
|
int Tpdu_formTpdu(uint8_t nad, uint8_t pcb, uint8_t len, uint8_t *data,
|
|
Tpdu *tpdu) {
|
|
uint8_t i;
|
|
|
|
if (len > TPDU_MAX_DATA_LENGTH) {
|
|
return -1;
|
|
}
|
|
// NAD - Copy the incoming nad into the tpdu nad
|
|
tpdu->nad = nad;
|
|
// PCB - Copy the incoming pcb into the tpdu pcb
|
|
tpdu->pcb = pcb;
|
|
// Length - Copy the incoming len into the tpdu len
|
|
tpdu->len = len;
|
|
|
|
// Data - Copy the incoming data into the tpdu data
|
|
// TODO: check if it will ever be overwritten
|
|
for (i = 0; i < len; i++) {
|
|
tpdu->data[i] = data[i];
|
|
}
|
|
// tpdu->data = data;
|
|
// Checksum - Calculate the checksum according to the prologue + data fields
|
|
// and copy into the tpdu checksum
|
|
switch (ATP.checksumType) {
|
|
case LRC:
|
|
// TODO: implement
|
|
return -1;
|
|
case CRC:
|
|
// Set temporally checksum to 0 to be able to convert the tpdu struct
|
|
// to an array
|
|
tpdu->checksum = 0;
|
|
|
|
// Create a buffer to store the tpdu to compute the CRC.
|
|
uint8_t buffer[TPDU_MAX_LENGTH];
|
|
Tpdu_toByteArray(tpdu, buffer);
|
|
|
|
// Calculate the crc
|
|
tpdu->checksum = computeCrc(buffer, (TPDU_PROLOGUE_LENGTH + tpdu->len));
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
**
|
|
** Function Tpdu_getChecksumBytes
|
|
**
|
|
** Description Get the checksum value in the form of a byte array.
|
|
**
|
|
** Parameters tpdu - TPDU from where to get the checksum value.
|
|
** checksumBytes - mem postion whre to store the result.
|
|
**
|
|
** Returns void
|
|
**
|
|
*******************************************************************************/
|
|
void Tpdu_getChecksumBytes(Tpdu *tpdu, uint8_t *checksumBytes) {
|
|
switch (ATP.checksumType) {
|
|
case LRC:
|
|
checksumBytes[0] = (uint8_t)tpdu->checksum;
|
|
break;
|
|
case CRC:
|
|
checksumBytes[0] = (uint8_t)tpdu->checksum;
|
|
checksumBytes[1] = (uint8_t)(tpdu->checksum >> 8);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*******************************************************************************
|
|
**
|
|
** Function Tpdu_getChecksumValue
|
|
**
|
|
** Description Gets the value of the checksum stored in the array.
|
|
**
|
|
** Parameters array - array that contains the checksum.
|
|
** checksumStartPosition
|
|
** checksumType -Checksum type (LRC or CRC)
|
|
**
|
|
** Returns checksum value
|
|
**
|
|
*******************************************************************************/
|
|
uint16_t Tpdu_getChecksumValue(uint8_t *array, int checksumStartPosition,
|
|
ChecksumType checksumType) {
|
|
switch (checksumType) {
|
|
case LRC:
|
|
return (uint16_t)array[checksumStartPosition];
|
|
case CRC:
|
|
return (uint16_t)(array[checksumStartPosition + 1] << 8) |
|
|
array[checksumStartPosition];
|
|
}
|
|
}
|
|
|
|
/*******************************************************************************
|
|
**
|
|
** Function Tpdu_getType
|
|
**
|
|
** Description Returns the type of the TPDU.
|
|
**
|
|
** Parameters tpdu - the tpdu the type has to be get.
|
|
**
|
|
** Returns TPDU type (I-Block, R-Block or S-Block)
|
|
**
|
|
*******************************************************************************/
|
|
TpduType Tpdu_getType(Tpdu *tpdu) {
|
|
if ((tpdu->pcb & 0x80) == 0x00) {
|
|
return IBlock;
|
|
} else if ((tpdu->pcb & 0xC0) == 0x80) {
|
|
return RBlock;
|
|
} else {
|
|
return SBlock;
|
|
}
|
|
}
|
|
|
|
/*******************************************************************************
|
|
**
|
|
** Function Tpdu_copy
|
|
**
|
|
** Description Copy a Tpdu Struct to an another one.
|
|
**
|
|
** Parameters dest - the destination tpdu
|
|
** src - the tpdu to be copied
|
|
**
|
|
** Returns void
|
|
**
|
|
*******************************************************************************/
|
|
void Tpdu_copy(Tpdu *dest, Tpdu *src) {
|
|
dest->checksum = src->checksum;
|
|
dest->len = src->len;
|
|
dest->nad = src->nad;
|
|
dest->pcb = src->pcb;
|
|
if (dest->data == NULL) {
|
|
dest->data = (uint8_t *)malloc(ATP.ifsc * sizeof(uint8_t));
|
|
}
|
|
if (((src->len) > 0) && ((src->len) < ATP.ifsc)) {
|
|
memcpy(dest->data, src->data, src->len);
|
|
}
|
|
}
|
|
|
|
/*******************************************************************************
|
|
**
|
|
** Function Tpdu_toHexString
|
|
**
|
|
** Description Converts the TPDU in hex string buffer.
|
|
**
|
|
** Parameters tpdu - input tpdu
|
|
** hexStringBuffer - output hex buffer
|
|
**
|
|
**
|
|
** Returns void
|
|
**
|
|
*******************************************************************************/
|
|
void Tpdu_toHexString(Tpdu *tpdu, uint8_t *hexStringBuffer) {
|
|
uint8_t buffer[tpdu->len + 5];
|
|
uint16_t length = Tpdu_toByteArray(tpdu, buffer);
|
|
char *ptr = (char *)hexStringBuffer;
|
|
int i;
|
|
for (i = 0; i < length; i++) {
|
|
ptr += sprintf(ptr, "%02X ", (char)buffer[i]);
|
|
}
|
|
}
|