[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-taler-mdb] 01/23: Added mdb communication module
From: |
gnunet |
Subject: |
[taler-taler-mdb] 01/23: Added mdb communication module |
Date: |
Wed, 04 Dec 2019 14:15:47 +0100 |
This is an automated email from the git hooks/post-receive script.
grothoff pushed a commit to branch master
in repository taler-mdb.
commit b1fd9e82edbd8b1a04ea25388a6ce28f00742445
Author: Dominik Hofer <address@hidden>
AuthorDate: Fri Nov 29 13:46:42 2019 +0100
Added mdb communication module
---
src/mdb/mdb_uart.c | 344 +++++++++++++++++++++++++++++++++++++++++++++++++++++
src/mdb/mdb_uart.h | 82 +++++++++++++
2 files changed, 426 insertions(+)
diff --git a/src/mdb/mdb_uart.c b/src/mdb/mdb_uart.c
new file mode 100644
index 0000000..00e6278
--- /dev/null
+++ b/src/mdb/mdb_uart.c
@@ -0,0 +1,344 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2014 GNUnet e.V.
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more
+details.
+
+ You should have received a copy of the GNU General Public License
+along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+*/
+
+/**
+ * @file mdb_uart.c
+ * @brief Functions for communication via the mdb bus with the VMC
+ * @author Dominik Hofer <address@hidden>
+ */
+
+#include "mdb_uart.h"
+
+int
+mdbUart_init(void)
+{
+ int uart0_filestream = -1;
+ struct termios options;
+
+ //Open Uart
+ uart0_filestream = open("/dev/ttyAMA0", O_RDWR | O_NOCTTY | O_NDELAY);
+ printf("File Descriptor: %d\n", uart0_filestream);
+
+ if(uart0_filestream < 0){
+ printf("Error - cannot open UART Device\n");
+ }
+ else{
+ fcntl(uart0_filestream, F_SETFL, 0);
+ if(tcgetattr(uart0_filestream, &options) != 0){
+ printf("Error - Cannot get current UART configuration\n");
+ return -1;
+ }
+
+ memset(&options, 0, sizeof(options)); /* Structur loeschen, ggf.
vorher sichern
+ und bei Programmende wieder
restaurieren */
+ /* Baudrate setzen */
+ cfsetispeed(&options, B9600);
+ cfsetospeed(&options, B9600);
+
+ /* setze Optionen */
+ options.c_cflag &= ~PARENB; /* kein Paritybit */
+ options.c_cflag &= ~CSTOPB; /* 1 Stoppbit */
+ options.c_cflag &= ~CSIZE; /* 8 Datenbits */
+ options.c_cflag |= CS8;
+
+ /* 19200 bps, 8 Datenbits, CD-Signal ignorieren, Lesen erlauben */
+ options.c_cflag |= (CLOCAL | CREAD);
+
+ /* Kein Echo, keine Steuerzeichen, keine Interrupts */
+ options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
+ options.c_iflag = IGNPAR; /* Parity-Fehler ignorieren */
+ options.c_oflag &= ~OPOST; /* setze "raw" Input */
+ options.c_cc[VMIN] = 14; /* warten auf min. 0 Zeichen */
+ options.c_cc[VTIME] = 10; /* Timeout 1 Sekunde */
+ tcflush(uart0_filestream,TCIOFLUSH); /* Puffer leeren */
+ if(tcsetattr(uart0_filestream, TCSAFLUSH, &options) != 0){
+ printf("Error - Cannot configurate UART device\n");
+ return(-1);
+ }
+ }
+
+ return uart0_filestream;
+}
+
+int
+uart_close(int filestream)
+{
+
+ return close(filestream);
+}
+
+int
+mdb_init(int filestream)
+{
+ mdbCmd *readerConfigData;
+
+
+ readerConfigData = newMdbCmd("Reader Config", "0101", "19780A02FF0C");
+
+ while(1){
+ sendMdbCmd(readerConfigData, filestream);
+ receivedMdbCmd = receiveMdbCmd(filestream);
+ if(receivedMdbCmd){
+ if(strcmp("Reader Enable",
receivedMdbCmd) == 0){
+ break;
+ }
+ else{
+ free(receivedMdbCmd);
+ }
+ }
+ }
+
+ free(receivedMdbCmd);
+
+ deleteMdbCmd(readerConfigData);
+
+ return EXIT_SUCCESS;
+}
+int
+uartSendBytes(int uart0_filestream, uint8_t* txBuffer, int nrOfBytes)
+{
+ int nrOfSentBytes = 0;
+
+ nrOfSentBytes = write(uart0_filestream, txBuffer, nrOfBytes);
+
+ printf("Number of Bytes sent: %d\n", nrOfSentBytes);
+
+ return nrOfSentBytes;
+}
+
+int
+uartReceiveBytes(int uart0_filestream, uint8_t *rxBuffer, int nrOfBytes)
+{
+ int Bytes = 0;
+
+ nrOfReceivedBytes = read(uart0_filestream, rxBuffer, nrOfBytes);
+
+ // printf("Number of Bytes received: %d\n", nrOfReceivedBytes);
+
+ return nrOfReceivedBytes;
+}
+
+char *
+receiveMdbCmd(int filestream)
+{
+ uint8_t rxBuffer[MAX_SIZE_RX_BUFFER];
+ uint8_t cmd = 0xFF;
+
+ size_t cmdStartIdx = 0;
+ int nrOfReceivedBytes = 0;
+
+ nrOfReceivedBytes = read(filestream, rxBuffer, MAX_SIZE_RX_BUFFER);
+
+ if(nrOfReceivedBytes < 4){
+ return NULL;
+ }
+
+ while(rxBuffer[cmdStartIdx] != 0x02){
+ cmdStartIdx++;
+ if(cmdStartIdx == nrOfReceivedBytes){
+ return NULL;
+ }
+ }
+ //printf("Received Bytes: %d\n", nrOfReceivedBytes);
+ char *retVal = malloc(30*sizeof(char) + sizeof(uint16_t));
+
+ if(!retVal){
+ puts("Error: Cannot allocate memory");
+ }
+
+ cmd = ((convertChar2Hex(rxBuffer[cmdStartIdx+1]) << 4) |
(convertChar2Hex(rxBuffer[cmdStartIdx+2])));
+ printf("Received Command: %X\n", cmd);
+
+ switch (cmd) {
+ case 0x13:
+ if(((convertChar2Hex(rxBuffer[cmdStartIdx+3]) << 4) |
(convertChar2Hex(rxBuffer[cmdStartIdx+4]))) == 0x00){
+ uint16_t productNmbr = 0x0000;
+ size_t idx;
+ size_t shiftIdx;
+ for (idx = cmdStartIdx + 9, shiftIdx = 12; idx <= cmdStartIdx
+ 12; idx++, shiftIdx -= 4) {
+ productNmbr |=
((uint16_t)((convertChar2Hex(rxBuffer[idx])) << shiftIdx));
+ }
+ puts("");
+ sprintf(retVal, "Vend Request for: %d", productNmbr);
+ }
+ else if (((convertChar2Hex(rxBuffer[cmdStartIdx+3]) << 4) |
(convertChar2Hex(rxBuffer[cmdStartIdx+4]))) == 0x02) {
+ sprintf(retVal, "Vend Success");
+ }
+ else if (((convertChar2Hex(rxBuffer[cmdStartIdx+3]) << 4) |
(convertChar2Hex(rxBuffer[cmdStartIdx+4]))) == 0x03) {
+ sprintf(retVal, "Vend Failure");
+ }
+ else if (((convertChar2Hex(rxBuffer[cmdStartIdx+3]) << 4) |
(convertChar2Hex(rxBuffer[cmdStartIdx+4]))) == 0x04) {
+ sprintf(retVal, "Session Complete");
+ }
+ else {
+ free(retVal);
+ retVal = NULL;
+ }
+ break;
+ case 0x11:
+ sprintf(retVal, "Config Data");
+ break;
+ case 0x14:
+ if(((convertChar2Hex(rxBuffer[cmdStartIdx+3]) << 4) |
(convertChar2Hex(rxBuffer[cmdStartIdx+4]))) == 0x01){
+ sprintf(retVal, "Reader Enable");
+ }
+ else {
+ free(retVal);
+ retVal = NULL;
+ }
+ break;
+ case 0x00:
+ sprintf(retVal, "Acknowledge");
+ break;
+ case 0xD0:
+ sprintf(retVal, "Command out of Sequence");
+ break;
+ case 0xAA:
+ sprintf(retVal, "Resend previous data");
+ break;
+ default:
+ free(retVal);
+ retVal = NULL;
+ break;
+ }
+ return retVal;
+
+}
+mdbCmd *
+newMdbCmd(char *name, char *cmd, char *data)
+{
+
+ mdbCmd* cmdNew = malloc(sizeof(mdbCmd));
+ size_t idx = 0;
+ size_t strIdx = 0;
+
+ if(name == NULL){
+ cmdNew->name = malloc(sizeof(char) * strlen("No Cmd Name Set") + 1);
+ strncpy(cmdNew->name, "No Cmd Name Set", strlen("No Cmd Name Set") +
1);
+ }
+ else{
+ cmdNew->name = malloc(sizeof(char) * strlen(name) + 1);
+ strncpy(cmdNew->name, name, strlen(name) + 1);
+ }
+
+ if(cmd == NULL){
+ cmdNew->cmdLength = 0;
+ cmdNew->cmd = NULL;
+ }
+ else{
+ cmdNew->cmdLength = strlen(cmd) / 2;
+ cmdNew->cmd = malloc(sizeof(uint8_t) * cmdNew->cmdLength);
+ printf("New Command: ");
+ for(idx = 0, strIdx = 0; idx < cmdNew->cmdLength; idx++, strIdx += 2){
+ cmdNew->cmd[idx] = (convertChar2Hex(cmd[strIdx]) << 4 |
convertChar2Hex(cmd[strIdx + 1]));
+ printf("%X", cmdNew->cmd[idx]);
+ }
+ puts("");
+ }
+
+ if(data == NULL){
+ cmdNew->dataLength = 0;
+ cmdNew->data = NULL;
+ }
+ else{
+ cmdNew->dataLength = strlen(data) / 2;
+ cmdNew->data = malloc(sizeof(uint8_t) * cmdNew->dataLength);
+
+ for(idx = 0, strIdx = 0; idx < cmdNew->dataLength; idx++, strIdx += 2){
+ cmdNew->data[idx] = ((convertChar2Hex(data[strIdx])) << 4 |
convertChar2Hex(data[strIdx + 1]));
+ }
+ }
+
+ return cmdNew;
+}
+
+void
+deleteMdbCmd(mdbCmd *mdbCmdToDelete)
+{
+ free(mdbCmdToDelete->name);
+ free(mdbCmdToDelete->cmd);
+ free(mdbCmdToDelete->data);
+ free(mdbCmdToDelete);
+}
+
+void
+setMdbCmdData(mdbCmd *mdbCmdToSet, char *data)
+{
+ mdbCmdToSet->dataLength = strlen(data);
+
+ if(mdbCmdToSet->dataLength == 0){
+ free(mdbCmdToSet->data);
+ mdbCmdToSet->data = NULL;
+ }
+ else{
+ mdbCmdToSet = realloc(mdbCmdToSet->data, sizeof(uint8_t) *
mdbCmdToSet->dataLength);
+ size_t strIdx = 0;
+ for(size_t idx = 0; idx < mdbCmdToSet->dataLength; idx++){
+ mdbCmdToSet->data[idx] = (convertChar2Hex(data[strIdx]) << 4) |
(convertChar2Hex(data[strIdx + 1]));
+ strIdx = strIdx + 2;
+ }
+ }
+
+}
+
+int
+sendMdbCmd(mdbCmd* cmdToSend, int filestream)
+{
+
+ uint8_t* txBuffer;
+ uint32_t chkSum = 0x00000000;
+ int nrOfSentBytes = 0;
+ char *receivedMdbCmd = NULL;
+
+ txBuffer = malloc(sizeof(uint8_t) * (cmdToSend->cmdLength +
cmdToSend->dataLength + 1));
+
+ for(size_t idx = 0; idx < cmdToSend->cmdLength; idx++){
+ txBuffer[idx] = cmdToSend->cmd[idx];
+ //printf("%X", cmdToSend->cmd[idx]);
+ chkSum += cmdToSend->cmd[idx];
+ }
+
+ for(size_t idx = 0; idx < cmdToSend->dataLength; idx++){
+ txBuffer[idx + cmdToSend->cmdLength] = cmdToSend->data[idx];
+ chkSum += cmdToSend->data[idx];
+ }
+
+ txBuffer[cmdToSend->cmdLength + cmdToSend->dataLength] = (uint8_t)(chkSum
& 0xFF);
+
+ printf("Send command: %s\n", cmdToSend->name);
+
+
+ while(!receivedMdbCmd){
+ nrOfSentBytes = uartSendBytes(filestream, txBuffer,
cmdToSend->cmdLength + cmdToSend->dataLength + 1);
+ receivedMdbCmd = receiveMdbCmd(filestream);
+
+ if(receivedMdbCmd){
+ if(strcmp("Acknowledge", receivedMdbCmd) == 0){
+ break;
+ }
+ else{
+ free(receivedMdbCmd);
+ receivedMdbCmd = NULL;
+ }
+ }
+ }
+ free(receivedMdbCmd);
+
+ return nrOfSentBytes;
+}
diff --git a/src/mdb/mdb_uart.h b/src/mdb/mdb_uart.h
new file mode 100644
index 0000000..7c30586
--- /dev/null
+++ b/src/mdb/mdb_uart.h
@@ -0,0 +1,82 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2014 GNUnet e.V.
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more
+details.
+
+ You should have received a copy of the GNU General Public License
+along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+*/
+
+/**
+ * @file mdb_uart.h
+ * @brief Functions for communication via the mdb bus with the VMC
+ * @author Dominik Hofer <address@hidden>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <termios.h>
+
+/* Commands for communication via MDB/ICP */
+/* VMC commands */
+#define VMC_VEND 0x13
+#define VMC_VEND_REQUEST 0x00
+#define VMC_VEND_CANCEL 0x01
+#define VMC_VEND_SUCCESS 0x02
+#define VMC_VEND_FAILURE 0x03
+#define VMC_VEND_SESSION_COMPLETE 0x04
+
+/* Reader commands */
+#define READER_CONFIG "01"
+#define READER_DISPLAY_REQUEST "02"
+#define READER_BEGIN_SESSION "03"
+#define READER_SESSION_CANCEL_REQUEST "04"
+#define READER_VEND_APPROVE "05"
+#define READER_VEND_DENIED "06"
+#define READER_END_SESSION "07"
+#define READER_SESSION_CANCELLED "08"
+#define READER_REVALUE_APPROVED "0D"
+#define READER_REVALUE_DENIED "0E"
+
+/* Constants */
+#define MAX_SIZE_RX_BUFFER 256
+
+/* Macro for char to hex conversion */
+#define convertChar2Hex(C) (((C) >= 'A' && (C) <= 'F') ? ((C) - 55) : ((C) -
'0'))
+
+/* Datatype for mdb command */
+typedef struct mdbCmd_
+{
+ char* name;
+ uint8_t* cmd;
+ size_t cmdLength;
+ uint8_t* data;
+ size_t dataLength;
+}mdbCmd;
+
+/* Function Prototypes */
+int uart_init(void);
+int uart_close(int filestream);
+int mdb_init(int filestream);
+int uartSendBytes(int uart0_filestream, uint8_t* txBuffer, int nrOfBytes);
+int uartReceiveBytes(int uart0_filestream, uint8_t* rxBuffer, int nrOfBytes);
+mdbCmd* newMdbCmd(char* name, char *cmd, char *data);
+void deleteMdbCmd(mdbCmd *mdbCmdToDelete);
+void setMdbCmdData(mdbCmd *mdbCmdToSet, char *data);
+int sendMdbCmd(mdbCmd* cmdToSend, int filestream);
+char *receiveMdbCmd(int filestream);
--
To stop receiving notification emails like this one, please contact
address@hidden.
- [taler-taler-mdb] branch master updated (b18e966 -> 9065ce5), gnunet, 2019/12/04
- [taler-taler-mdb] 03/23: Some corrections, gnunet, 2019/12/04
- [taler-taler-mdb] 13/23: fix shutdown, gnunet, 2019/12/04
- [taler-taler-mdb] 05/23: some little bugfixes, gnunet, 2019/12/04
- [taler-taler-mdb] 09/23: neg cond, gnunet, 2019/12/04
- [taler-taler-mdb] 08/23: neg cond, gnunet, 2019/12/04
- [taler-taler-mdb] 04/23: mdb communication working (test integration), gnunet, 2019/12/04
- [taler-taler-mdb] 10/23: parse filenames from config, gnunet, 2019/12/04
- [taler-taler-mdb] 01/23: Added mdb communication module,
gnunet <=
- [taler-taler-mdb] 02/23: integration mdb first try, gnunet, 2019/12/04
- [taler-taler-mdb] 06/23: major mdb refactoring, gnunet, 2019/12/04
- [taler-taler-mdb] 23/23: add TODO, gnunet, 2019/12/04
- [taler-taler-mdb] 15/23: config, gnunet, 2019/12/04
- [taler-taler-mdb] 21/23: fix NPE, gnunet, 2019/12/04
- [taler-taler-mdb] 22/23: logging, gnunet, 2019/12/04
- [taler-taler-mdb] 17/23: invert checks, gnunet, 2019/12/04
- [taler-taler-mdb] 19/23: fix end session handling, gnunet, 2019/12/04
- [taler-taler-mdb] 11/23: use more named constants, gnunet, 2019/12/04
- [taler-taler-mdb] 14/23: fix FTBFS, gnunet, 2019/12/04