error handling and reporting

This commit is contained in:
2020-09-03 14:05:25 +02:00
parent dfee439030
commit 59f4c2d972
2 changed files with 143 additions and 86 deletions

View File

@ -10,34 +10,9 @@
#include <fcntl.h> #include <fcntl.h>
#include <string.h> #include <string.h>
#include "mbusgw.h"
#define LOOP_ENABLE 18
#define LOOP_DISABLE 23
#define LOOP_STATUS 22
#define FRONTEND_RESET 26
#define FRONTEND_SAMPLE_HOLD 19
#define LED_RED 5
#define LED_GREEN 6
#define DEFAULT_SERIAL_DEVICE "/dev/ttyAMA0"
typedef struct {
uint8_t start1;
uint8_t length1;
uint8_t length2;
uint8_t start2;
uint8_t l;
uint8_t c;
uint8_t a;
uint8_t ci;
uint8_t *userdata;
uint8_t chksum;
uint8_t stop;
} t_longframe;
typedef enum { typedef enum {
e_START1, e_START1,
e_LENGTH1, e_LENGTH1,
@ -57,7 +32,7 @@ typedef enum {
int serialFd; int serialFd;
bool verbose = false; bool verbose = false;
bool loopActiveFlag = false;
void msleep(uint32_t t) { void msleep(uint32_t t) {
usleep(t * 1000); usleep(t * 1000);
@ -65,31 +40,6 @@ void msleep(uint32_t t) {
void frontendReset() {
digitalWrite(FRONTEND_RESET, LOW);
msleep(25);
digitalWrite(FRONTEND_RESET, HIGH);
msleep(100);
}
void loopControl(bool v) {
if (v) {
digitalWrite(LOOP_ENABLE, HIGH);
msleep(25);
digitalWrite(LOOP_ENABLE, LOW);
} else {
digitalWrite(LOOP_DISABLE, HIGH);
digitalWrite(LOOP_DISABLE, LOW);
}
}
void frontendSample() {
digitalWrite(FRONTEND_SAMPLE_HOLD, LOW);
}
void frontendHold() {
digitalWrite(FRONTEND_SAMPLE_HOLD, HIGH);
}
void ledRed(bool v) { void ledRed(bool v) {
if (v) { if (v) {
@ -106,6 +56,39 @@ void ledGreen(bool v) {
digitalWrite(LED_GREEN, LOW); digitalWrite(LED_GREEN, LOW);
} }
} }
void frontendReset() {
digitalWrite(FRONTEND_RESET, LOW);
msleep(25);
digitalWrite(FRONTEND_RESET, HIGH);
msleep(100);
}
void loopControl(bool v) {
if (v) {
loopActiveFlag = true;
digitalWrite(LOOP_ENABLE, HIGH);
msleep(25);
digitalWrite(LOOP_ENABLE, LOW);
} else {
loopActiveFlag = false;
digitalWrite(LOOP_DISABLE, HIGH);
digitalWrite(LOOP_DISABLE, LOW);
}
}
void frontendSample() {
digitalWrite(FRONTEND_SAMPLE_HOLD, LOW);
}
void frontendHold() {
digitalWrite(FRONTEND_SAMPLE_HOLD, HIGH);
}
void loopFailureISR() {
loopActiveFlag = false;
ledRed(true);
}
void myExit(int e) { void myExit(int e) {
ledRed(false); ledRed(false);
@ -141,6 +124,8 @@ void init() {
pinMode(LOOP_STATUS, INPUT); pinMode(LOOP_STATUS, INPUT);
pullUpDnControl(LOOP_STATUS, PUD_UP); pullUpDnControl(LOOP_STATUS, PUD_UP);
wiringPiISR(LOOP_STATUS, INT_EDGE_RISING, loopFailureISR);
frontendReset(); frontendReset();
loopControl(false); loopControl(false);
@ -232,6 +217,8 @@ t_longframe *request(int fd, uint8_t cmd, uint8_t addr) {
if (ioctl(fd, TIOCSERGETLSR, &r) == -1) { if (ioctl(fd, TIOCSERGETLSR, &r) == -1) {
fprintf(stderr, "Error %d getting TIOCSERGETLSR for fd %d: %s\n", fprintf(stderr, "Error %d getting TIOCSERGETLSR for fd %d: %s\n",
errno, fd, strerror(errno)); errno, fd, strerror(errno));
errno = ERROR_APP_SPECIFIC_ERROR_FLAG | ERROR_TX_REG_UNACCESSIBLE;
return NULL;
} }
if (r & TIOCSER_TEMT) { if (r & TIOCSER_TEMT) {
break; break;
@ -355,6 +342,11 @@ t_longframe *request(int fd, uint8_t cmd, uint8_t addr) {
} }
if ((state == e_ERROR) || (state == e_TIMEOUT)) { if ((state == e_ERROR) || (state == e_TIMEOUT)) {
if (state == e_ERROR) {
errno = ERROR_TX_REG_UNACCESSIBLE | ERROR_STATE_ENGINE;
} else if (state == e_TIMEOUT) {
errno = ERROR_TX_REG_UNACCESSIBLE | ERROR_TIMEOUT;
}
if (frame->userdata) { if (frame->userdata) {
free(frame->userdata); free(frame->userdata);
frame->userdata = NULL; frame->userdata = NULL;
@ -395,7 +387,9 @@ void printFrame(bool hexOut, t_longframe *frame) {
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
init(); init();
ledGreen(true);
int exitCode = 0;
bool hexOut = false; bool hexOut = false;
bool lineMode = false; bool lineMode = false;
uint8_t addr = 0; uint8_t addr = 0;
@ -447,51 +441,64 @@ int main(int argc, char *argv[]) {
myExit(-1); myExit(-1);
} }
if (! lineMode) {
fprintf(stderr, "Sending request %02x %02x\n", cmd, addr); while (1) {
t_longframe *frame = request(fd, cmd, addr); if (! loopActiveFlag) {
fprintf(stderr, "loop is not active, enable it and delay\n");
loopControl(true);
msleep(2000);
}
if (lineMode) {
if (verbose) {
fprintf(stderr, "lineMode, waiting for input\n");
}
fread(&cmd, 1, 1, stdin);
fread(&addr, 1, 1, stdin);
}
if ((cmd == 0) && (addr == 0)) {
fprintf(stderr, "termination requested\n");
break;
}
if (verbose) {
fprintf(stderr, "sending request %02x %02x\n", cmd, addr);
}
t_longframe *frame = NULL;
if (loopActiveFlag) {
ledRed(false);
frame = request(fd, cmd, addr);
} else {
fprintf(stderr, "loop is currently inactive, no need to try\n");
}
if (frame) { if (frame) {
fprintf(stderr, "received something\n"); if (verbose) {
fprintf(stderr, "received a valid frame\n");
}
printFrame(hexOut, frame); printFrame(hexOut, frame);
free(frame->userdata); free(frame->userdata);
frame->userdata = NULL; frame->userdata = NULL;
free(frame); free(frame);
frame = NULL; frame = NULL;
} else { } else {
fprintf(stderr, "some error occured\n"); ledRed(true);
if (! loopActiveFlag) {
errno = ERROR_APP_SPECIFIC_ERROR_FLAG | ERROR_LOOP_FAILURE;
}
fprintf(stderr, "error %04x occured\n", errno);
if (! hexOut) { if (! hexOut) {
fprintf(stdout, "%c%c", 0xff, 0); uint8_t maskedError = (uint8_t)(errno & ~ERROR_APP_SPECIFIC_ERROR_FLAG);
fprintf(stdout, "%c%c", maskedError, 0);
fflush(stdout); fflush(stdout);
} }
myExit(-1); if (! lineMode) {
exitCode = -2;
}
} }
} else {
while (1) { if (! lineMode) {
fread(&cmd, 1, 1, stdin); break;
fread(&addr, 1, 1, stdin);
if ((cmd == 0) && (addr == 0)) {
break;
}
if (verbose) {
fprintf(stderr, "%02x %02x\n", cmd, addr);
}
t_longframe *frame = request(fd, cmd, addr);
if (frame) {
if (verbose) {
fprintf(stderr, "received something\n");
}
printFrame(false, frame);
free(frame->userdata);
frame->userdata = NULL;
free(frame);
frame = NULL;
} else {
if (verbose) {
fprintf(stderr, "some error occured\n");
}
fprintf(stdout, "%c%c", 0xff, 0);
fflush(stdout);
}
} }
} }
@ -499,6 +506,8 @@ int main(int argc, char *argv[]) {
fprintf(stderr, "Closing device\n"); fprintf(stderr, "Closing device\n");
} }
closeSerial(fd); closeSerial(fd);
myExit(exitCode);
} }

48
src/mbusgw.h Normal file
View File

@ -0,0 +1,48 @@
#ifndef _MBUSGW_H_
#define _MBUSGW_H_
#include <stdint.h>
#define LOOP_ENABLE 18
#define LOOP_DISABLE 23
#define LOOP_STATUS 22
#define FRONTEND_RESET 26
#define FRONTEND_SAMPLE_HOLD 19
#define LED_RED 5
#define LED_GREEN 6
#define DEFAULT_SERIAL_DEVICE "/dev/ttyAMA0"
#define ERROR_TIMEOUT 1
#define ERROR_STATE_ENGINE 2
#define ERROR_LOOP_FAILURE 3
#define ERROR_TX_REG_UNACCESSIBLE 4
#define ERROR_APP_SPECIFIC_ERROR_FLAG 0x4000
typedef struct {
uint8_t start1;
uint8_t length1;
uint8_t length2;
uint8_t start2;
uint8_t l;
uint8_t c;
uint8_t a;
uint8_t ci;
uint8_t *userdata;
uint8_t chksum;
uint8_t stop;
} t_longframe;
#endif