78 Commits
v1.0 ... master

Author SHA1 Message Date
Martijn Scheepers
370d7396e8 fix typo 2023-01-03 12:24:12 +01:00
Martijn Scheepers
ae8dc0a476 fix status script 2023-01-03 10:00:34 +01:00
Martijn Scheepers
8f0d34a193 Add server port to acs reader 2023-01-02 11:14:12 +01:00
Martijn Scheepers
c2519082d3 longer serial timeout 2021-07-30 11:48:18 +02:00
Martijn Scheepers
68ddd1c433 Cast to double 2021-07-30 09:21:18 +02:00
Martijn Scheepers
d27a7ae20c Cron every 0th minute of hour 2020-02-25 10:08:39 +01:00
Martijn Scheepers
7a1b3b1954 Added connection test script 2020-02-21 15:51:18 +01:00
Martijn Scheepers
82e92f1eed added logtypes to server log 2019-09-09 12:48:21 +02:00
Martijn Scheepers
f99061c762 time to unsigned int 2019-08-22 14:52:56 +02:00
Martijn Scheepers
1d2582993d Update display to version 2 2019-08-22 08:34:25 +02:00
Martijn Scheepers
da17cc5fe3 added readername to syslog 2019-08-09 16:15:05 +02:00
Martijn Scheepers
1f0bff764f readme json-c to cjson 2019-08-09 16:06:38 +02:00
Martijn Scheepers
048bd74664 added reader names 2019-08-09 16:01:24 +02:00
Martijn Scheepers
47de58e0cd make var's 0 2019-08-09 14:21:50 +02:00
Martijn Scheepers
b1cdf7f6db changed from json-c to cjson lib 2019-08-09 14:09:18 +02:00
Martijn Scheepers
78df77a1c5 changed ash to sh 2019-08-06 16:03:50 +02:00
Martijn Scheepers
f6ce9550ee make logrotate daily 2019-08-06 15:37:17 +02:00
Martijn Scheepers
c4b6d5dce5 memcpy real data to malloc area 2019-08-06 13:26:20 +02:00
Martijn Scheepers
208f5c1637 use timer_delete in mf700 timers 2019-08-06 13:21:50 +02:00
Martijn Scheepers
293de40169 implement timer_delete in relay timer 2019-08-06 12:15:41 +02:00
Martijn Scheepers
5aa0c7b89f relay timer better log message 2019-08-06 09:29:52 +02:00
Martijn Scheepers
de95821d6b mf700 write is seperate function 2019-08-06 09:14:23 +02:00
Martijn Scheepers
e839c7f93a no new timer if time is -1 2019-08-06 09:04:09 +02:00
Martijn Scheepers
34cec2c4d0 pins for raspberry test 2019-08-06 09:03:30 +02:00
Martijn Scheepers
07f80f9e4f rpi macaddress is standard file path 2019-08-05 12:16:11 +02:00
Martijn Scheepers
13491b809b Message with missing config file 2019-08-05 11:57:22 +02:00
Martijn Scheepers
089c1ce25f clean up 2019-07-11 14:16:26 +02:00
Martijn Scheepers
b157063f92 Better opentime = 0 handeling 2019-07-11 13:59:06 +02:00
Martijn Scheepers
ab0ae0671c added stdint.h, change true false define 2019-07-11 13:16:45 +02:00
Martijn Scheepers
611f97242a remove compiler warnings 2019-07-11 12:15:46 +02:00
Martijn Scheepers
176d8ead1e Added deviceinactive return type 2019-07-11 11:14:08 +02:00
Martijn Scheepers
8d1a74fc8d Git hash to 77 chars 2019-07-09 13:24:39 +02:00
Martijn Scheepers
1a24d0eb64 error log message to info message 2019-07-09 10:10:18 +02:00
Martijn Scheepers
de292e5c38 Changed S01logging to S01syslogd 2019-05-02 09:36:51 +02:00
Martijn Scheepers
17c1fc392b dual reader led control 2019-03-11 16:04:08 +01:00
Martijn Scheepers
80f3c05170 increased buf for display line 2019-03-08 10:03:42 +01:00
Martijn Scheepers
800efb2a3f Removed display timer, for timer in display driver 2019-03-08 09:25:45 +01:00
Martijn Scheepers
c64393e72c ssh failed gives servererror 2019-03-06 13:25:12 +01:00
Martijn Scheepers
d34f2bed05 debug timer code 2019-02-11 08:27:54 +01:00
Martijn Scheepers
afe577a0cb removed debug code 2019-02-05 11:19:06 +01:00
Martijn Scheepers
b76f80f6b7 debug display data 2019-02-05 11:06:57 +01:00
Martijn Scheepers
c70252be4b debugging dislay write 2019-02-05 08:41:56 +01:00
Martijn Scheepers
4bbd2c435f removed switchtime from config 2019-02-01 14:09:19 +01:00
Martijn Scheepers
3e0ed17d26 fix for building on rpi 2019-02-01 08:06:29 +01:00
Martijn Scheepers
1e8dd93ed6 extra compiler warnings 2019-01-31 19:04:42 +01:00
Martijn Scheepers
b7212ee4a7 more error info from curl in syslog 2019-01-31 16:21:44 +01:00
Martijn Scheepers
53eedfc10b errors to syslog 2019-01-31 15:16:12 +01:00
Martijn Scheepers
24689cd83e use device server opentime for manual open 2019-01-31 13:42:46 +01:00
Martijn Scheepers
69ccfb0b68 write version in syslog at startup 2019-01-31 13:15:22 +01:00
Martijn Scheepers
5f274e7cc7 every webrequest handles errors 2019-01-31 13:05:14 +01:00
Martijn Scheepers
12137089fe opentime to long int 2019-01-31 11:22:59 +01:00
Martijn Scheepers
91ae304ee9 make semaphore static 2019-01-31 10:57:37 +01:00
Martijn Scheepers
5c2f6c2367 removed unused strcut members 2019-01-31 10:45:29 +01:00
Martijn Scheepers
c84acef8e0 removed global line[] variable 2019-01-31 10:38:48 +01:00
Martijn Scheepers
d8b5a00376 Add display code to display.c file 2019-01-31 10:14:33 +01:00
Martijn Scheepers
bbac6c3a08 show curl errors on display 2019-01-30 15:55:54 +01:00
Martijn Scheepers
f8869ac5fe Changed to api versie 2 2019-01-30 13:11:31 +01:00
Martijn Scheepers
b6d16bd871 add counting semaphore for display, relay and mf700 leds 2019-01-30 08:15:46 +01:00
Martijn Scheepers
0d6b6b8dad #ifdef not #if 2019-01-29 14:48:29 +01:00
Martijn Scheepers
5e2ff7f912 h1502 gpio directions are already set 2019-01-29 14:45:53 +01:00
Martijn Scheepers
949aacdcbd cleanup old code 2019-01-29 13:19:10 +01:00
Martijn Scheepers
65c8e01300 add pthread header 2019-01-29 12:55:56 +01:00
Martijn Scheepers
a6a017ed80 state init errors 2019-01-29 12:47:50 +01:00
Martijn Scheepers
cc8b4966d5 added display timer 2019-01-29 11:36:26 +01:00
Martijn Scheepers
0a351e158c v2 save 2019-01-29 10:15:35 +01:00
Martijn Scheepers
c660d7c6b6 changes for version 2 2019-01-23 12:59:56 +01:00
Martijn Scheepers
ef1185390e read inputs from thread 2019-01-21 13:56:51 +01:00
Martijn Scheepers
fce6cd9d7d serial ports in pthreads 2019-01-21 08:16:39 +01:00
Martijn Scheepers
95120f5cbc buildroot version number 2018-12-13 08:28:07 +01:00
Martijn Scheepers
75226341db Only one time manual open 2018-12-10 14:54:57 +01:00
Martijn Scheepers
fd5c78f987 Check if acsconfig.conf exists 2018-12-10 14:04:36 +01:00
Martijn Scheepers
0b173c1293 ACS status update every min. 2018-12-10 12:24:30 +01:00
Martijn Scheepers
bd1bd867ab Merge branch 'master' of https://git.SDNsupport.nl:4000/ACS/ACSreader 2018-12-10 08:47:01 +01:00
Martijn Scheepers
75d818e908 Changed status script 2018-12-10 08:46:25 +01:00
Martijn Scheepers
6d06094d4e add confuse and json link in readme 2018-12-07 21:37:53 +01:00
Martijn Scheepers
ef24258a45 Push lockstate to serverq 2018-12-06 10:48:54 +01:00
Martijn Scheepers
f52dbc2c9d Connection with server message 2018-12-05 09:01:21 +01:00
Martijn Scheepers
6680f7bdac Added productclass to status update 2018-12-04 14:50:34 +01:00
35 changed files with 1143 additions and 660 deletions

View File

@@ -1,8 +1,14 @@
CC = gcc
CFLAGS = -DVERSION=\"$(GIT_VERSION)\" -Werror -Wall -Wextra -pedantic -Wcast-align -Wcast-qual -Wdisabled-optimization -Wformat=2 -Winit-self -Wlogical-op -Wmissing-include-dirs -Wredundant-decls -Wshadow -Wstrict-overflow=5 -Wundef -Wno-unused -Wno-variadic-macros -Wno-parentheses -fdiagnostics-show-option -Wconversion
LDFLAGS = -std=c11 -lcurl -lconfuse -ljson-c
CFLAGS = -DVERSION=\"$(GIT_VERSION)\" -Werror -Wall -Wextra -pedantic -Wcast-align\
-Wcast-qual -Wdisabled-optimization -Wformat=2 -Winit-self -Wlogical-op -Wmissing-include-dirs\
-Wredundant-decls -Wshadow -Wstrict-overflow=5 -Wundef -Wno-unused -Wno-variadic-macros\
-Wno-parentheses -fdiagnostics-show-option -Wconversion -Wswitch-default -Wvla -Wlong-long -Wredundant-decls\
-Wunreachable-code -Wduplicated-cond -Wnull-dereference -Wjump-misses-init -Wdouble-promotion\
-Wimplicit-fallthrough -Wduplicated-branches -Wrestrict
GIT_VERSION := $(shell git --git-dir ./.git describe --abbrev=6 --dirty --always --tags)
LDFLAGS = -std=gnu11 -lcurl -lconfuse -lcjson -lpthread -lrt
GIT_VERSION := $(shell git describe --dirty --always --tags)
SRC = $(wildcard *.c)
OBJ = $(SRC:.c=.o)

3
README
View File

@@ -1,5 +1,8 @@
ACSreader
- Install confuse https://github.com/martinh/libconfuse
- Install cjson https://github.com/DaveGamble/cJSON
- to build software use "make"
-- make all = standaard build for h1502
-- make test = build without display or debug on rpi

View File

@@ -1,10 +1,14 @@
#acsreader configuratie
serialport = "/dev/ttyS2"
serialport1 = "/dev/ttyS2"
reader1name = "reader 1"
serialport2 = "/dev/ttyS3"
#serialport = "/dev/ttyUSB0"
reader2name = "reader 2"
#adres van de ACS server
serveraddress = "192.168.0.104"
serverport = 443
#naam van het apparaat
devicename = "H1502R11"
@@ -24,7 +28,4 @@ relay = 1
#draait schakelfunctie van het relais om
relayinvert = false
#schakeltijd in seconden
switchtime = 5

View File

@@ -14,17 +14,10 @@ int get_device_id(char *device){
int fd;
ssize_t count;
#ifdef TEST
if((fd = open("/sys/class/net/enxb827eb66e7b5/address", O_RDONLY)) < 0){
writesyslog(LOG_ERR, "error opening /sys/class/net/enxb827eb66e7b5/address");
return -1;
}
#else
if((fd = open("/sys/class/net/eth0/address", O_RDONLY)) < 0){
writesyslog(LOG_ERR, "error opening /sys/class/net/eth0/address");
return -1;
}
#endif
char mac[18];
count = read(fd, &mac, sizeof(mac));
@@ -58,14 +51,17 @@ int config_read(struct config_t *config, char *filepath){
get_device_id(config->device);
config->serialport = NULL;
config->serialport1 = NULL;
config->reader1name = NULL;
config->serialport2 = NULL;
config->reader2name = NULL;
config->serveraddress = NULL;
config->serverport = 0;
config->name = NULL;
config->manualinput = 0;
config->inputlevel = 0;
config->relay = 0;
config->relayinvert = cfg_false;
config->switchtime = 0;
cfg_opt_t opts[] = {
//CFG_SIMPLE_BOOL("verbose", &verbose),
@@ -74,15 +70,18 @@ int config_read(struct config_t *config, char *filepath){
//CFG_SIMPLE_INT("debug", &debug),
//CFG_SIMPLE_FLOAT("delay", &delay),
//CFG_SIMPLE_STR("serialport", &serialport),
CFG_SIMPLE_STR("serialport", &config->serialport),
CFG_SIMPLE_STR("serialport1", &config->serialport1),
CFG_SIMPLE_STR("reader1name", &config->reader1name),
CFG_SIMPLE_STR("serialport2", &config->serialport2),
CFG_SIMPLE_STR("reader2name", &config->reader2name),
CFG_SIMPLE_STR("serveraddress", &config->serveraddress),
CFG_SIMPLE_INT("serverport", &config->serverport),
CFG_SIMPLE_STR("devicename", &config->name),
CFG_SIMPLE_INT("productclass", &config->ProductClass),
CFG_SIMPLE_INT("manualinput", &config->manualinput),
CFG_SIMPLE_INT("inputlevel", &config->inputlevel),
CFG_SIMPLE_INT("relay", &config->relay),
CFG_SIMPLE_BOOL("relayinvert", &config->relayinvert),
CFG_SIMPLE_INT("switchtime", &config->switchtime),
CFG_END()
};
cfg_t *cfg;
@@ -114,14 +113,17 @@ int config_read(struct config_t *config, char *filepath){
void config_print(struct config_t *config, char *filepath){
printf("------------- configfile ----------\n");
printf("filepath: %s\n", filepath);
printf("serialport: %s\n", config->serialport);
printf("reader 1 name: %s\n", config->reader1name);
printf("serialport 1: %s\n", config->serialport1);
printf("reader 2 name: %s\n", config->reader2name);
printf("serialport 2: %s\n", config->serialport2);
printf("serveraddress: %s\n", config->serveraddress);
printf("serverport: %ld\n", config->serverport);
printf("device: %s\n", config->device);
printf("device name: %s\n", config->name);
printf("manualinput: %ld\n", config->manualinput);
printf("inputlevel: %ld\n", config->inputlevel);
printf("relay: %ld\n", config->relay);
printf("relayinvert: %s\n", config->relayinvert ? "true" : "false");
printf("switchtime: %ld\n", config->switchtime);
printf("-----------------------------------\n\n");
}

View File

@@ -3,8 +3,12 @@
#include <confuse.h>
struct config_t {
char *serialport;
char *serialport1;
char *reader1name;
char *serialport2;
char *reader2name;
char *serveraddress;
long int serverport;
char device[8];
char *name;
long int ProductClass;
@@ -12,7 +16,6 @@ struct config_t {
long int inputlevel;
long int relay;
cfg_bool_t relayinvert;
long int switchtime;
};
int config_read(struct config_t *config, char *filepath);

76
display.c Normal file
View File

@@ -0,0 +1,76 @@
#define _GNU_SOURCE
#include <syslog.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <signal.h>
#include <time.h>
#include <pthread.h>
#include <sys/ioctl.h>
#include "config.h"
#include "web.h"
#include "log.h"
#include "jsontypes.h"
#include "display.h"
#define DEVICE "/dev/h1502display"
#define CONTENT_LENGTH 21
#define MENU_LENGTH 8
#define MENU_SIZE 4
#define MENU_OFFSET 80
static unsigned int line[] = {
0, 8, 16, 24,
};
int display_open(){
int fd = open(DEVICE, O_WRONLY);
if(fd < 0){
writesyslog(LOG_ERR, "opening /dev/h1502display failed");
return 0;
}
return fd;
}
void display_timer(int fd, unsigned int time){
if(time <= 0){
time = 3; //3 sec
}
if(ioctl(fd, H1502DISPLAY_IOCTL_TIMER, time) < 0){
writesyslog(LOG_ERR, "Timer ioctl /dev/h1502display failed");
}
}
void display_clear(int fd){
if(ioctl(fd, H1502DISPLAY_IOCTL_CLEAR) < 0){
close(fd);
writesyslog(LOG_ERR, "clearing /dev/h1502display failed");
}
}
void display_write(int fd, int ln, int pos, int invert, char *txt){
#ifdef TEST
printf("Display write ->%s<-\n", txt);
//return 0;
#endif
struct optdata_t opts;
opts.x = (unsigned int)pos;
opts.y = line[ln];
opts.invert = (unsigned int)invert;
if(ioctl(fd, H1502DISPLAY_IOCTL_SETOPT, &opts) < 0){
close(fd);
writesyslog(LOG_ERR, "Setopt ioctl /dev/h1502display failed");
return;
}
if(write(fd, txt, strlen(txt)) < 0){
close(fd);
writesyslog(LOG_ERR, "write /dev/h1502display failed");
return;
}
return;
}

21
display.h Normal file
View File

@@ -0,0 +1,21 @@
#ifndef DISPLAY_FILE
#define DISPLAY_FILE
struct optdata_t
{
unsigned int x;
unsigned int y;
unsigned int invert;
};
#define H1502DISPLAY_MAGIC 'm'
#define H1502DISPLAY_IOCTL_CLEAR _IO(H1502DISPLAY_MAGIC, 1)
#define H1502DISPLAY_IOCTL_SETOPT _IOC(_IOC_WRITE, H1502DISPLAY_MAGIC, 2, sizeof(struct optdata_t))
#define H1502DISPLAY_IOCTL_TIMER _IOC(_IOC_WRITE, H1502DISPLAY_MAGIC, 3, sizeof(unsigned int))
int display_open();
void display_timer(int fd, unsigned int time);
void display_clear(int fd);
void display_write(int fd, int ln, int pos, int invert, char *txt);
#endif

11
global.h Normal file
View File

@@ -0,0 +1,11 @@
#ifndef FLAGS_FILE
#define FLAGS_FILE
#define ACS_TRUE 1
#define ACS_FALSE 0
#define DISPLAY_TIME 60
volatile int doorlockedflag;
#endif

91
gpio.c
View File

@@ -177,14 +177,20 @@ int GPIOWrite(unsigned int pin, unsigned int value){
return(0);
}
#ifdef TEST
unsigned int relaysysfs[9] = {0, 17, 17, 17, 17, 17, 17, 17, 17}; //SYSFS export number
unsigned int relaypin[9] = {0, 17, 17, 17, 17, 17, 17, 17, 17}; //PortC number
unsigned int relaypin[9] = {0, 17, 17, 17, 17, 17, 17, 17, 17}; //Port number
#else
unsigned int relaysysfs[9] = {0, 81, 80, 79, 78, 83, 84, 76, 77}; //SYSFS export number
unsigned int relaypin[9] = {0, 17, 16, 15, 14, 19, 20, 12, 13}; //PortC number
#endif
unsigned int get_relaypin(unsigned int pin){
return(relaypin[pin]);
}
int gpio_initrelay(unsigned int relay, cfg_bool_t relayinvert){
if(relay > 8 || relay < 1){
char *log;
@@ -194,7 +200,7 @@ int gpio_initrelay(unsigned int relay, cfg_bool_t relayinvert){
free(log);
return(-1);
}
#ifdef TEST
for (int i = 1; i<9; i++ ) {
if(GPIOExport(relaysysfs[i]) < 0){
return(-1);
@@ -203,6 +209,7 @@ int gpio_initrelay(unsigned int relay, cfg_bool_t relayinvert){
return(-1);
}
}
#endif
if(relayinvert == cfg_true){
if(GPIOWrite(relaypin[relay], HIGH) < 0){
@@ -218,54 +225,18 @@ int gpio_initrelay(unsigned int relay, cfg_bool_t relayinvert){
}
int gpio_switchrelay(int state, unsigned int relay, cfg_bool_t relayinvert){
if(state == RELAY_ON){
if (relayinvert == cfg_false){
#ifdef TEST
printf("Relay %d - HIGH\n", relay);
#endif
if(GPIOWrite(relaypin[relay], HIGH) < 0){
return(-1);
}
}
else{
#ifdef TEST
printf("Relay %d - LOW\n", relay);
#endif
if(GPIOWrite(relaypin[relay], LOW) < 0){
return(-1);
}
}
}
else{
if (relayinvert == cfg_false){
#ifdef TEST
printf("Relay %d - LOW\n", relay);
#endif
if(GPIOWrite(relaypin[relay], LOW) < 0){
return(-1);
}
}
else{
#ifdef TEST
printf("Relay %d - HIGH\n", relay);
#endif
if(GPIOWrite(relaypin[relay], HIGH) < 0){
return(-1);
}
}
}
return(0);
}
#ifdef TEST
unsigned int inputsysfs[9] = {0, 2, 2, 2, 2, 2, 2, 2, 2}; //SYSFS export number
unsigned int inputpin[9] = {0, 2, 2, 2, 2, 2, 2, 2, 2}; //PortA number
unsigned int inputsysfs[9] = {0, 22, 22, 22, 22, 22, 22, 22, 22}; //SYSFS export number
unsigned int inputpin[9] = {0, 22, 22, 22, 22, 22, 22, 22, 22}; //Port number
#else
unsigned int inputsysfs[9] = {0, 29, 28, 27, 26, 25, 24, 23, 22}; //SYSFS export number
unsigned int inputpin[9] = {0, 29, 28, 27, 26, 25, 24, 23, 22}; //PortA number
#endif
unsigned int get_inputpin(int pin){
return(inputpin[pin]);
}
int gpio_initinput(unsigned int input){
if(input > 8 || input < 1){
char *log;
@@ -276,37 +247,15 @@ int gpio_initinput(unsigned int input){
return(-1);
}
//input is pioA
#ifdef TEST
for (int i = 1; i<9; i++ ) {
if(GPIOExport(inputsysfs[i]) < 0){
return(-1);
}
//if(GPIODirection(inputpin[i], IN) < 0){
// return(-1);
//}
}
return(0);
}
int input_fd_open(long int input){
char *fl;
#ifdef TEST
if(asprintf(&fl, "/sys/class/gpio/gpio%d/value", inputpin[input]) < 0 ){
writesyslog(LOG_ERR, "asprintf failed");
return(-1);
}
#else
if(asprintf(&fl, "/sys/class/gpio/pioA%d/value", inputpin[input]) < 0 ){
writesyslog(LOG_ERR, "asprintf failed");
return(-1);
if(GPIODirection(inputpin[i], IN) < 0){
return(-1);
}
}
#endif
int fd = open(fl, O_RDONLY | O_NONBLOCK );
if (fd < 0) {
writesyslog(LOG_ERR, "failed to open gpio value for manualinput");
return(-1);
}
free(fl);
return fd;
return(0);
}

6
gpio.h
View File

@@ -12,10 +12,12 @@
#define LOW 0
#define HIGH 1
int GPIOWrite(unsigned int pin, unsigned int value);
unsigned int get_relaypin(unsigned int pin);
int gpio_initrelay(unsigned int relay, cfg_bool_t relayinvert);
int gpio_switchrelay(int state, unsigned int relay, cfg_bool_t relayinvert);
unsigned int get_inputpin(int pin);
int gpio_initinput(unsigned int input);
int input_fd_open(long int input);
#endif

122
inputs.c Normal file
View File

@@ -0,0 +1,122 @@
#define _GNU_SOURCE
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <syslog.h>
#include <string.h>
#include <sys/file.h>
#include <poll.h>
#include <pthread.h>
#include "runtime.h"
#include "config.h"
#include "gpio.h"
#include "log.h"
#include "web.h"
#include "relay.h"
#include "global.h"
#include "display.h"
int input_fd_open(long int input){
char *fle, *flv;
#ifdef TEST
if(asprintf(&fle, "/sys/class/gpio/gpio%d/edge", get_inputpin((int)input)) < 0 ){
writesyslog(LOG_ERR, "asprintf failed");
return(-1);
}
if(asprintf(&flv, "/sys/class/gpio/gpio%d/value", get_inputpin((int)input)) < 0 ){
writesyslog(LOG_ERR, "asprintf failed");
return(-1);
}
#else
if(asprintf(&fle, "/sys/class/gpio/pioA%d/edge", get_inputpin((int)input)) < 0 ){
writesyslog(LOG_ERR, "asprintf failed");
return(-1);
}
if(asprintf(&flv, "/sys/class/gpio/pioA%d/value", get_inputpin((int)input)) < 0 ){
writesyslog(LOG_ERR, "asprintf failed");
return(-1);
}
#endif
int fd = open(fle, O_WRONLY);
ssize_t ret = write(fd, "both", 4);
close(fd);
fd = open(flv, O_RDONLY);
if (fd < 0) {
writesyslog(LOG_ERR, "failed to open gpio value for manualinput");
return(-1);
}
free(fle);
free(flv);
return fd;
}
//input read thread
void *readinputs(void *ptr){
struct config_t *config;
config = (struct config_t *) ptr;
struct pollfd pfd;
pfd.fd = input_fd_open(config->manualinput);;
if(pfd.fd < 0){
writesyslog(LOG_ERR, "manualinput failed\n");
exitprogram(EXIT_FAILURE);
}
pfd.events = POLLPRI;
while(1){
lseek(pfd.fd, 0, SEEK_SET);
int rc = poll(&pfd, 1, -1);
if (rc < 0){
if(errno != EINTR){
char *log;
if(asprintf(&log, "inputpoll failed: %s", strerror(errno)) > 0 ){
writesyslog(LOG_ERR, log);
}
exitprogram(EXIT_FAILURE);
}
}else if(rc > 0){
unsigned char val;
if(read(pfd.fd, &val, 1) < 0){
char *log;
if(asprintf(&log, "input read failed: %s", strerror(errno)) != 0 ){
writesyslog(LOG_ERR, log);
}
free(log);
exitprogram(EXIT_FAILURE);
}
if(doorlockedflag == ACS_TRUE){
if((val == '0' && config->inputlevel == 1) || (val == '1' && config->inputlevel == 0)){
unsigned int switchtime = server_get_opentime(config);
if(relay_switch(RELAY_ON, switchtime, config) == ERROR){
exitprogram(EXIT_FAILURE);
}
int fd = display_open();
display_clear(fd);
char *ln1;
if(asprintf(&ln1, "Manual open - %d sec", switchtime) > 0 ){
display_write(fd, 1, 0, 0, ln1);
}
char *ln2;
if(asprintf(&ln2, "In: %ld - Relay: %ld", config->manualinput, config->relay) > 0 ){
display_write(fd, 2, 0, 0, ln2);
}
free(ln2);
display_timer(fd, switchtime);
close(fd);
writesyslog(LOG_INFO, ln1);
server_send_log(config, MANUALOPEN, ln1);
free(ln1);
}
}
}
}
}

6
inputs.h Normal file
View File

@@ -0,0 +1,6 @@
#ifndef INPUTS_FILE
#define INPUTS_FILE
void *readinputs(void *ptr);
#endif

View File

@@ -2,28 +2,50 @@
#define JSONTYPES_FILE
typedef enum{
UNKNOWNERROR = 0,
ACCESSGRANTED = 1,
ACCESSDENIED = 2,
UNKNOWNERROR = 0,
LOGOK = 3,
LOGERROR = 4,
ACCESSGRANTED = 1,
ACCESSDENIED = 2,
CONNECTIONTIMEOUT = 5,
RESOLVEERROR = 6,
SERVERERROR = 7,
LOGOK = 3,
LOGERROR = 4,
CREDENTIALERROR = 8,
CONNECTIONTIMEOUT = 5,
RESOLVEERROR = 6,
SERVERERROR = 7,
CREDENTIALERROR = 8,
LOCKSTATEOK = 9,
LOCKSTATEERROR = 10,
STATUSOK = 11,
STATUSERROR = 12,
OPENTIMEOK = 13,
OPENTIMEERROR = 14,
DEVICEINACTIVE = 15,
} returnstate_t;
struct returnjson_t{
char device[7];
char uid[11];
int cardnumber;
char sectorkey[36];
int opentime;
returnstate_t state;
};
typedef enum{
UNKNOWNLOCKSTATE = 0,
UNLOCKED = 1,
LOCKED = 2,
SECURED = 3,
JAMMED = 4
} lockstates_t;
typedef enum{
UNKNOWNLOGTYPE = 0,
SYSTEM = 1,
USER = 2,
DEVICE = 3,
UNKNOWNUSER = 4,
DTC = 5,
BOOTLOG = 6,
MANUALOPEN = 7
} logtypes_t;
#endif

131
log.c
View File

@@ -1,142 +1,13 @@
#define _GNU_SOURCE
#include <syslog.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <json-c/json.h>
#include "config.h"
#include "web.h"
#include "log.h"
#include "jsontypes.h"
#define CONTENT_LENGTH 21
#define MENU_LENGTH 8
#define MENU_SIZE 4
#define MENU_OFFSET 80
void writesyslog(int priority, const char *logtext){
#ifdef TEST
printf("Serverlog = %s\n", logtext);
printf("Syslog = %s\n", logtext);
#endif
openlog("acsreader", LOG_PID|LOG_CONS|LOG_NDELAY, LOG_LOCAL0);
setlogmask(LOG_UPTO(LOG_INFO));
syslog(priority, "%s", logtext);
closelog();
}
int writeserverlog(struct config_t *config, const char *logtext){
int ret = 0;
char *url;
int len = asprintf(&url, "https://%s/api/addlog", config->serveraddress );
struct json_object *sendobj;
sendobj = json_object_new_object();
json_object_object_add(sendobj, "Device", json_object_new_string(config->device));
json_object_object_add(sendobj, "Name", json_object_new_string(config->name));
json_object_object_add(sendobj, "Message", json_object_new_string(logtext));
json_object_object_add(sendobj, "ProductClass", json_object_new_int64(config->ProductClass));
if(len > 0 ){
struct returnjson_t retdata;
web_request_json(url, json_object_to_json_string(sendobj), &retdata);
if(retdata.state != LOGOK){
char *log;
if(asprintf(&log, "ACS server log writing error - %d", retdata.state) > 0 ){
writesyslog(LOG_ERR, log);
}
free(log);
ret = -1;
}
}else{
writesyslog(LOG_ERR, "writeserverlog: asprintf failed");
ret = -1;
}
json_object_put(sendobj); //delete json object
free(url);
return(ret);
}
//write display line to h1502display char device
int write_device(char *line){
int fd;
ssize_t ret;
fd = open("/dev/h1502display", O_WRONLY);
if (fd == -1) {
perror("open /dev/h1502display: ");
return -1;
}
ret = write(fd, line, strlen(line));
if(ret < (int)strlen(line)){
perror("write /dev/h1502display: ");
close(fd);
return -1;
}
close(fd);
return 0;
}
//write display line to h1502display char device
int fwrite_device(char *line){
FILE *fd;
fd = fopen("/dev/h1502display", "w");
if (fd == NULL) {
writesyslog(LOG_ERR, "write_device: opening /dev/h1502display failed");
return -1;
}
if(fwrite(line, sizeof(char), strlen(line), fd) != strlen(line)){
writesyslog(LOG_ERR, "write_device: writing /dev/h1502display failed");
fclose(fd);
return -1;
}
fclose(fd);
return 0;
}
//write data to de h1502display device
int write_line(int y, int x, int invert, char *txt){
char *buf;
int ret;
if(strlen(txt) <= 0 ){
return -1;
}
buf = malloc((strlen(txt) + 8) * sizeof(char));
if(buf == NULL){
writesyslog(LOG_ERR, "write_line: out off memory");
return -1;
}
sprintf(buf, "%03d%03d%d%s", x, y, invert, txt);
ret = write_device(buf);
free(buf);
return ret;
}
void clear_display(void){
#ifndef TEST
write_line(ln[0], MENU_OFFSET, 0, " ");
write_line(ln[1], 0, 0, " ");
write_line(ln[2], 0, 0, " ");
write_line(ln[3], MENU_OFFSET, 0, " ");
#endif
}
void write_display(int line, int pos, int invert, char *txt){
#ifdef TEST
printf("Display write : %s\n", txt);
#else
write_line(line, pos, invert, txt);
#endif
}

10
log.h
View File

@@ -3,14 +3,4 @@
void writesyslog(int priority, const char *logtext);
struct config_t;
int writeserverlog(struct config_t *config, const char *logtext);
static int ln[] = {
0, 8, 16, 24,
};
void clear_display(void);
void write_display(int line, int pos, int invert, char *txt);
#endif

375
main.c
View File

@@ -1,16 +1,12 @@
#define _GNU_SOURCE
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <signal.h>
#include <syslog.h>
#include <string.h>
#include <sys/file.h>
#include <poll.h>
#include <pthread.h>
#include "runtime.h"
#include "config.h"
#include "web.h"
@@ -20,179 +16,24 @@
#include "log.h"
#include "info.h"
#include "jsontypes.h"
#include "inputs.h"
#include "reader.h"
#include "global.h"
#include "display.h"
#define ERROR -1
/*baudrate 19200, 8 bits, no parity, 1 stop bit */
#define BAUDRATE B19200
#define STARTMSG "Starting acsreader version " VERSION
volatile unsigned int relayswitchflag = 0;
volatile int displaytime;
void timerhandler(int signal){
if (signal == SIGALRM) {
relayswitchflag = 1;
displaytime = 0;
}else{
char *log;
if(asprintf(&log, "Timerhandler: wrong signal returned: %d\n", signal) > 0 ){
writesyslog(LOG_ERR, log);
}
free(log);
}
}
void starttimer(unsigned int switchtime){
if(switchtime > 0){
if (signal(SIGALRM, timerhandler) == SIG_ERR){
writesyslog(LOG_ERR, "starttimer - can't catch SIGALRM\n");
}
alarm(switchtime);
}else{
relayswitchflag = 1;
}
}
void set_displaytime(int time){
displaytime = time;
}
/************************************************/
/* strip the data string from the mf700 reader */
/************************************************/
void procesReaderData(unsigned char *readerdata, struct config_t *config, int *serialport){
struct returnjson_t retdata;
server_credential_request(readerdata, config, &retdata);
#ifdef TEST
printf("retdata Device: %s\n", retdata.device);
printf("retdata UID: %s\n", retdata.uid);
printf("retdata Cardnumber: %d\n", retdata.cardnumber);
printf("retdata Sectorkey: %s\n", retdata.sectorkey);
printf("retdata Opentime: %d\n", retdata.opentime);
printf("retdatat State: %d\n", retdata.state);
#endif
int len;
unsigned int retval = retdata.state;
if(retval == ACCESSGRANTED){
if(mf700_controlcommand(serialport, GREENLED1BEEP) == ERROR){
exitprogram(EXIT_FAILURE);
}
if(gpio_switchrelay(RELAY_ON, (unsigned int)config->relay, config->relayinvert) == ERROR){
exitprogram(EXIT_FAILURE);
}
if(retdata.opentime <= 0){
starttimer(1);
}else{
starttimer((unsigned int)retdata.opentime);
}
char *log;
if(asprintf(&log, "CARD ID %d", retdata.cardnumber) > 0){
clear_display();
write_display(ln[1], 0, 0, log);
write_display(ln[2], 0, 0, "access granted");
}
free(log);
if(asprintf(&log, "%d - access granted", retdata.cardnumber) > 0 ){
writesyslog(LOG_INFO, log);
}
free(log);
}
else if(retval == ACCESSDENIED){
if(mf700_controlcommand(serialport, REDLED3BEEPS) == ERROR){
exitprogram(EXIT_FAILURE);
}
starttimer(2);
char *log;
if(asprintf(&log, "CARD ID %d", retdata.cardnumber) > 0){
clear_display();
write_display(ln[1], 0, 0, log);
write_display(ln[2], 0, 0, "access denied");
}
free(log);
if(asprintf(&log, "%d - access denied", retdata.cardnumber) > 0 ){
writesyslog(LOG_INFO, log);
}
free(log);
}
else if (retval == UNKNOWNERROR || retval == CONNECTIONTIMEOUT || retval == RESOLVEERROR || retval == SERVERERROR || retval == CREDENTIALERROR){
if(mf700_controlcommand(serialport, EVERYLEDON) == ERROR){
exitprogram(EXIT_FAILURE);
}
if(mf700_controlcommand(serialport, BUZZER3TIME) == ERROR){
exitprogram(EXIT_FAILURE);
}
starttimer(10);
char *log;
char *ln1, *ln2;
len = 0;
switch(retval){
case UNKNOWNERROR:
len = asprintf(&log, "Unknown error");
asprintf(&ln1, "Unknown error");
asprintf(&ln2, "%s", config->serveraddress);
break;
case CONNECTIONTIMEOUT:
len = asprintf(&log, "Connection timeout to server: %s", config->serveraddress);
asprintf(&ln1, "Connection timout");
asprintf(&ln2, "%s", config->serveraddress);
break;
case RESOLVEERROR:
len = asprintf(&log, "Can't resolve server address: %s", config->serveraddress);
asprintf(&ln1, "Resolve error");
asprintf(&ln2, "%s", config->serveraddress);
break;
case SERVERERROR:
len = asprintf(&log, "Error in ACS server: %s", config->serveraddress);
asprintf(&ln1, "Error in server");
asprintf(&ln2, "%s", config->serveraddress);
break;
case CREDENTIALERROR:
len = asprintf(&log, "Error in credential: %s", config->serveraddress);
asprintf(&ln1, "Error in credential");
asprintf(&ln2, "%s", config->serveraddress);
break;
default:
len = asprintf(&log, "switch default - server errors");
asprintf(&ln1, "Switch default server");
asprintf(&ln2, "cannot happen !");
}
if(len > 0){
clear_display();
write_display(ln[1], 0, 0, ln1);
write_display(ln[2], 0, 0, ln2);
writesyslog(LOG_ERR, log);
}
free(ln1);
free(ln2);
free(log);
}else{
char *log;
if(asprintf(&log, "Unknown ReturnState from server: %d\n", retval) > 0 ){
writesyslog(LOG_ERR, log);
}
free(log);
}
}
#define STARTMSG "Starting ACSreader version " VERSION
/*********************************/
/* MAIN */
/**********************************/
int main(int argc, char **argv){
writesyslog(LOG_INFO, "Starting ACSreader\n");
clear_display();
write_display(ln[1], 0, 0, "Starting");
write_display(ln[2], 0, 0, "ACSreader");
set_displaytime(100);
writesyslog(LOG_INFO, STARTMSG);
int fd = display_open();
display_clear(fd);
display_write(fd, 1, 0, 0, "Starting");
display_write(fd, 2, 0, 0, "ACSreader");
display_timer(fd, 5);
close(fd);
createpidfile("/var/run/acsreader.pid");
sighandlerinit();
@@ -232,144 +73,104 @@ int main(int argc, char **argv){
struct config_t config;
if(config_read(&config, filepath) <= 0){
printf("Config error\n");
char *log;
if(asprintf(&log, "Config error: file path %s", filepath) > 0 ){
writesyslog(LOG_ERR, log);
}
printf("Config error: file path %s\r\n", filepath);
exitprogram(EXIT_FAILURE);
}
config_print(&config, filepath);
if(gpio_initrelay((unsigned int)config.relay, (unsigned int)config.relayinvert) == ERROR){
printf("GPIO relay error\n");
char *log;
if(asprintf(&log, "GPIO relay init error : relay %ld : invert %d", config.relay, config.relayinvert) > 0 ){
writesyslog(LOG_ERR, log);
}
free(log);
exitprogram(EXIT_FAILURE);
}
doorlockedflag = ACS_TRUE;
if(gpio_initinput((unsigned int)config.manualinput) == ERROR){
printf("GPIO input error\n");
exitprogram(EXIT_FAILURE);
}
int serialport = open(config.serialport, O_RDWR | O_NOCTTY | O_SYNC);
if (serialport < 0) {
char *log;
if(asprintf(&log, "Error opening %s: %s", config.serialport, strerror(errno)) > 0 ){
if(asprintf(&log, "GPIO input init error : input %ld : level %ld", config.manualinput, config.inputlevel) > 0 ){
writesyslog(LOG_ERR, log);
}
free(log);
printf("Serial port error\n");
exitprogram(EXIT_FAILURE);
}
serial_interfaceattribs(&serialport, BAUDRATE);
struct serialport_t serial1, serial2;
if(openserialport(&serial1, config.serialport1) == ERROR){
writesyslog(LOG_ERR, "Serialport 1 error");
exitprogram(EXIT_FAILURE);
}
serial1.reader = 1;
serial1.readername = config.reader1name;
if(writeserverlog(&config, STARTMSG)){
if(openserialport(&serial2, config.serialport2) == ERROR){
writesyslog(LOG_ERR, "Serialport 2 error");
exitprogram(EXIT_FAILURE);
}
serial2.reader = 2;
serial2.readername = config.reader2name;
if(!server_send_log(&config, BOOTLOG, STARTMSG)){
char *log;
if(asprintf(&log, "Server error log writing : %s", config.serveraddress) > 0 ){
if(asprintf(&log, "Connection with server : %s:%ld", config.serveraddress, config.serverport) > 0 ){
writesyslog(LOG_INFO, log);
}
free(log);
}
//start threads
pthread_t serialthread1, serialthread2, watchthread, inputsthread;
/* Initialize mutex and condition variable objects */
pthread_mutex_init(&sharedbuffermutex, NULL);
pthread_cond_init (&sharedbuffersignal, NULL);
int ret = pthread_create(&watchthread, NULL, serialdatawatch, (void*) &config);
if(ret){
char *log;
if(asprintf(&log, "Error - watchthread pthread_create() return code: %d", ret) > 0 ){
writesyslog(LOG_ERR, log);
}
writesyslog(LOG_ERR, "Error - watchthread pthread_create()");
exitprogram(EXIT_FAILURE);
}
ret = pthread_create(&serialthread1, NULL, readserialport, (void*) &serial1);
if(ret){
char *log;
if(asprintf(&log, "Error - serialthread1 pthread_create() return code: %d", ret) > 0 ){
writesyslog(LOG_ERR, log);
}
exitprogram(EXIT_FAILURE);
}
ret = pthread_create(&serialthread2, NULL, readserialport, (void*) &serial2);
if(ret){
char *log;
if(asprintf(&log, "Error - serialthread2 pthread_create() return code: %d", ret) > 0 ){
writesyslog(LOG_ERR, log);
}
free(log);
printf("Writeserverlog failed :%s \n", config.serveraddress);
}
//setup input poll
struct pollfd fdset[1];
fdset[0].fd = input_fd_open(config.manualinput);;
if(fdset[0].fd < 0){
printf("manualinput failed\n");
exitprogram(EXIT_FAILURE);
}
fdset[0].events = POLLPRI;
ret = pthread_create(&inputsthread, NULL, readinputs, (void*) &config);
if(ret){
char *log;
if(asprintf(&log, "Error - inputsthread pthread_create() return code: %d", ret) > 0 ){
writesyslog(LOG_ERR, log);
}
exitprogram(EXIT_FAILURE);
}
unsigned char buff[80];
unsigned int idx = 0;
pthread_join(watchthread, NULL);
pthread_join(serialthread1, NULL);
pthread_join(serialthread2, NULL);
pthread_join(inputsthread, NULL);
/* simple noncanonical input */
do {
unsigned char chr;
//serial read from mf700 reader
ssize_t len = read(serialport, &chr, sizeof(chr));
if (len > 0){
if ((chr == '\r' || chr == '\n') && idx == 72){
buff[idx] = '\0';
procesReaderData(buff, &config, &serialport);
idx = 0;
}else if (idx > 72){
idx = 0;
}else if (chr == ACK || chr == NACK ){
idx = 0;
}else {
buff[idx] = chr;
idx++;
}
} else if (len == -1) {
if(errno == EINTR){
continue;
}else {
char *log;
if(asprintf(&log, "Error from read: %ld: %s\n", (long int)len, strerror(errno)) > 0 ){
writesyslog(LOG_ERR, log);
}
free(log);
}
}
//input poll
int rc = poll(fdset, 1, 0);
if (rc < 0){
if(errno != EINTR){
char *log;
if(asprintf(&log, "inputpoll failed: %s", strerror(errno)) > 0 ){
writesyslog(LOG_ERR, log);
}
exitprogram(EXIT_FAILURE);
}
}else if(rc > 0){
if (fdset[0].revents & POLLPRI) {
lseek(fdset[0].fd, 0, SEEK_SET);
unsigned char buf[3];
if(read(fdset[0].fd, buf, 3) < 0){
char *log;
if(asprintf(&log, "input read failed: %s", strerror(errno)) != 0 ){
writesyslog(LOG_ERR, log);
}
free(log);
exitprogram(EXIT_FAILURE);
}
if((buf[0] == '0' && config.inputlevel == 1) || (buf[0] == '1' && config.inputlevel == 0)){
if(gpio_switchrelay(RELAY_ON, (unsigned int)config.relay, config.relayinvert) == ERROR){
exitprogram(EXIT_FAILURE);
}
starttimer((unsigned int)config.switchtime);
set_displaytime(100);
write_display(ln[1], 0, 0, "Manual open");
char *ln2;
asprintf(&ln2, "In: %ld - Relay: %ld",config.manualinput, config.relay);
write_display(ln[2], 0, 0, ln2);
free(ln2);
writesyslog(LOG_INFO, "Manual open");
writeserverlog(&config, "Manual open");
}
}
}
//relay switch action
if(relayswitchflag == 1){
if(gpio_switchrelay(RELAY_OFF, (unsigned int)config.relay, config.relayinvert) == ERROR){
exitprogram(EXIT_FAILURE);
}
if(mf700_controlcommand(&serialport, EVERYLEDOFF) == ERROR){
exitprogram(EXIT_FAILURE);
}
relayswitchflag = 0;
}
//display timer
if(displaytime == 0){
clear_display();
displaytime = -1;
}else if(displaytime > 0){
displaytime--;
}
/* repeat read to get full message */
printf("can not happen\n");
} while (1);
}

104
mf700.c
View File

@@ -1,30 +1,124 @@
#define _GNU_SOURCE
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <syslog.h>
#include <signal.h>
#include <time.h>
#include "mf700.h"
#include "serial.h"
#include "log.h"
#include "reader.h"
int mf700_controlcommand(int *serial, mf700controlset command){
int mf700_writecommand(struct reader_t *reader, mf700controlset command){
char cmd[4];
cmd[0] = STX;
cmd[1] = 'J';
cmd[2] = command;
cmd[3] = '\r';
ssize_t wlen = write(*serial, cmd, 4);
ssize_t wlen = write(reader->fd, cmd, 4);
if (wlen != 4) {
char *log;
if(asprintf(&log, "Error from write to mf700: %ld : %d", (long int)wlen, errno) > 0 ){
if(asprintf(&log, "Error writing to mf700: %ld : %d", (long int)wlen, errno) > 0 ){
writesyslog(LOG_ERR, log);
}
free(log);
return(-1);
}
usleep(5000); //little sleep between commands
return(0);
return 0;
}
struct readerdata_t {
struct reader_t reader;
timer_t timer_id;
};
static volatile int reader1timersemaphore = 0;
static volatile int reader2timersemaphore = 0;
void mf700_timer_handler(union sigval arg){
struct readerdata_t *readerdata = (struct readerdata_t *)arg.sival_ptr;
if(readerdata->reader.reader == 1){
reader1timersemaphore -= 1;
if(reader1timersemaphore == 0){
mf700_writecommand(&readerdata->reader, EVERYLEDOFF);
}
}
if(readerdata->reader.reader == 2){
reader2timersemaphore -= 1;
if(reader2timersemaphore == 0){
mf700_writecommand(&readerdata->reader, EVERYLEDOFF);
}
}
timer_delete(readerdata->timer_id);
free(readerdata);
}
void mf700_timer(unsigned int time, struct reader_t *reader){
struct readerdata_t *readerdata = malloc(sizeof(struct readerdata_t));
struct itimerspec ts;
struct sigevent se;
memcpy(&readerdata->reader, reader, sizeof(struct reader_t));
memset(&ts, 0, sizeof(struct itimerspec));
memset(&se, 0, sizeof(struct sigevent));
se.sigev_notify = SIGEV_THREAD;
se.sigev_value.sival_ptr = readerdata;
se.sigev_notify_function = mf700_timer_handler;
se.sigev_notify_attributes = NULL;
ts.it_value.tv_sec = (long int)time;
ts.it_value.tv_nsec = (long int)0;
ts.it_interval.tv_sec = 0;
ts.it_interval.tv_nsec = 0;
int status = timer_create(CLOCK_REALTIME, &se, &readerdata->timer_id);
if (status == -1){
char *log;
if(asprintf(&log, "Error creating mf700 timer: %d", errno) > 0 ){
writesyslog(LOG_ERR, log);
}
free(log);
return;
}
status = timer_settime(readerdata->timer_id, 0, &ts, 0);
if (status == -1){
char *log;
if(asprintf(&log, "Error setting mf700 timer: %d", errno) > 0 ){
writesyslog(LOG_ERR, log);
}
free(log);
return;
}
if(reader->reader == 1)
reader1timersemaphore += 1;
if(reader->reader == 2)
reader2timersemaphore += 1;
}
int mf700_controlcommand(struct reader_t *reader, unsigned int time, mf700controlset command){
if( mf700_writecommand(reader, command) == -1){
return -1;
}
usleep(5000); //little sleep between commands
if(time <= 0){
mf700_timer(1, reader);
}else{
mf700_timer(time, reader);
}
return 0;
}

View File

@@ -1,6 +1,7 @@
#ifndef MF700_FILE
#define MF700_FILE
#include "reader.h"
typedef enum {
EVERYLEDOFF = 0x30,
@@ -15,7 +16,6 @@ typedef enum {
EVERYLEDON = 0x39,
}mf700controlset;
int mf700_controlcommand(int *serial, mf700controlset command);
int mf700_controlcommand(struct reader_t *reader, unsigned int time, mf700controlset command);
#endif

86
reader.c Normal file
View File

@@ -0,0 +1,86 @@
#define _GNU_SOURCE
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <syslog.h>
#include <string.h>
#include "runtime.h"
#include "config.h"
#include "web.h"
#include "gpio.h"
#include "serial.h"
#include "mf700.h"
#include "log.h"
#include "info.h"
#include "jsontypes.h"
#include "inputs.h"
#include "reader.h"
#include "relay.h"
#include "display.h"
void readerrequest(struct reader_t *reader, struct config_t *config){
server_credential_request(reader, config);
#ifdef TEST
printf("reader: %d\n", reader->reader);
printf("Reader name: %s\n", reader->readername);
printf("Cardnumber: %d\n", reader->cardnumber);
printf("Opentime: %d\n", reader->opentime);
printf("State: %d\n", reader->state);
#endif
if(reader->state == ACCESSGRANTED){
if(mf700_controlcommand(reader, reader->opentime, GREENLED1BEEP) == ERROR){
exitprogram(EXIT_FAILURE);
}
if(relay_switch(RELAY_ON, reader->opentime, config) == ERROR){
exitprogram(EXIT_FAILURE);
}
char *log;
if(asprintf(&log, "CARD ID %d - %d sec", reader->cardnumber, reader->opentime) > 0){
int fd = display_open();
display_clear(fd);
display_write(fd, 1, 0, 0, log);
display_write(fd, 2, 0, 0, "access granted");
display_timer(fd, reader->opentime);
close(fd);
}
free(log);
if(asprintf(&log, "%s - Card %d - access granted - %d sec", reader->readername, reader->cardnumber, reader->opentime) > 0 ){
writesyslog(LOG_INFO, log);
}
free(log);
}
else if(reader->state == ACCESSDENIED){
if(mf700_controlcommand(reader, 2, REDLED3BEEPS) == ERROR){
exitprogram(EXIT_FAILURE);
}
char *log;
if(asprintf(&log, "CARD ID %d", reader->cardnumber) > 0){
int fd = display_open();
display_clear(fd);
display_write(fd, 1, 0, 0, log);
display_write(fd, 2, 0, 0, "access denied");
display_timer(fd, 3);
close(fd);
}
free(log);
if(asprintf(&log, "%s - Card %d - access denied", reader->readername, reader->cardnumber) > 0 ){
writesyslog(LOG_INFO, log);
}
free(log);
}
else{
if(mf700_controlcommand(reader, 0, EVERYLEDON) == ERROR){
exitprogram(EXIT_FAILURE);
}
if(mf700_controlcommand(reader, 5, BUZZER3TIME) == ERROR){
exitprogram(EXIT_FAILURE);
}
}
}

19
reader.h Normal file
View File

@@ -0,0 +1,19 @@
#ifndef READER_FILE
#define READER_FILE
#include <stdint.h>
#include "config.h"
struct reader_t{
int fd;
unsigned char buff[80];
int reader;
int state;
unsigned int opentime;
int cardnumber;
char *readername;
};
void readerrequest(struct reader_t *reader, struct config_t *config);
#endif

139
relay.c Normal file
View File

@@ -0,0 +1,139 @@
#define _GNU_SOURCE
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <syslog.h>
#include <time.h>
#include "gpio.h"
#include "log.h"
#include "reader.h"
#include "config.h"
#include "relay.h"
#include "jsontypes.h"
#include "web.h"
#include "global.h"
int relay_set_state(int state, struct config_t *config){
if(state == RELAY_ON){
doorlockedflag = ACS_FALSE;
if (config->relayinvert == cfg_false){
#ifdef TEST
printf("Relay %ld - HIGH\n", config->relay);
#endif
if(GPIOWrite(get_relaypin((unsigned int)config->relay), HIGH) < 0){
return(-1);
}
}
else{
#ifdef TEST
printf("Relay %ld - LOW\n", config->relay);
#endif
if(GPIOWrite(get_relaypin((unsigned int)config->relay), LOW) < 0){
return(-1);
}
}
server_send_lockstate(config, UNLOCKED);
}
else{ //RELAY_OFF
if (config->relayinvert == cfg_false){
#ifdef TEST
printf("Relay %ld - LOW\n", config->relay);
#endif
if(GPIOWrite(get_relaypin((unsigned int)config->relay), LOW) < 0){
return(-1);
}
}
else{
#ifdef TEST
printf("Relay %ld - HIGH\n", config->relay);
#endif
if(GPIOWrite(get_relaypin((unsigned int)config->relay), HIGH) < 0){
return(-1);
}
}
server_send_lockstate(config, LOCKED);
doorlockedflag = ACS_TRUE;
}
return(0);
}
struct relaydata_t {
struct config_t config;
timer_t timer_id;
};
static volatile int relaytimersemaphore = 0;
void relay_timer_handler(union sigval arg){
struct relaydata_t *relaydata = (struct relaydata_t *)arg.sival_ptr;
relaytimersemaphore -= 1;
if(relaytimersemaphore == 0){
relay_set_state(RELAY_OFF, &relaydata->config);
}
timer_delete(relaydata->timer_id);
free(relaydata);
}
void relay_timer(unsigned int time, struct config_t *config){
struct relaydata_t *relaydata = malloc(sizeof(struct relaydata_t));
struct itimerspec ts;
struct sigevent se;
memcpy(&relaydata->config, config, sizeof(struct config_t));
memset(&ts, 0, sizeof(struct itimerspec));
memset(&se, 0, sizeof(struct sigevent));
se.sigev_notify = SIGEV_THREAD;
se.sigev_value.sival_ptr = relaydata;
se.sigev_notify_function = relay_timer_handler;
se.sigev_notify_attributes = NULL;
ts.it_value.tv_sec = (long int)time;
ts.it_value.tv_nsec = (long int)0;
ts.it_interval.tv_sec = 0;
ts.it_interval.tv_nsec = 0;
int status = timer_create(CLOCK_REALTIME, &se, &relaydata->timer_id);
if (status == -1){
char *log;
if(asprintf(&log, "Error creating relay timer: %d", errno) > 0 ){
writesyslog(LOG_ERR, log);
}
free(log);
return;
}
status = timer_settime(relaydata->timer_id, 0, &ts, 0);
if (status == -1){
char *log;
if(asprintf(&log, "Error setting relay timer: %d", errno) > 0 ){
writesyslog(LOG_ERR, log);
}
free(log);
return;
}
relaytimersemaphore += 1;
}
int relay_switch(int state, unsigned int time, struct config_t *config){
if(time <= 0){
return 0;
}
if(relay_set_state(state, config) != 0){
return -1;
}
relay_timer(time, config);
return 0;
}

6
relay.h Normal file
View File

@@ -0,0 +1,6 @@
#ifndef RELAY_FILE
#define RELAY_FILE
int relay_switch(int state, unsigned int time, struct config_t *config);
#endif

View File

@@ -17,7 +17,9 @@ void exitprogram(int status){
close(pid_file);
writesyslog(LOG_INFO, "Goodbye and thanks for all the fish");
#ifdef TEST
printf("bye....\n");
#endif
exit(status);
}
@@ -27,7 +29,6 @@ void createpidfile(const char *location){
if(fl) {
if(EWOULDBLOCK == errno){
writesyslog(LOG_ERR, "Attempting to run duplicate instance of acsreader");
printf("Attempting to run duplicate instance of acsreader");
exit(EXIT_FAILURE);
}
}

View File

@@ -1,6 +1,8 @@
#ifndef RUNTIME_FILE
#define RUNTIME_FILE
#define ERROR -1
void exitprogram(int status);
void createpidfile(const char *location);
void sighandler(int signo);

View File

@@ -2,7 +2,7 @@
# /etc/init.d/S51acsreader
start(){
if [ ! -e /settings/acsreader.conf ]; then
if [ ! -f /settings/acsreader.conf ]; then
echo "Copy acsreader.conf to /settings"
logger -p local0.info -t acsreader Copy acsreader.conf to /settings
cp /etc/acsreader/acsreader.conf /settings/acsreader.conf

1
scripts/acsconnection Normal file
View File

@@ -0,0 +1 @@
0 * * * * /etc/acsreader/acsconnectionscript

9
scripts/acsconnectionscript Executable file
View File

@@ -0,0 +1,9 @@
#!/bin/sh
source /settings/acsreader.conf
if ! ping -c4 $serveraddress; then
echo $serveraddress "ping fail"
/etc/init.d/S45ifplugd restart
fi

View File

@@ -1,4 +1,4 @@
#!/bin/ash
#!/bin/sh
logrotate /etc/acsreader/logrotate.conf

View File

@@ -1 +1 @@
*/10 * * * * /etc/acsreader/acsstatusscript
*/1 * * * * /etc/acsreader/acsstatusscript

View File

@@ -1,4 +1,4 @@
#!/bin/ash
#!/bin/sh
# Unknown = 0
# Running = 1
@@ -11,22 +11,27 @@ source /settings/acsreader.conf
service='acsreader'
devid=$(cat /sys/class/net/eth0/address | sed 's/://g' | tr a-z A-Z | tail -c 7)
#Check if process is running
if [ $(ps -ef | grep -v grep | grep $service | wc -l) -gt 0 ]; then
#Send status that the service is running.
curl -X POST -H "Content-Type: application/json" -d '{"Device":"'"$devid"'","Name":"'"$devicename"'","Status":1}' https://$serveraddress/api/status
else
#Send status that the service is not started.
curl -X POST -H "Content-Type: application/json" -d '{"Device":"'"$devid"'","Name":"'"$devicename"'","Status":2}' https://$serveraddress/api/status
#Try to restart the service
/etc/init.d/S51$service start
case "$(pidof $service | wc -w)" in
0) #echo "service stoped case"
#Send status that the service is not started.
$(curl -X POST -H "Content-Type: application/json" -d '{"Device":"'"$devid"'","Name":"'"$devicename"'","ProductClass":'$productclass',"Status":2}' https://$serveraddress:$serverport/v2/api/status)
#Check if restart was successfully
if [ $(ps -ef | grep -v grep | grep $service | wc -l) -gt 0 ]; then
#Send status that the restart was successfully
curl -X POST -H "Content-Type: application/json" -d '{"Device":"'"$devid"'","Name":"'"$devicename"'","Status":3}' https://$serveraddress/api/status
else
#Send status that the restart has failed
curl -X POST -H "Content-Type: application/json" -d '{"Device":"'"$devid"'","Name":"'"$devicename"'","Status":4}' https://$serveraddress/api/status
fi
fi
#Try to restart the service
/etc/init.d/S51$service start
#Check if restart was successfully
case "$(pidof $service | wc -w)" in
0) #echo "service not started"
$(curl -X POST -H "Content-Type: application/json" -d '{"Device":"'"$devid"'","Name":"'"$devicename"'","ProductClass":'$productclass',"Status":4}' https://$serveraddress:$serverport/v2/api/status)
;;
1) #echo "service started"
$(curl -X POST -H "Content-Type: application/json" -d '{"Device":"'"$devid"'","Name":"'"$devicename"'","ProductClass":'$productclass',"Status":3}' https://$serveraddress:$serverport/v2/api/status)
;;
esac
;;
1) #echo "service running case"
#Send status that the service is running.
$(curl -X POST -H "Content-Type: application/json" -d '{"Device":"'"$devid"'","Name":"'"$devicename"'","ProductClass":'$productclass',"Status":1}' https://$serveraddress:$serverport/v2/api/status)
;;
esac

View File

@@ -1,4 +1,5 @@
/var/log/acsreader.log {
daily
su root root
missingok
create
@@ -7,7 +8,7 @@
dateext
dateformat -%Y%m%d
lastaction
/etc/init.d/S01logging restart
/etc/init.d/S01syslogd restart
/etc/init.d/S51acsreader restart
endscript
}

View File

@@ -7,8 +7,14 @@
#include <termios.h>
#include <unistd.h>
#include <syslog.h>
#include <pthread.h>
#include "serial.h"
#include "log.h"
#include "config.h"
#include "gpio.h"
#include "runtime.h"
#include "mf700.h"
#include "reader.h"
int serial_interfaceattribs(int *fd, int speed){
struct termios tty;
@@ -37,8 +43,8 @@ int serial_interfaceattribs(int *fd, int speed){
cfmakeraw(&tty);
/* fetch bytes as they become available */
tty.c_cc[VMIN] = 0;
tty.c_cc[VTIME] = 1; //block time out 0.1 sec
tty.c_cc[VMIN] = 73; //read() unblocks after receiving 73 chars
tty.c_cc[VTIME] = 5; //read() unblocks after 0.5 sec after first char
if (tcsetattr(*fd, TCSANOW, &tty) != 0) {
char *log;
@@ -50,3 +56,75 @@ int serial_interfaceattribs(int *fd, int speed){
}
return 0;
}
int openserialport(struct serialport_t *serial, char *serialpath){
serial->fd = open(serialpath, O_RDWR | O_NOCTTY | O_SYNC);
if (serial->fd < 0) {
char *log;
if(asprintf(&log, "Error opening %s: %s", serialpath, strerror(errno)) > 0 ){
writesyslog(LOG_ERR, log);
}
free(log);
return -1;
}
serial_interfaceattribs(&serial->fd, BAUDRATE);
return 0;
}
struct serialport_t sharedbuffer;
//read serial port thread
void *readserialport(void *ptr){
unsigned char chr;
struct serialport_t *serial;
serial = (struct serialport_t *) ptr;
unsigned int idx = 0;
while(1){
ssize_t len1 = read(serial->fd, &chr, sizeof(chr));
if (len1 > 0){
if ((chr == '\r' || chr == '\n') && idx == 72){
serial->buff[idx] = '\0';
pthread_mutex_lock(&sharedbuffermutex);
memcpy(&sharedbuffer, serial, sizeof(struct serialport_t));
pthread_cond_signal(&sharedbuffersignal);
pthread_mutex_unlock(&sharedbuffermutex);
idx = 0;
}else if (idx > 72){
idx = 0;
}else if (chr == ACK || chr == NACK ){
idx = 0;
}else {
serial->buff[idx] = chr;
idx++;
}
}
}
}
void *serialdatawatch(void *ptr){
struct config_t *config;
config = (struct config_t *) ptr;
while(1) {
pthread_mutex_lock(&sharedbuffermutex);
//wait for signal from serial read
pthread_cond_wait(&sharedbuffersignal, &sharedbuffermutex);
struct reader_t reader;
reader.fd = sharedbuffer.fd;
reader.reader = sharedbuffer.reader;
memcpy(reader.buff, sharedbuffer.buff, sizeof(reader.buff));
reader.readername = sharedbuffer.readername;
readerrequest(&reader, config);
//remove all credential data from buffer
memset(&sharedbuffer, 0, sizeof(struct serialport_t));
pthread_mutex_unlock(&sharedbuffermutex);
}
}

View File

@@ -1,11 +1,29 @@
#ifndef SERIAL_FILE
#define SERIAL_FILE
#include <pthread.h>
#define STX '\2'
#define ETX '\3'
#define ACK '\x6'
#define NACK '\15'
/*baudrate 19200, 8 bits, no parity, 1 stop bit */
#define BAUDRATE B19200
struct serialport_t{
int fd;
unsigned char buff[80];
int reader;
char *readername;
};
pthread_mutex_t sharedbuffermutex;
pthread_cond_t sharedbuffersignal;
int serial_interfaceattribs(int *fd, int speed);
int openserialport(struct serialport_t *serial, char *serialpath);
void *readserialport(void *ptr);
void *serialdatawatch(void *ptr);
#endif

307
web.c
View File

@@ -1,41 +1,22 @@
/* <DESC>
* Shows how the write callback function can be used to download data into a
* chunk of memory instead of storing it in a file.
* </DESC>
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <syslog.h>
#include <inttypes.h>
#include <curl/curl.h>
#include <json-c/json.h>
#include <cjson/cJSON.h>
#include <pthread.h>
#include "config.h"
#include "web.h"
#include "log.h"
#include "jsontypes.h"
#include "reader.h"
#include "display.h"
#include "global.h"
//#define TRUE 1
//#define FALSE 0
void server_credential_request(unsigned char *readerdata, struct config_t *config, struct returnjson_t *retobj){
char *url;
int len = asprintf(&url, "https://%s/api/CredentialRequest", config->serveraddress);
struct json_object *sendobj;
sendobj = json_object_new_object();
json_object_object_add(sendobj, "Device", json_object_new_string(config->device));
json_object_object_add(sendobj, "Name", json_object_new_string(config->name));
json_object_object_add(sendobj, "ReaderData", json_object_new_string((const char *)readerdata));
json_object_object_add(sendobj, "ProductClass", json_object_new_int64(config->ProductClass));
web_request_json(url, json_object_to_json_string(sendobj), retobj);
json_object_put(sendobj); //delete json object
free(url);
}
//------------------- Web request Callback -------------------
struct memory_t {
char *memory;
size_t size;
@@ -62,14 +43,18 @@ static size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, voi
//---------------- Web Request JSON -------------------------------
void web_request_json(char *url, const char *json, struct returnjson_t *retobj){
void web_request_json(char *url, const char *json, struct reader_t *reader){
CURL *curl_handle;
struct memory_t chunk;
struct curl_slist *headers = NULL; /* http headers to send with request */
reader->state = 0;
reader->opentime = 0;
reader->cardnumber = 0;
#ifdef TEST
printf("Server request = %s\n", url);
printf("Json data = %s\n", json);
printf("Json send data = %s\n", json);
#endif
chunk.memory = malloc(1); /* will be grown as needed by the realloc above */
@@ -88,91 +73,241 @@ void web_request_json(char *url, const char *json, struct returnjson_t *retobj){
curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); //send all data to this function
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk); //we pass our 'chunk' struct to the callback function
curl_easy_setopt(curl_handle, CURLOPT_CONNECTTIMEOUT, 5); // complete connection within 5 seconds
curl_easy_setopt(curl_handle, CURLOPT_FAILONERROR, ACS_TRUE); //fail on error code >= 400
char errbuf[CURL_ERROR_SIZE];
curl_easy_setopt(curl_handle, CURLOPT_ERRORBUFFER, errbuf);
errbuf[0] = '\0';
CURLcode res = curl_easy_perform(curl_handle);
if(res == CURLE_OK) {
struct json_object *parseobj = NULL;
parseobj = json_tokener_parse(chunk.memory);
cJSON *retjson = cJSON_Parse(chunk.memory);
if(retjson == NULL){
writesyslog(LOG_ERR, "web_request: cJSON_Parse failed\n");
reader->state = SERVERERROR;
}
else{
#ifdef TEST
printf("Server answer: %s\n", json_object_to_json_string(parseobj));
printf("Server answer: %s\n", cJSON_PrintUnformatted(retjson));
#endif
if(parseobj != NULL){
struct json_object *tmpobj;
tmpobj = json_object_new_object();
if(json_object_object_get_ex(parseobj, "Device", &tmpobj) == TRUE && tmpobj != NULL) {
strcpy(retobj->device, json_object_get_string(tmpobj));
if(cJSON_GetObjectItem(retjson,"State") != NULL){
reader->state = cJSON_GetObjectItem(retjson,"State")->valueint;
}
else{
retobj->device[0] = '\0';
if(cJSON_GetObjectItem(retjson,"OpenTime") != NULL){
reader->opentime = (unsigned int)cJSON_GetObjectItem(retjson,"OpenTime")->valueint;
}
if(json_object_object_get_ex(parseobj, "UID", &tmpobj) == TRUE && tmpobj != NULL) {
strcpy(retobj->uid, json_object_get_string(tmpobj));
}
else{
retobj->uid[0] = '\0';
}
if(json_object_object_get_ex(parseobj, "CardNumber", &tmpobj) == TRUE && tmpobj != NULL) {
retobj->cardnumber = json_object_get_int(tmpobj);
}
else{
retobj->cardnumber = 0;
}
if(json_object_object_get_ex(parseobj, "SectorKey", &tmpobj) == TRUE && tmpobj != NULL) {
strcpy(retobj->sectorkey, json_object_get_string(tmpobj));
}
else{
retobj->sectorkey[0] = '\0';
}
if(json_object_object_get_ex(parseobj, "OpenTime", &tmpobj) == TRUE && tmpobj != NULL) {
retobj->opentime = json_object_get_int(tmpobj);
}
else{
retobj->opentime = 0;
}
if(json_object_object_get_ex(parseobj, "State", &tmpobj) == TRUE && tmpobj != NULL) {
retobj->state = json_object_get_int(tmpobj);
}
else{
retobj->state = 0;
if(cJSON_GetObjectItem(retjson, "CardNumber") != NULL){
reader->cardnumber = cJSON_GetObjectItem(retjson,"CardNumber")->valueint;
}
}
json_object_put(parseobj); //delete json object
cJSON_Delete(retjson);
}
else{ //curl returned a error
char *log;
if(asprintf(&log, "web_request: curl_easy_perform() failed: %s\n", curl_easy_strerror(res)) > 0 ){
if(asprintf(&log, "web_request: curl failed: %d : %s\n", res, curl_easy_strerror(res)) > 0 ){
writesyslog(LOG_ERR, log);
}
free(log);
writesyslog(LOG_ERR, errbuf);
if(res == CURLE_COULDNT_RESOLVE_HOST){
retobj->state = RESOLVEERROR;
reader->state = RESOLVEERROR;
}else if(res == CURLE_OPERATION_TIMEDOUT){
retobj->state = CONNECTIONTIMEOUT;
reader->state = CONNECTIONTIMEOUT;
}else if(res == CURLE_HTTP_RETURNED_ERROR || res == CURLE_PEER_FAILED_VERIFICATION){
reader->state = SERVERERROR;
}else{
retobj->state = SERVERERROR;
reader->state = UNKNOWNERROR;
}
retobj->device[0] = '\0';
retobj->uid[0] = '\0';
retobj->cardnumber = 0;
retobj->sectorkey[0] = '\0';
retobj->opentime = 0;
}
/* cleanup curl stuff */
curl_easy_cleanup(curl_handle);
free(chunk.memory);
/* we're done with libcurl, so clean it up */
curl_global_cleanup();
}
//----------------------- Print Errors --------------------------------------
void server_display_error(returnstate_t state, struct config_t *config){
char *log;
char *ln1, *ln2;
int len = 0;
int ret1, ret2;
switch(state){
case UNKNOWNERROR:
len = asprintf(&log, "Unknown error");
ret1 = asprintf(&ln1, "Unknown error");
ret2 = asprintf(&ln2, "%s", config->serveraddress);
break;
case CONNECTIONTIMEOUT:
len = asprintf(&log, "Connection timeout to server: %s", config->serveraddress);
ret1 = asprintf(&ln1, "Connection timout");
ret2 = asprintf(&ln2, "%s", config->serveraddress);
break;
case RESOLVEERROR:
len = asprintf(&log, "Can't resolve server address: %s", config->serveraddress);
ret1 = asprintf(&ln1, "Resolve error");
ret2 = asprintf(&ln2, "%s", config->serveraddress);
break;
case SERVERERROR:
len = asprintf(&log, "Error in ACS server: %s", config->serveraddress);
ret1 = asprintf(&ln1, "Error in server");
ret2 = asprintf(&ln2, "%s", config->serveraddress);
break;
case CREDENTIALERROR:
len = asprintf(&log, "Error in credential on server: %s", config->serveraddress);
ret1 = asprintf(&ln1, "Error in credential");
ret2 = asprintf(&ln2, "%s", config->serveraddress);
break;
case LOGERROR:
len = asprintf(&log, "Error in log on server: %s", config->serveraddress);
ret1 = asprintf(&ln1, "Error in log");
ret2 = asprintf(&ln2, "%s", config->serveraddress);
break;
case LOCKSTATEERROR:
len = asprintf(&log, "Error in lockstate on server: %s", config->serveraddress);
ret1 = asprintf(&ln1, "Error in lockstate");
ret2 = asprintf(&ln2, "%s", config->serveraddress);
break;
case OPENTIMEERROR:
len = asprintf(&log, "Error in opentime on server: %s", config->serveraddress);
ret1 = asprintf(&ln1, "Error in opentime");
ret2 = asprintf(&ln2, "%s", config->serveraddress);
break;
case DEVICEINACTIVE:
len = asprintf(&log, "Device not active on server: %s", config->serveraddress);
ret1 = asprintf(&ln1, "Device not active");
ret2 = asprintf(&ln2, "%s", config->serveraddress);
break;
default:
len = asprintf(&log, "switch default - server errors");
ret1 = asprintf(&ln1, "Switch default server");
ret2 = asprintf(&ln2, "cannot happen !");
}
if(len > 0){
int fd = display_open();
display_clear(fd);
display_write(fd, 1, 0, 0, ln1);
display_write(fd, 2, 0, 0, ln2);
display_timer(fd, DISPLAY_TIME);
close(fd);
writesyslog(LOG_ERR, log);
}
free(ln1);
free(ln2);
free(log);
}
//----------------------- Request functions ----------------------------------
void server_credential_request(struct reader_t *reader, struct config_t *config){
char *url;
if(asprintf(&url, "https://%s:%ld/v2/api/CredentialRequest", config->serveraddress, config->serverport) <= 0){
writesyslog(LOG_ERR, "server_credential_request: asprintf failed");
return;
}
cJSON *sendjson = cJSON_CreateObject();
cJSON_AddStringToObject(sendjson, "Device", config->device);
cJSON_AddStringToObject(sendjson, "Name", config->name);
cJSON_AddStringToObject(sendjson, "ReaderData", (const char *)reader->buff);
cJSON_AddNumberToObject(sendjson, "ProductClass", (double)config->ProductClass);
cJSON_AddNumberToObject(sendjson, "Reader", reader->reader);
cJSON_AddStringToObject(sendjson, "ReaderName", reader->readername);
web_request_json(url, cJSON_PrintUnformatted(sendjson), reader);
cJSON_Delete(sendjson);
free(url);
if(reader->state != ACCESSGRANTED && reader->state != ACCESSDENIED){
server_display_error(reader->state, config);
}
}
//****************** LockState *******************************
int server_send_lockstate(struct config_t *config, lockstates_t lockstate){
char *url;
if(asprintf(&url, "https://%s:%ld/v2/api/LockState", config->serveraddress, config->serverport) <= 0){
writesyslog(LOG_ERR, "server_send_lockstate: asprintf failed");
return -1;
}
cJSON *sendjson = cJSON_CreateObject();
cJSON_AddStringToObject(sendjson, "Device", config->device);
cJSON_AddStringToObject(sendjson, "Name", config->name);
cJSON_AddNumberToObject(sendjson, "ProductClass", (double)config->ProductClass);
cJSON_AddNumberToObject(sendjson, "LockState", lockstate);
struct reader_t reader;
web_request_json(url, cJSON_PrintUnformatted(sendjson), &reader);
cJSON_Delete(sendjson);
free(url);
if(reader.state != LOCKSTATEOK){
server_display_error(reader.state, config);
return -1;
}
return 0;
}
//****************** Add Log *******************************
int server_send_log(struct config_t *config, logtypes_t logtype, const char *logtext){
char *url;
if(asprintf(&url, "https://%s:%ld/v2/api/addlog", config->serveraddress, config->serverport) <= 0){
writesyslog(LOG_ERR, "server_send_log: asprintf failed");
return -1;
}
cJSON *sendjson = cJSON_CreateObject();
cJSON_AddStringToObject(sendjson, "Device", config->device);
cJSON_AddStringToObject(sendjson, "Name", config->name);
cJSON_AddStringToObject(sendjson, "Message", logtext);
cJSON_AddNumberToObject(sendjson, "ProductClass", (double)config->ProductClass);
cJSON_AddNumberToObject(sendjson, "LogType", logtype);
struct reader_t reader;
web_request_json(url, cJSON_PrintUnformatted(sendjson), &reader);
cJSON_Delete(sendjson);
free(url);
if(reader.state != LOGOK){
server_display_error(reader.state, config);
return -1;
}
return 0;
}
//****************** get OpenTime *******************************
unsigned int server_get_opentime(struct config_t *config){
char *url;
if(asprintf(&url, "https://%s:%ld/v2/api/opentime", config->serveraddress, config->serverport) <= 0){
writesyslog(LOG_ERR, "server_get_opentime: asprintf failed");
return 0;
}
cJSON *sendjson = cJSON_CreateObject();
cJSON_AddStringToObject(sendjson, "Device", config->device);
cJSON_AddStringToObject(sendjson, "Name", config->name);
cJSON_AddNumberToObject(sendjson, "ProductClass", (double)config->ProductClass);
struct reader_t reader;
web_request_json(url, cJSON_PrintUnformatted(sendjson), &reader);
cJSON_Delete(sendjson);
free(url);
if(reader.state != OPENTIMEOK){
server_display_error(reader.state, config);
return 0;
}
return reader.opentime;
}

7
web.h
View File

@@ -1,8 +1,11 @@
#ifndef WEB_FILE
#define WEB_FILE
#include "jsontypes.h"
#include "reader.h"
void server_credential_request(unsigned char *readerdata, struct config_t *config, struct returnjson_t *retobj);
void web_request_json(char *url, const char *json, struct returnjson_t *retobj);
void server_credential_request(struct reader_t *reader, struct config_t *config);
int server_send_lockstate(struct config_t *config, lockstates_t lockstate);
int server_send_log(struct config_t *config, logtypes_t logtype, const char *logtext);
unsigned int server_get_opentime(struct config_t *config);
#endif