20 Commits
v2.2 ... 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
25 changed files with 313 additions and 290 deletions

View File

@@ -6,7 +6,7 @@ CFLAGS = -DVERSION=\"$(GIT_VERSION)\" -Werror -Wall -Wextra -pedantic -Wcast-ali
-Wunreachable-code -Wduplicated-cond -Wnull-dereference -Wjump-misses-init -Wdouble-promotion\
-Wimplicit-fallthrough -Wduplicated-branches -Wrestrict
LDFLAGS = -std=gnu11 -lcurl -lconfuse -ljson-c -lpthread -lrt
LDFLAGS = -std=gnu11 -lcurl -lconfuse -lcjson -lpthread -lrt
GIT_VERSION := $(shell git describe --dirty --always --tags)

2
README
View File

@@ -1,7 +1,7 @@
ACSreader
- Install confuse https://github.com/martinh/libconfuse
- Install json-c https://github.com/json-c/json-c
- Install cjson https://github.com/DaveGamble/cJSON
- to build software use "make"
-- make all = standaard build for h1502

View File

@@ -1,11 +1,14 @@
#acsreader configuratie
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"

View File

@@ -52,8 +52,11 @@ int config_read(struct config_t *config, char *filepath){
get_device_id(config->device);
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;
@@ -68,8 +71,11 @@ int config_read(struct config_t *config, char *filepath){
//CFG_SIMPLE_FLOAT("delay", &delay),
//CFG_SIMPLE_STR("serialport", &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),
@@ -107,9 +113,12 @@ 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("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);

View File

@@ -4,8 +4,11 @@
struct config_t {
char *serialport1;
char *reader1name;
char *serialport2;
char *reader2name;
char *serveraddress;
long int serverport;
char device[8];
char *name;
long int ProductClass;

101
display.c
View File

@@ -8,78 +8,69 @@
#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 int line[] = {
static unsigned int line[] = {
0, 8, 16, 24,
};
//write display line to h1502display char device
int write_device(char *ln, size_t len){
int fd = open("/dev/h1502display", O_WRONLY);
if (fd == -1) {
writesyslog(LOG_ERR, "open /dev/h1502display error");
return -1;
int display_open(){
int fd = open(DEVICE, O_WRONLY);
if(fd < 0){
writesyslog(LOG_ERR, "opening /dev/h1502display failed");
return 0;
}
ssize_t ret = write(fd, ln, len);
if(ret < 0){
writesyslog(LOG_ERR, "write /dev/h1502display error");
close(fd);
return -1;
}
close(fd);
return 0;
return fd;
}
//write data to de h1502display device
int write_line(int y, int x, int invert, char *txt, int32_t time){
size_t len = strlen(txt);
if(len <= 0 ){
return -1;
}
char *buf = malloc((len + 12) * sizeof(char));
if(buf == NULL){
writesyslog(LOG_ERR, "write_line: out off memory");
return -1;
}
int length = sprintf(buf, "%03d%03d%03d%d%s", x, y, time, invert, txt);
int ret = 0;
if(length > 0){
#ifdef TEST
ret = printf("Display write ->%s<-\n", buf);
#else
ret = write_device(buf, ((size_t)length + 1));
#endif
}
free(buf);
return ret;
}
void clear_display(void){
write_line(line[0], MENU_OFFSET, 0, " ", 0);
write_line(line[1], 0, 0, " ", 0);
write_line(line[2], 0, 0, " ", 0);
write_line(line[3], MENU_OFFSET, 0, " ", 0);
}
void write_display(int ln, int pos, int invert, char *txt, int32_t time){
void display_timer(int fd, unsigned int time){
if(time <= 0){
time = 3;
time = 3; //3 sec
}
if(ioctl(fd, H1502DISPLAY_IOCTL_TIMER, time) < 0){
writesyslog(LOG_ERR, "Timer ioctl /dev/h1502display failed");
}
write_line(line[ln], pos, invert, txt, time);
}
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;
}

View File

@@ -1,8 +1,21 @@
#ifndef DISPLAY_FILE
#define DISPLAY_FILE
void clear_display(void);
void write_display(int ln, int pos, int invert, char *txt, int time);
void display_timer(long int time);
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

View File

@@ -94,23 +94,26 @@ void *readinputs(void *ptr){
}
if(doorlockedflag == ACS_TRUE){
if((val == '0' && config->inputlevel == 1) || (val == '1' && config->inputlevel == 0)){
int32_t switchtime = server_get_opentime(config);
unsigned int switchtime = server_get_opentime(config);
if(relay_switch(RELAY_ON, switchtime, config) == ERROR){
exitprogram(EXIT_FAILURE);
}
clear_display();
int fd = display_open();
display_clear(fd);
char *ln1;
if(asprintf(&ln1, "Manual open - %d sec", switchtime) > 0 ){
write_display(1, 0, 0, ln1, switchtime);
display_write(fd, 1, 0, 0, ln1);
}
char *ln2;
if(asprintf(&ln2, "In: %ld - Relay: %ld", config->manualinput, config->relay) > 0 ){
write_display(2, 0, 0, ln2, switchtime);
display_write(fd, 2, 0, 0, ln2);
}
free(ln2);
display_timer(fd, switchtime);
close(fd);
writesyslog(LOG_INFO, ln1);
server_send_log(config, ln1);
server_send_log(config, MANUALOPEN, ln1);
free(ln1);
}
}

View File

@@ -30,11 +30,22 @@ typedef enum{
typedef enum{
UNKNOWN = 0,
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

18
main.c
View File

@@ -28,9 +28,12 @@
/**********************************/
int main(int argc, char **argv){
writesyslog(LOG_INFO, STARTMSG);
clear_display();
write_display(1, 0, 0, "Starting", 5);
write_display(2, 0, 0, "ACSreader", 5);
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();
@@ -71,7 +74,7 @@ int main(int argc, char **argv){
struct config_t config;
if(config_read(&config, filepath) <= 0){
char *log;
if(asprintf(&log, "Config erro: file path %s", filepath) > 0 ){
if(asprintf(&log, "Config error: file path %s", filepath) > 0 ){
writesyslog(LOG_ERR, log);
}
printf("Config error: file path %s\r\n", filepath);
@@ -103,15 +106,18 @@ int main(int argc, char **argv){
exitprogram(EXIT_FAILURE);
}
serial1.reader = 1;
serial1.readername = config.reader1name;
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, STARTMSG)){
if(!server_send_log(&config, BOOTLOG, STARTMSG)){
char *log;
if(asprintf(&log, "Connection with server : %s", config.serveraddress) > 0 ){
if(asprintf(&log, "Connection with server : %s:%ld", config.serveraddress, config.serverport) > 0 ){
writesyslog(LOG_INFO, log);
}
free(log);

37
mf700.c
View File

@@ -33,50 +33,55 @@ int mf700_writecommand(struct reader_t *reader, mf700controlset command){
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 reader_t *reader = (struct reader_t *)arg.sival_ptr;
struct readerdata_t *readerdata = (struct readerdata_t *)arg.sival_ptr;
if(reader->reader == 1){
if(readerdata->reader.reader == 1){
reader1timersemaphore -= 1;
if(reader1timersemaphore == 0){
mf700_writecommand(reader, EVERYLEDOFF);
mf700_writecommand(&readerdata->reader, EVERYLEDOFF);
}
}
if(reader->reader == 2){
if(readerdata->reader.reader == 2){
reader2timersemaphore -= 1;
if(reader2timersemaphore == 0){
mf700_writecommand(reader, EVERYLEDOFF);
mf700_writecommand(&readerdata->reader, EVERYLEDOFF);
}
}
free(reader);
timer_delete(readerdata->timer_id);
free(readerdata);
}
void mf700_timer(long int time, struct reader_t *reader){
timer_t timer_id;
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;
struct reader_t *ptr = malloc(sizeof(struct reader_t));
*ptr = *reader;
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 = ptr;
se.sigev_value.sival_ptr = readerdata;
se.sigev_notify_function = mf700_timer_handler;
se.sigev_notify_attributes = NULL;
ts.it_value.tv_sec = time;
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, &timer_id);
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 ){
@@ -86,7 +91,7 @@ void mf700_timer(long int time, struct reader_t *reader){
return;
}
status = timer_settime(timer_id, 0, &ts, 0);
status = timer_settime(readerdata->timer_id, 0, &ts, 0);
if (status == -1){
char *log;
if(asprintf(&log, "Error setting mf700 timer: %d", errno) > 0 ){
@@ -102,9 +107,7 @@ void mf700_timer(long int time, struct reader_t *reader){
reader2timersemaphore += 1;
}
int mf700_controlcommand(struct reader_t *reader, long int time, mf700controlset command){
int mf700_controlcommand(struct reader_t *reader, unsigned int time, mf700controlset command){
if( mf700_writecommand(reader, command) == -1){
return -1;
}

View File

@@ -16,6 +16,6 @@ typedef enum {
EVERYLEDON = 0x39,
}mf700controlset;
int mf700_controlcommand(struct reader_t *reader, long int time, mf700controlset command);
int mf700_controlcommand(struct reader_t *reader, unsigned int time, mf700controlset command);
#endif

View File

@@ -26,6 +26,7 @@ void readerrequest(struct reader_t *reader, struct config_t *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);
@@ -41,12 +42,15 @@ void readerrequest(struct reader_t *reader, struct config_t *config){
char *log;
if(asprintf(&log, "CARD ID %d - %d sec", reader->cardnumber, reader->opentime) > 0){
clear_display();
write_display(1, 0, 0, log, reader->opentime);
write_display(2, 0, 0, "access granted", reader->opentime);
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, "Card %d - access granted - %d sec", reader->cardnumber, reader->opentime) > 0 ){
if(asprintf(&log, "%s - Card %d - access granted - %d sec", reader->readername, reader->cardnumber, reader->opentime) > 0 ){
writesyslog(LOG_INFO, log);
}
free(log);
@@ -58,12 +62,15 @@ void readerrequest(struct reader_t *reader, struct config_t *config){
char *log;
if(asprintf(&log, "CARD ID %d", reader->cardnumber) > 0){
clear_display();
write_display(1, 0, 0, log, 3);
write_display(2, 0, 0, "access denied", 3);
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, "Card %d - access denied", reader->cardnumber) > 0 ){
if(asprintf(&log, "%s - Card %d - access denied", reader->readername, reader->cardnumber) > 0 ){
writesyslog(LOG_INFO, log);
}
free(log);

View File

@@ -1,15 +1,16 @@
#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;
int32_t opentime;
unsigned int opentime;
int cardnumber;
struct config_t *config;
char *readername;
};
void readerrequest(struct reader_t *reader, struct config_t *config);

29
relay.c
View File

@@ -64,36 +64,47 @@ int relay_set_state(int state, struct config_t *config){
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 config_t *config = (struct config_t *)arg.sival_ptr;
struct relaydata_t *relaydata = (struct relaydata_t *)arg.sival_ptr;
relaytimersemaphore -= 1;
if(relaytimersemaphore == 0){
relay_set_state(RELAY_OFF, config);
relay_set_state(RELAY_OFF, &relaydata->config);
}
timer_delete(relaydata->timer_id);
free(relaydata);
}
void relay_timer(long int time, struct config_t *config){
timer_t timer_id;
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 = config;
se.sigev_value.sival_ptr = relaydata;
se.sigev_notify_function = relay_timer_handler;
se.sigev_notify_attributes = NULL;
ts.it_value.tv_sec = time;
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, &timer_id);
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 ){
@@ -103,7 +114,7 @@ void relay_timer(long int time, struct config_t *config){
return;
}
status = timer_settime(timer_id, 0, &ts, 0);
status = timer_settime(relaydata->timer_id, 0, &ts, 0);
if (status == -1){
char *log;
if(asprintf(&log, "Error setting relay timer: %d", errno) > 0 ){
@@ -116,7 +127,7 @@ void relay_timer(long int time, struct config_t *config){
relaytimersemaphore += 1;
}
int relay_switch(int state, long int time, struct config_t *config){
int relay_switch(int state, unsigned int time, struct config_t *config){
if(time <= 0){
return 0;
}

View File

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

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

@@ -12,9 +12,9 @@ service='acsreader'
devid=$(cat /sys/class/net/eth0/address | sed 's/://g' | tr a-z A-Z | tail -c 7)
case "$(pidof $service | wc -w)" in
0) #echo "service stooped case"
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/v2/api/status)
$(curl -X POST -H "Content-Type: application/json" -d '{"Device":"'"$devid"'","Name":"'"$devicename"'","ProductClass":'$productclass',"Status":2}' https://$serveraddress:$serverport/v2/api/status)
#Try to restart the service
/etc/init.d/S51$service start
@@ -22,16 +22,16 @@ case "$(pidof $service | wc -w)" in
#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/v2/api/status)
$(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/v2/api/status)
$(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/v2/api/status)
$(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

View File

@@ -43,8 +43,8 @@ int serial_interfaceattribs(int *fd, int speed){
cfmakeraw(&tty);
/* fetch bytes as they become available */
tty.c_cc[VMIN] = 73;
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;
@@ -116,8 +116,8 @@ void *serialdatawatch(void *ptr){
struct reader_t reader;
reader.fd = sharedbuffer.fd;
reader.reader = sharedbuffer.reader;
reader.config = config;
memcpy(reader.buff, sharedbuffer.buff, sizeof(reader.buff));
reader.readername = sharedbuffer.readername;
readerrequest(&reader, config);

View File

@@ -15,6 +15,7 @@ struct serialport_t{
int fd;
unsigned char buff[80];
int reader;
char *readername;
};
pthread_mutex_t sharedbuffermutex;

285
web.c
View File

@@ -1,11 +1,13 @@
#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"
@@ -41,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 json_object **jsonobj){
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 */
@@ -76,7 +82,27 @@ void web_request_json(char *url, const char *json, struct json_object **jsonobj)
CURLcode res = curl_easy_perform(curl_handle);
if(res == CURLE_OK) {
*jsonobj = 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", cJSON_PrintUnformatted(retjson));
#endif
if(cJSON_GetObjectItem(retjson,"State") != NULL){
reader->state = cJSON_GetObjectItem(retjson,"State")->valueint;
}
if(cJSON_GetObjectItem(retjson,"OpenTime") != NULL){
reader->opentime = (unsigned int)cJSON_GetObjectItem(retjson,"OpenTime")->valueint;
}
if(cJSON_GetObjectItem(retjson, "CardNumber") != NULL){
reader->cardnumber = cJSON_GetObjectItem(retjson,"CardNumber")->valueint;
}
}
cJSON_Delete(retjson);
}
else{ //curl returned a error
char *log;
@@ -87,27 +113,19 @@ void web_request_json(char *url, const char *json, struct json_object **jsonobj)
writesyslog(LOG_ERR, errbuf);
if(res == CURLE_COULDNT_RESOLVE_HOST){
*jsonobj = json_object_new_object();
json_object_object_add(*jsonobj, "State", json_object_new_int(RESOLVEERROR));
reader->state = RESOLVEERROR;
}else if(res == CURLE_OPERATION_TIMEDOUT){
*jsonobj = json_object_new_object();
json_object_object_add(*jsonobj, "State", json_object_new_int(CONNECTIONTIMEOUT));
}else if(res == CURLE_HTTP_RETURNED_ERROR){
*jsonobj = json_object_new_object();
json_object_object_add(*jsonobj, "State", json_object_new_int(SERVERERROR));
}else if(res == CURLE_PEER_FAILED_VERIFICATION){
*jsonobj = json_object_new_object();
json_object_object_add(*jsonobj, "State", json_object_new_int(SERVERERROR));
reader->state = CONNECTIONTIMEOUT;
}else if(res == CURLE_HTTP_RETURNED_ERROR || res == CURLE_PEER_FAILED_VERIFICATION){
reader->state = SERVERERROR;
}else{
*jsonobj = json_object_new_object();
json_object_object_add(*jsonobj, "State", json_object_new_int(UNKNOWNERROR));
reader->state = UNKNOWNERROR;
}
}
/* cleanup curl stuff */
curl_easy_cleanup(curl_handle);
free(chunk.memory);
/* we're done with libcurl, so clean it up */
curl_global_cleanup();
}
@@ -170,10 +188,12 @@ void server_display_error(returnstate_t state, struct config_t *config){
ret2 = asprintf(&ln2, "cannot happen !");
}
if(len > 0){
clear_display();
write_display(1, 0, 0, ln1, DISPLAY_TIME);
write_display(2, 0, 0, ln2, DISPLAY_TIME);
//display_timer(15);
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);
}
@@ -186,177 +206,108 @@ void server_display_error(returnstate_t state, struct config_t *config){
//----------------------- Request functions ----------------------------------
void server_credential_request(struct reader_t *reader, struct config_t *config){
char *url;
int len = asprintf(&url, "https://%s/v2/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 *)reader->buff));
json_object_object_add(sendobj, "ProductClass", json_object_new_int((int32_t)config->ProductClass));
json_object_object_add(sendobj, "Reader", json_object_new_int(reader->reader));
struct json_object *jsonobj = NULL;
web_request_json(url, json_object_to_json_string(sendobj), &jsonobj);
#ifdef TEST
printf("Server answer: %s\n", json_object_to_json_string(jsonobj));
#endif
reader->state = 0;
if(jsonobj != NULL){
struct json_object *tmpobj;
tmpobj = json_object_new_object();
if(json_object_object_get_ex(jsonobj, "State", &tmpobj) == ACS_TRUE && tmpobj != NULL) {
reader->state = json_object_get_int(tmpobj);
}
if(json_object_object_get_ex(jsonobj, "OpenTime", &tmpobj) == ACS_TRUE && tmpobj != NULL) {
reader->opentime = json_object_get_int(tmpobj);
}
else{
reader->opentime = 0;
}
if(json_object_object_get_ex(jsonobj, "CardNumber", &tmpobj) == ACS_TRUE && tmpobj != NULL) {
reader->cardnumber = json_object_get_int(tmpobj);
}
else{
reader->cardnumber = 0;
}
json_object_put(tmpobj); //delete json object
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);
}
json_object_put(sendobj); //delete json object
free(url);
}
//****************** LockState *******************************
void server_send_lockstate(struct config_t *config, lockstates_t lockstate){
int server_send_lockstate(struct config_t *config, lockstates_t lockstate){
char *url;
int len = asprintf(&url, "https://%s/v2/api/LockState", 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, "ProductClass", json_object_new_int((int32_t)config->ProductClass));
json_object_object_add(sendobj, "LockState", json_object_new_int(lockstate));
struct json_object *jsonobj = NULL;
web_request_json(url, json_object_to_json_string(sendobj), &jsonobj);
#ifdef TEST
printf("Server answer: %s\n", json_object_to_json_string(jsonobj));
#endif
returnstate_t state = 0;
if(jsonobj != NULL){
struct json_object *tmpobj;
tmpobj = json_object_new_object();
if(json_object_object_get_ex(jsonobj, "State", &tmpobj) == ACS_TRUE && tmpobj != NULL) {
state = json_object_get_int(tmpobj);
}
json_object_put(tmpobj); //delete json object
if(asprintf(&url, "https://%s:%ld/v2/api/LockState", config->serveraddress, config->serverport) <= 0){
writesyslog(LOG_ERR, "server_send_lockstate: asprintf failed");
return -1;
}
if(state != LOCKSTATEOK){
server_display_error(state, config);
}
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);
json_object_put(sendobj); //delete json object
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, const char *logtext){
int ret = 0;
int server_send_log(struct config_t *config, logtypes_t logtype, const char *logtext){
char *url;
int len = asprintf(&url, "https://%s/v2/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_int((int32_t)config->ProductClass));
if(len > 0 ){
struct json_object *jsonobj = NULL;
web_request_json(url, json_object_to_json_string(sendobj), &jsonobj);
#ifdef TEST
printf("Server answer: %s\n", json_object_to_json_string(jsonobj));
#endif
returnstate_t state = 0;
if(jsonobj != NULL){
struct json_object *tmpobj;
tmpobj = json_object_new_object();
if(json_object_object_get_ex(jsonobj, "State", &tmpobj) == ACS_TRUE && tmpobj != NULL) {
state = json_object_get_int(tmpobj);
}
json_object_put(tmpobj); //delete json object
}
if(state != LOGOK){
server_display_error(state, config);
ret = -1;
}
}else{
if(asprintf(&url, "https://%s:%ld/v2/api/addlog", config->serveraddress, config->serverport) <= 0){
writesyslog(LOG_ERR, "server_send_log: asprintf failed");
ret = -1;
return -1;
}
json_object_put(sendobj); //delete json object
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);
return(ret);
if(reader.state != LOGOK){
server_display_error(reader.state, config);
return -1;
}
return 0;
}
//****************** get OpenTime *******************************
int32_t server_get_opentime(struct config_t *config){
unsigned int server_get_opentime(struct config_t *config){
char *url;
int len = asprintf(&url, "https://%s/v2/api/opentime", 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, "ProductClass", json_object_new_int((int32_t)config->ProductClass));
struct json_object *jsonobj = NULL;
web_request_json(url, json_object_to_json_string(sendobj), &jsonobj);
#ifdef TEST
printf("Server answer: %s\n", json_object_to_json_string(jsonobj));
#endif
int32_t opentime = 0;
returnstate_t state = 0;
if(jsonobj != NULL){
struct json_object *tmpobj;
tmpobj = json_object_new_object();
if(json_object_object_get_ex(jsonobj, "State", &tmpobj) == ACS_TRUE && tmpobj != NULL) {
state = json_object_get_int(tmpobj);
}
if(json_object_object_get_ex(jsonobj, "OpenTime", &tmpobj) == ACS_TRUE && tmpobj != NULL) {
opentime = json_object_get_int(tmpobj);
}
json_object_put(tmpobj); //delete json object
}
if(state != OPENTIMEOK){
server_display_error(state, config);
if(asprintf(&url, "https://%s:%ld/v2/api/opentime", config->serveraddress, config->serverport) <= 0){
writesyslog(LOG_ERR, "server_get_opentime: asprintf failed");
return 0;
}
json_object_put(sendobj); //delete json object
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);
return opentime;
if(reader.state != OPENTIMEOK){
server_display_error(reader.state, config);
return 0;
}
return reader.opentime;
}

7
web.h
View File

@@ -1,12 +1,11 @@
#ifndef WEB_FILE
#define WEB_FILE
#include <json-c/json.h>
#include "jsontypes.h"
#include "reader.h"
void server_credential_request(struct reader_t *reader, struct config_t *config);
void server_send_lockstate(struct config_t *config, lockstates_t lockstate);
int server_send_log(struct config_t *config, const char *logtext);
int32_t server_get_opentime(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