ATmega644 Smart-Card
Classes | Public Member Functions | Private Member Functions | Static Private Member Functions | Private Attributes | Static Private Attributes | List of all members
Communication Class Reference

Class that implements the communication protocol between the SmartCard & the Terminal. More...

#include <communication.h>

Collaboration diagram for Communication:
Collaboration graph

Classes

class  IOPin
 Class that provides functionality for the ATmega644's PinB6, such as an ISR. More...
 
class  Timer
 Class that provides functionality for the ATmega644's on-board 16-bit timer, such as an ISR. More...
 

Public Member Functions

 Communication ()
 Construct a new Communication object. More...
 
void sendATR ()
 Send the Answer-To-Reset sequence to the Terminal. More...
 
void receiveDataToDecrypt (byte_t *data)
 Receive data to decrypt from the Terminal. More...
 
void sendDecryptedData (const byte_t *data)
 Send the decrypted data to the Terminal. More...
 

Private Member Functions

void sendBit (const bit_t bit)
 Send a single bit to the Terminal. More...
 
void sendByte (const byte_t byte)
 Send a single byte to the Terminal. More...
 
void sendBytes (const byte_t *bytes, const uint8_t len)
 Send an array of bytes byte by byte. More...
 
byte_t receiveByte ()
 Receive a single byte from the Terminal. More...
 
void receiveProtocolHeader (const byte_t *header)
 Receive a protocol header, which contains 5 bytes. More...
 

Static Private Member Functions

static bit_t sampleBit ()
 Sample the IOPin 3-times for a more reliable result. More...
 
static bit_t getParity (byte_t byte)
 Calculate the parity of a byte. More...
 

Private Attributes

friend Timer
 16-bit Timer/Counter
 
friend IOPin
 IOPin (PinB6)
 
Logger mLog
 Logger.
 
volatile PinDir mDirection = PinDir::OUTPUT
 Current direction of the IOPin.
 
volatile bool mBitSent = true
 Whether the last bit of a transmission was sent.
 
volatile bit_t mOutputBit = 0
 The next bit to output.
 
volatile bool mByteReceived = 0
 Whether a byte was received successfully.
 
volatile uint8_t mInputBitCounter = 0
 Number of input bits in the current transfer.
 
volatile byte_t mInputByte = 0x00
 The currently received input byte.
 
volatile bool mCheckErrors = false
 Whether to check for errors after sending a byte.
 
volatile bit_t mErrorBit = 0
 Error bit that is set to 0/1 during the stop bit indicating failure/success.
 
volatile bool mParityError = false
 Whether a parity error occurred while receiving a byte.
 

Static Private Attributes

static constexpr bit_t START_BIT = 0
 The start bit of a transfer.
 
static constexpr bit_t STOP_BIT = 1
 The stop bit of a transfer.
 

Detailed Description

Class that implements the communication protocol between the SmartCard & the Terminal.

Authors
Philipp Karg (phili.nosp@m.pp.k.nosp@m.arg@t.nosp@m.um.d.nosp@m.e)
Date
05.06.2022

Constructor & Destructor Documentation

◆ Communication()

Communication::Communication ( )

Construct a new Communication object.

Initialize the Timer & IOPin class.

Member Function Documentation

◆ getParity()

static bit_t Communication::getParity ( byte_t  byte)
staticprivate

Calculate the parity of a byte.

Copied from https://stackoverflow.com/questions/21617970/how-to-check-if-value-has-even-parity-of-bits-or-odd.

Parameters
[in]byte( byte_t): Byte to calculate parity for.
Returns
( bit_t): The parity bit.

◆ receiveByte()

byte_t Communication::receiveByte ( )
private

Receive a single byte from the Terminal.

  1. Set the direction to input (IOPin::setDirection()) & enable interrupts for the IOPin (IOPin::setInterrupt()).
  2. Set mByteReceived to false & wait until it's true again.
Returns
( byte_t): The received byte

◆ receiveDataToDecrypt()

void Communication::receiveDataToDecrypt ( byte_t *  data)

Receive data to decrypt from the Terminal.

  1. Receive the protocol header, Protocol::DATA_IN_HEADER, by calling receiveProtocolHeader().
  2. Receive 16 bytes of data byte-by-byte & send Protocol::ACK_DATA_IN after each byte.
Parameters
[out]data( byte_t*): Byte array to store the received data in.

◆ receiveProtocolHeader()

void Communication::receiveProtocolHeader ( const byte_t *  header)
private

Receive a protocol header, which contains 5 bytes.

Parameters
[in]header(const byte_t*): Header to expect.

◆ sampleBit()

static bit_t Communication::sampleBit ( )
staticprivate

Sample the IOPin 3-times for a more reliable result.

Returns
(bit_t): The sample value of the bit.

◆ sendATR()

void Communication::sendATR ( )
inline

Send the Answer-To-Reset sequence to the Terminal.

After the Reset-Pin is set to 1, send this sequence to initiate the transfer.

◆ sendBit()

void Communication::sendBit ( const bit_t  bit)
private

Send a single bit to the Terminal.

  1. Wait for the last bit to be sent, (mBitSent to be true).
  2. Set mOutputBit to bit.
  3. Set mBitSent to false.
Parameters
[in]bit(const bit_t): The bit to send.

◆ sendByte()

void Communication::sendByte ( const byte_t  byte)
private

Send a single byte to the Terminal.

  1. Set the direction to output (IOPin::setDirection()) & disable interrupts for the IOPin (IOPin::setInterrupt()).
  2. Start the timer & set the match value to 1 Timer::ETU.
  3. Send the START_BIT.
  4. Send each bit of byte separately.
  5. Calculate the parity (getParity()) & send the parity bit.
  6. Send the STOP_BIT.
  7. After half an Timer::ETU, check if the IOPin is low, which indicates a parity error. If so, restart at 2.
Parameters
[in]byte(const byte_t): Byte to send.

◆ sendBytes()

void Communication::sendBytes ( const byte_t *  bytes,
const uint8_t  len 
)
inlineprivate

Send an array of bytes byte by byte.

Parameters
[in]bytes(const byte_t*): Array of bytes.
[in]len(const uint8_t): Length of the array.

◆ sendDecryptedData()

void Communication::sendDecryptedData ( const byte_t *  data)

Send the decrypted data to the Terminal.

  1. Indicate that the decryption is done by sending Protocol::RESPONSE_DECRYPTED.
  2. Receive the protocol header, Protocol::DATA_OUT_HEADER, by calling receiveProtocolHeader().
  3. Send Protocol::ACK_DATA_OUT.
  4. Send each decrypted byte consequentially.
  5. Indicate that the transfer of decrypted data is done, by sending Protocol::RESPONSE_DATA_OUT.
Parameters
[in]data(const byte_t*): Decrypted byte array to send to the Terminal.

The documentation for this class was generated from the following file: