From 243486ec643382e7efa0803c6fa1a2d1ea54d2d8 Mon Sep 17 00:00:00 2001 From: Christoph Haas Date: Tue, 7 May 2019 20:19:52 +0200 Subject: [PATCH] Start from scratch --- .gitlab-ci.yml | 21 --- LICENSE | 21 --- Makefile | 35 ----- README.md | 25 ---- gclogger.example.ini | 46 ------ include/gclogger.h | 61 -------- include/gmc.h | 33 ---- include/ini.h | 130 ---------------- obj/.gitignore | 4 - src/gclogger.c | 349 ------------------------------------------- src/gmc.c | 109 -------------- src/ini.c | 269 --------------------------------- 12 files changed, 1103 deletions(-) delete mode 100644 .gitlab-ci.yml delete mode 100644 LICENSE delete mode 100644 Makefile delete mode 100644 README.md delete mode 100644 gclogger.example.ini delete mode 100644 include/gclogger.h delete mode 100644 include/gmc.h delete mode 100644 include/ini.h delete mode 100644 obj/.gitignore delete mode 100644 src/gclogger.c delete mode 100644 src/gmc.c delete mode 100644 src/ini.c diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml deleted file mode 100644 index e008a44..0000000 --- a/.gitlab-ci.yml +++ /dev/null @@ -1,21 +0,0 @@ -# This file is only necessary for the gitlab to github sync and does not belong to the gclogger code. - -#before_script: -# - ssh-keyscan -t rsa,dsa,ecdsa github.com > /etc/ssh/ssh_known_hosts -stages: - - mirror - -variables: - MIRROR_REPOSITORY: "git@github.com:h44z/gclogger.git" - -mirror-github: - stage: mirror - cache: {} - script: - # Do a mirror clone of the repository - - git clone --mirror $CI_REPOSITORY_URL - # Mirror push it to the destination - - cd $CI_PROJECT_NAME.git - - git push --mirror $MIRROR_REPOSITORY - # Cleanup - - cd ..; rm -rf $CI_PROJECT_NAME.git diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 2cc9177..0000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2018 Christoph Haas - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/Makefile b/Makefile deleted file mode 100644 index 499e997..0000000 --- a/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright 2018 Christoph Haas -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the standard MIT license. See LICENSE for more details. - -EXE = gclogger - -SRC_DIR = src -OBJ_DIR = obj - -SRC = $(wildcard $(SRC_DIR)/*.c) -OBJ = $(SRC:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o) - -CPPFLAGS += -Iinclude -CFLAGS += -Wall -Wextra -Os - -#LDFLAGS += -Llib -LDLIBS += -lcurl - -.PHONY: all clean - -all: $(EXE) - -# Linking: -$(EXE): $(OBJ) - $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@ - -# Compiling: -$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c - $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@ - -# Cleaning: -clean: - $(RM) $(OBJ) - $(RM) $(EXE) diff --git a/README.md b/README.md deleted file mode 100644 index d9df6a0..0000000 --- a/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# Geiger Counter Logger -Version 0.1 - -Copyright (C) 2018 Christoph Haas, christoph.h@sprinternet.at - -This program comes with ABSOLUTELY NO WARRANTY. -This is free software, and you are welcome to redistribute it. - -gclogger is a lightweight daemon for reporting your -Geiger counter readings to various radiation monitoring websites. - -Tested Geiger counter devices: -- GMC-320 and GMC-320 Plus - http://www.gqelectronicsllc.com/comersus/store/LeftStart.asp?idCategory=50 - - -## Usage: - -Compile the project using make. - -Then edit the example config file and run gclogger: - -``` -./gclogger -c gclogger.ini -d -``` diff --git a/gclogger.example.ini b/gclogger.example.ini deleted file mode 100644 index 2fed26f..0000000 --- a/gclogger.example.ini +++ /dev/null @@ -1,46 +0,0 @@ -; -; Geiger Counter Logger - configuration file -; - -; Serial device filename -; ------------------------ -[device] -port=/dev/ttyUSB0 -baud=115200 - -; GPS location of your sensor -; ----------------------------- -location=Innsbruck, AT -latitude=47.2530 -longitude=11.3969 - -; Polling interval in seconds (60..3600) -; ---------------------------------------- -interval=60 - -; -; Log portal configurations -; -; Uncomment sections to enable them -; - -; Custom REST logging portal -; ---------------------------------------------- -[custlog] -;id=example_device_id -;url=https://api.mygclog.com/log -;type=GET -;param_id=id -;param_cpm=cpm -;param_temp=temp -;param_lng=lng -;param_lat=lat -;param_loc=loc -;param_version=version -;param_time=captured_at - -; Log to CSV file -; ---------------------------------------------- -[csv] -;path=/tmp/gclog.csv - diff --git a/include/gclogger.h b/include/gclogger.h deleted file mode 100644 index 0c27c43..0000000 --- a/include/gclogger.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2018 Christoph Haas - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the standard MIT license. See LICENSE for more details. - */ - -#ifndef _GCLOGGER_H_ -#define _GCLOGGER_H_ - -#include -#include -#include -#include -#include -#include -#include - -#include "ini.h" -#include "gmc.h" - -#define GCLOGGER_VERSION "0.1" - -typedef struct -{ - bool debug; - char* dev_port; - int dev_baud; - char* dev_location; - float dev_latitude; - float dev_longitude; - int dev_interval; - - char* radmon_user; - char* radmon_pass; - char* safecast_key; - char* safecast_device; - char* netc_id; - char* custlog_url; - char* custlog_type; - char* custlog_id; - char* custlog_param_id; - char* custlog_param_cpm; - char* custlog_param_temp; - char* custlog_param_lng; - char* custlog_param_lat; - char* custlog_param_loc; - char* custlog_param_version; - char* custlog_param_time; - char* csv_path; -} configuration; - -static int confighandler(void* config, const char* section, const char* name, const char* value); -bool str_isset(char *str); -void init_configuration(configuration* config); -void signal_handler(int sig); -bool send_custlog(const configuration config, int cpm, float temperature, const char *version, struct tm *tm); -bool send_tocsv(const configuration config, int cpm, float temperature, const char *version, const struct tm *tm); -void show_usage(); - -#endif \ No newline at end of file diff --git a/include/gmc.h b/include/gmc.h deleted file mode 100644 index 733020b..0000000 --- a/include/gmc.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2018 Christoph Haas - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the standard MIT license. See LICENSE for more details. - */ - -#ifndef _GC_GMC_H_ -#define _GC_GMC_H_ - -#include -#include -#include -#include -#include -#include - -// GQ Geiger Counter Communication Protocol: http://www.gqelectronicsllc.com/download/GQ-RFC1201.txt - -int gmc_open(const char *device, int baud); -void gmc_close(int device); - -int gmc_get_cpm(int device); -float gmc_get_temperature(int device); -int gmc_get_version(int device, char *buf); - -bool gmc_set_heartbeat_off(int device); - -int gmc_write(int device, const char *cmd); -int gmc_read(int device, char *buf, int length); -bool gmc_flush(int device); - -#endif diff --git a/include/ini.h b/include/ini.h deleted file mode 100644 index 7b1f03b..0000000 --- a/include/ini.h +++ /dev/null @@ -1,130 +0,0 @@ -/* inih -- simple .INI file parser - -inih is released under the New BSD license (see LICENSE.txt). Go to the project -home page for more info: - -https://github.com/benhoyt/inih - -*/ - -#ifndef __INI_H__ -#define __INI_H__ - -/* Make this header file easier to include in C++ code */ -#ifdef __cplusplus -extern "C" { -#endif - -#include - -/* Nonzero if ini_handler callback should accept lineno parameter. */ -#ifndef INI_HANDLER_LINENO -#define INI_HANDLER_LINENO 0 -#endif - -/* Typedef for prototype of handler function. */ -#if INI_HANDLER_LINENO -typedef int (*ini_handler)(void* user, const char* section, - const char* name, const char* value, - int lineno); -#else -typedef int (*ini_handler)(void* user, const char* section, - const char* name, const char* value); -#endif - -/* Typedef for prototype of fgets-style reader function. */ -typedef char* (*ini_reader)(char* str, int num, void* stream); - -/* Parse given INI-style file. May have [section]s, name=value pairs - (whitespace stripped), and comments starting with ';' (semicolon). Section - is "" if name=value pair parsed before any section heading. name:value - pairs are also supported as a concession to Python's configparser. - - For each name=value pair parsed, call handler function with given user - pointer as well as section, name, and value (data only valid for duration - of handler call). Handler should return nonzero on success, zero on error. - - Returns 0 on success, line number of first error on parse error (doesn't - stop on first error), -1 on file open error, or -2 on memory allocation - error (only when INI_USE_STACK is zero). -*/ -int ini_parse(const char* filename, ini_handler handler, void* user); - -/* Same as ini_parse(), but takes a FILE* instead of filename. This doesn't - close the file when it's finished -- the caller must do that. */ -int ini_parse_file(FILE* file, ini_handler handler, void* user); - -/* Same as ini_parse(), but takes an ini_reader function pointer instead of - filename. Used for implementing custom or string-based I/O (see also - ini_parse_string). */ -int ini_parse_stream(ini_reader reader, void* stream, ini_handler handler, - void* user); - -/* Same as ini_parse(), but takes a zero-terminated string with the INI data -instead of a file. Useful for parsing INI data from a network socket or -already in memory. */ -int ini_parse_string(const char* string, ini_handler handler, void* user); - -/* Nonzero to allow multi-line value parsing, in the style of Python's - configparser. If allowed, ini_parse() will call the handler with the same - name for each subsequent line parsed. */ -#ifndef INI_ALLOW_MULTILINE -#define INI_ALLOW_MULTILINE 1 -#endif - -/* Nonzero to allow a UTF-8 BOM sequence (0xEF 0xBB 0xBF) at the start of - the file. See http://code.google.com/p/inih/issues/detail?id=21 */ -#ifndef INI_ALLOW_BOM -#define INI_ALLOW_BOM 1 -#endif - -/* Chars that begin a start-of-line comment. Per Python configparser, allow - both ; and # comments at the start of a line by default. */ -#ifndef INI_START_COMMENT_PREFIXES -#define INI_START_COMMENT_PREFIXES ";#" -#endif - -/* Nonzero to allow inline comments (with valid inline comment characters - specified by INI_INLINE_COMMENT_PREFIXES). Set to 0 to turn off and match - Python 3.2+ configparser behaviour. */ -#ifndef INI_ALLOW_INLINE_COMMENTS -#define INI_ALLOW_INLINE_COMMENTS 1 -#endif -#ifndef INI_INLINE_COMMENT_PREFIXES -#define INI_INLINE_COMMENT_PREFIXES ";" -#endif - -/* Nonzero to use stack for line buffer, zero to use heap (malloc/free). */ -#ifndef INI_USE_STACK -#define INI_USE_STACK 1 -#endif - -/* Maximum line length for any line in INI file (stack or heap). Note that - this must be 3 more than the longest line (due to '\r', '\n', and '\0'). */ -#ifndef INI_MAX_LINE -#define INI_MAX_LINE 200 -#endif - -/* Nonzero to allow heap line buffer to grow via realloc(), zero for a - fixed-size buffer of INI_MAX_LINE bytes. Only applies if INI_USE_STACK is - zero. */ -#ifndef INI_ALLOW_REALLOC -#define INI_ALLOW_REALLOC 0 -#endif - -/* Initial size in bytes for heap line buffer. Only applies if INI_USE_STACK - is zero. */ -#ifndef INI_INITIAL_ALLOC -#define INI_INITIAL_ALLOC 200 -#endif - -/* Stop parsing on first error (default is to keep parsing). */ -#ifndef INI_STOP_ON_FIRST_ERROR -#define INI_STOP_ON_FIRST_ERROR 0 -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* __INI_H__ */ \ No newline at end of file diff --git a/obj/.gitignore b/obj/.gitignore deleted file mode 100644 index 0aaa831..0000000 --- a/obj/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -# Ignore everything in this directory -* -# Except this file -!.gitignore diff --git a/src/gclogger.c b/src/gclogger.c deleted file mode 100644 index 701f9c3..0000000 --- a/src/gclogger.c +++ /dev/null @@ -1,349 +0,0 @@ -/* - * Copyright 2018 Christoph Haas - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the standard MIT license. See LICENSE for more details. - */ - -#include "gclogger.h" - -extern char *optarg; -extern int optind; - -static volatile bool running = true; - -static int confighandler(void* config, const char* section, const char* name, const char* value) { - configuration* pconfig = (configuration*)config; - - #define MATCH(s, n) strcmp(section, s) == 0 && strcmp(name, n) == 0 - if (MATCH("device", "port")) { - pconfig->dev_port = strdup(value); - } else if (MATCH("device", "baud")) { - pconfig->dev_baud = atoi(value); - } else if (MATCH("device", "location")) { - pconfig->dev_location = strdup(value); - } else if (MATCH("device", "latitude")) { - pconfig->dev_latitude = atof(value); - } else if (MATCH("device", "longitude")) { - pconfig->dev_longitude = atof(value); - } else if (MATCH("device", "interval")) { - pconfig->dev_interval = atoi(value); - } else if (MATCH("custlog", "url")) { - pconfig->custlog_url = strdup(value); - } else if (MATCH("custlog", "type")) { - pconfig->custlog_type = strdup(value); - } else if (MATCH("custlog", "id")) { - pconfig->custlog_id = strdup(value); - } else if (MATCH("custlog", "param_id")) { - pconfig->custlog_param_id = strdup(value); - } else if (MATCH("custlog", "param_cpm")) { - pconfig->custlog_param_cpm = strdup(value); - } else if (MATCH("custlog", "param_temp")) { - pconfig->custlog_param_temp = strdup(value); - } else if (MATCH("custlog", "param_lng")) { - pconfig->custlog_param_lng = strdup(value); - } else if (MATCH("custlog", "param_lat")) { - pconfig->custlog_param_lat = strdup(value); - } else if (MATCH("custlog", "param_loc")) { - pconfig->custlog_param_loc = strdup(value); - } else if (MATCH("custlog", "param_version")) { - pconfig->custlog_param_version = strdup(value); - } else if (MATCH("custlog", "param_time")) { - pconfig->custlog_param_time = strdup(value); - } else if (MATCH("csv", "path")) { - pconfig->csv_path = strdup(value); - } else { - return 0; /* unknown section/name, error */ - } - return 1; -} - -bool str_isset(char *str) { - return str != NULL && str[0] != '\0'; -} - -void init_configuration(configuration* config) { - config->debug = false; - - config->dev_port = ""; - config->dev_baud = 115200; - config->dev_location = ""; - config->dev_latitude = 0.0; - config->dev_longitude = 0.0; - config->dev_interval = 60; - config->custlog_url = ""; - config->custlog_type = "GET"; - config->custlog_id = ""; - config->custlog_param_id = "id"; - config->custlog_param_cpm = "cpm"; - config->custlog_param_temp = "temp"; - config->custlog_param_lng = "lng"; - config->custlog_param_lat = "lat"; - config->custlog_param_loc = "loc"; - config->custlog_param_version = "version"; - config->custlog_param_time = "time"; - config->csv_path = ""; -} - -void signal_handler(int sig) { - switch (sig) { - case SIGTERM: - case SIGINT: - case SIGQUIT: - case SIGHUP: - running = false; - default: - break; - } -} - -bool send_custlog(const configuration config, int cpm, float temperature, const char *version, struct tm *tm) { - CURL *curl; - CURLcode res; - - curl = curl_easy_init(); - - if(curl) { - char *url_buffer = NULL; - size_t url_size; - char *post_buffer = NULL; - size_t post_size; - - if(strncmp(config.custlog_type, "GET", 3) == 0) { - // first get size of final url - url_size = snprintf(NULL, 0, "%s?%s=%s&%s=%d&%s=%f&%s=%s&%s=%ld&%s=%f&%s=%f&%s=%s", - config.custlog_url, - config.custlog_param_id, config.custlog_id, - config.custlog_param_cpm, cpm, - config.custlog_param_temp, temperature, - config.custlog_param_version, version, - config.custlog_param_time, mktime(tm), - config.custlog_param_lng, config.dev_longitude, - config.custlog_param_lat, config.dev_latitude, - config.custlog_param_loc, config.dev_location); - - // now allocate buffer and build url - url_buffer = (char *)malloc(url_size + 1); - snprintf(url_buffer, url_size+1,"%s?%s=%s&%s=%d&%s=%f&%s=%s&%s=%ld&%s=%f&%s=%f&%s=%s", - config.custlog_url, - config.custlog_param_id, config.custlog_id, - config.custlog_param_cpm, cpm, - config.custlog_param_temp, temperature, - config.custlog_param_version, version, - config.custlog_param_time, mktime(tm), - config.custlog_param_lng, config.dev_longitude, - config.custlog_param_lat, config.dev_latitude, - config.custlog_param_loc, config.dev_location); - - if(config.debug) { - printf("Final url: %s\n", url_buffer); - } - } else { - url_buffer = strdup(config.custlog_url); - } - - curl_easy_setopt(curl, CURLOPT_URL, url_buffer); - - if(strncmp(config.custlog_type, "POST", 4) == 0) { - // first get size of final url - post_size = snprintf(NULL, 0, "%s=%s&%s=%d&%s=%f&%s=%s&%s=%ld&%s=%f&%s=%f&%s=%s", - config.custlog_param_id, config.custlog_id, - config.custlog_param_cpm, cpm, - config.custlog_param_temp, temperature, - config.custlog_param_version, version, - config.custlog_param_time, mktime(tm), - config.custlog_param_lng, config.dev_longitude, - config.custlog_param_lat, config.dev_latitude, - config.custlog_param_loc, config.dev_location); - - // now allocate buffer and build url - post_buffer = (char *)malloc(post_size + 1); - snprintf(post_buffer, post_size+1,"%s=%s&%s=%d&%s=%f&%s=%s&%s=%ld&%s=%f&%s=%f&%s=%s", - config.custlog_param_id, config.custlog_id, - config.custlog_param_cpm, cpm, - config.custlog_param_temp, temperature, - config.custlog_param_version, version, - config.custlog_param_time, mktime(tm), - config.custlog_param_lng, config.dev_longitude, - config.custlog_param_lat, config.dev_latitude, - config.custlog_param_loc, config.dev_location); - - curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_buffer); - } - - #ifdef SKIP_PEER_VERIFICATION - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); - #endif - - #ifdef SKIP_HOSTNAME_VERIFICATION - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); - #endif - - res = curl_easy_perform(curl); - if(res != CURLE_OK) - printf("curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); - else - printf("curl_easy_perform() ok!"); - - free(url_buffer); - if(post_buffer != NULL) - free(post_buffer); - curl_easy_cleanup(curl); - - return true; - } - - return false; -} - -bool send_tocsv(const configuration config, int cpm, float temperature, const char *version, const struct tm *tm) { - FILE *fp; - - if ((fp = fopen(config.csv_path, "a")) == NULL) { - printf("Error while opening the csv file '%s'.\n", config.csv_path); - return false; - } - - char *ts = asctime(tm); - ts[strlen(ts) - 1] = 0; // get rid of \n - fprintf(fp, "%s,%d,%07.3f,%s\n", ts, cpm, temperature, version); - - fclose(fp); - - return true; -} - -void show_usage() { - printf("Geiger Counter Logger\n"); - printf("Version %s\n", GCLOGGER_VERSION); - printf("Copyright (C) 2018 Christoph Haas, christoph.h@sprinternet.at\n\n"); - printf("This program comes with ABSOLUTELY NO WARRANTY.\n"); - printf("This is free software, and you are welcome to redistribute it.\n\n"); - printf("Usage: gclogger -c [-d]\n"); - printf(" -c configuration file path\n"); - printf(" -d enable verbose mode\n\n"); -} - -int main(int argc, char *argv[]) { - int opt = 0; - int gc_fd = -1; - configuration config; - - // setup signal handlers - signal(SIGTERM, signal_handler); - signal(SIGINT, signal_handler); - signal(SIGQUIT, signal_handler); - signal(SIGHUP, signal_handler); - - // setup curl - curl_global_init(CURL_GLOBAL_DEFAULT); - - // parse config file - init_configuration(&config); - while ((opt = getopt(argc, argv, "c:d")) != -1) { - switch (opt) { - case 'd': - config.debug = true; - break; - - case 'c': - if (ini_parse(optarg, confighandler, &config) < 0) { - printf("Can't load config file '%s'\n", optarg); - return 1; - } - printf("Config loaded from '%s': device_port=%s, interval=%d\n", - optarg, config.dev_port, config.dev_interval); - break; - - default: /* '?' */ - show_usage(); - exit(EXIT_FAILURE); - } - } - - // additional check if extra/no arguments where given - if (optind < argc || argc == 1) { - show_usage(); - exit(EXIT_FAILURE); - } - - // check if device port is set - if(!str_isset(config.dev_port)) { - printf("Device port must be set!'\n"); - exit(EXIT_FAILURE); - } - - gc_fd = gmc_open(config.dev_port, config.dev_baud); - - // check if device connection was successful - if(gc_fd == -1) { - printf("Connection to device (%s) failed!'\n", config.dev_port); - exit(EXIT_FAILURE); - } - - // read version - char version[15] = { 0 }; - if(gmc_get_version(gc_fd, version) == -1) { - printf("Unable to read Geiger counter version!'\n"); - exit(EXIT_FAILURE); - } - - if (config.debug) { - printf("GC VERSION: %s\n", version); - } - - time_t last = time(NULL); - int cpm, sum = 0, count = 0, tcount = 0; - float temperature, tsum = 0; - - // main loop - while (running) { - // read cpm - if ((cpm = gmc_get_cpm(gc_fd)) > 0) { - sum += cpm; - count++; - } - - // read temperature - tsum += gmc_get_temperature(gc_fd); - tcount++; - - if (difftime(time(NULL), last) >= config.dev_interval) { - if (count > 0) { - struct tm *tm = gmtime(&last); - cpm = sum / count; - temperature = tsum / tcount; - - if (config.debug) { - printf("CPM: %d (= %d/%d), TEMP: %07.3f, Timestamp: %s\n", cpm, sum, count, temperature, asctime(tm)); - } - - // log to custom REST api - if (str_isset(config.custlog_url)) { - printf("Uploading to %s.\n", config.custlog_url); - if(!send_custlog(config, cpm, temperature, version, tm)) { - printf("Upload to %s failed.\n", config.custlog_url); - } - } - - // log to csv - if (str_isset(config.csv_path)) { - if(!send_tocsv(config, cpm, temperature, version, tm)) { - printf("Logging to %s failed.\n", config.csv_path); - } - } - - time(&last); - sum = tsum = count = tcount = 0; - } else { - printf("Reading ZERO value from Geiger tube.\n"); - } - } - - sleep(1); // sleep one second - } - - gmc_close(gc_fd); - - return EXIT_SUCCESS; -} diff --git a/src/gmc.c b/src/gmc.c deleted file mode 100644 index aafff39..0000000 --- a/src/gmc.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2018 Christoph Haas - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the standard MIT license. See LICENSE for more details. - */ - -#include "gmc.h" - -int gmc_open(const char *device, int baud) { - int gc_fd = -1; - struct termios tio; - - memset(&tio, 0, sizeof(struct termios)); - tio.c_cflag = CS8 | CREAD | CLOCAL; // 8n1 - tio.c_cc[VMIN] = 0; - tio.c_cc[VTIME] = 5; - - int tio_baud = B115200; - switch(baud) { - case 9600: tio_baud = B9600; break; - case 19200: tio_baud = B19200; break; - case 38400: tio_baud = B38400; break; - case 57600: tio_baud = B57600; break; - case 115200: tio_baud = B115200; break; - } - - if ((gc_fd = open(device, O_RDWR)) != -1) { - if (cfsetspeed(&tio, tio_baud) == 0) { // set baud speed - if (tcsetattr(gc_fd, TCSANOW, &tio) == 0) { // apply baud speed change - if (gmc_set_heartbeat_off(gc_fd)) { // disable heartbeat, we use polling - return gc_fd; - } - } - } else { - // something failed - close(gc_fd); - gc_fd = -1; - } - } - - return gc_fd; -} - -void gmc_close(int device) { - close(device); -} - -int gmc_get_cpm(int device) { - const char cmd[] = ">"; - char buf[2] = { 0 }; - - if (gmc_write(device, cmd) == (ssize_t) strlen(cmd)) - gmc_read(device, buf, 2); - - return buf[0] * 256 + buf[1]; -} - -float gmc_get_temperature(int device) { - const char cmd[] = ">"; - char buf[4] = { 0 }; - - if (gmc_write(device, cmd) == (ssize_t) strlen(cmd)) - gmc_read(device, buf, 4); - - int sign = buf[2] == 0 ? 1 : -1; - float temp = buf[0]; - temp += (float) buf[1] / 10; - temp = temp * sign; - return temp; -} - -int gmc_get_version(int device, char *version) { - const char cmd[] = ">"; - - if (gmc_write(device, cmd) == (ssize_t) strlen(cmd)) - return gmc_read(device, version, 14); - - return -1; -} - -bool gmc_set_heartbeat_off(int device) { - const char cmd[] = ">"; - - if (gmc_write(device, cmd) == (ssize_t) strlen(cmd)) - return gmc_flush(device); - - return false; -} - -int gmc_write(int device, const char *cmd) { - return write(device, cmd, strlen(cmd)); -} - -int gmc_read(int device, char *buf, int length) { - return read(device, buf, length); -} - -bool gmc_flush(int device) { - char ch; - - // flush input stream (max 100 bytes) - for (int i = 0; i < 100; i++) { - if (read(device, &ch, 1) == 0) - return true; - } - - return false; -} diff --git a/src/ini.c b/src/ini.c deleted file mode 100644 index 7a0a2a0..0000000 --- a/src/ini.c +++ /dev/null @@ -1,269 +0,0 @@ -/* inih -- simple .INI file parser - -inih is released under the New BSD license (see LICENSE.txt). Go to the project -home page for more info: - -https://github.com/benhoyt/inih - -*/ - -#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) -#define _CRT_SECURE_NO_WARNINGS -#endif - -#include -#include -#include - -#include "ini.h" - -#if !INI_USE_STACK -#include -#endif - -#define MAX_SECTION 50 -#define MAX_NAME 50 - -/* Used by ini_parse_string() to keep track of string parsing state. */ -typedef struct { - const char* ptr; - size_t num_left; -} ini_parse_string_ctx; - -/* Strip whitespace chars off end of given string, in place. Return s. */ -static char* rstrip(char* s) -{ - char* p = s + strlen(s); - while (p > s && isspace((unsigned char)(*--p))) - *p = '\0'; - return s; -} - -/* Return pointer to first non-whitespace char in given string. */ -static char* lskip(const char* s) -{ - while (*s && isspace((unsigned char)(*s))) - s++; - return (char*)s; -} - -/* Return pointer to first char (of chars) or inline comment in given string, - or pointer to null at end of string if neither found. Inline comment must - be prefixed by a whitespace character to register as a comment. */ -static char* find_chars_or_comment(const char* s, const char* chars) -{ -#if INI_ALLOW_INLINE_COMMENTS - int was_space = 0; - while (*s && (!chars || !strchr(chars, *s)) && - !(was_space && strchr(INI_INLINE_COMMENT_PREFIXES, *s))) { - was_space = isspace((unsigned char)(*s)); - s++; - } -#else - while (*s && (!chars || !strchr(chars, *s))) { - s++; - } -#endif - return (char*)s; -} - -/* Version of strncpy that ensures dest (size bytes) is null-terminated. */ -static char* strncpy0(char* dest, const char* src, size_t size) -{ - strncpy(dest, src, size); - dest[size - 1] = '\0'; - return dest; -} - -/* See documentation in header file. */ -int ini_parse_stream(ini_reader reader, void* stream, ini_handler handler, - void* user) -{ - /* Uses a fair bit of stack (use heap instead if you need to) */ -#if INI_USE_STACK - char line[INI_MAX_LINE]; - int max_line = INI_MAX_LINE; -#else - char* line; - int max_line = INI_INITIAL_ALLOC; -#endif -#if INI_ALLOW_REALLOC - char* new_line; - int offset; -#endif - char section[MAX_SECTION] = ""; - char prev_name[MAX_NAME] = ""; - - char* start; - char* end; - char* name; - char* value; - int lineno = 0; - int error = 0; - -#if !INI_USE_STACK - line = (char*)malloc(INI_INITIAL_ALLOC); - if (!line) { - return -2; - } -#endif - -#if INI_HANDLER_LINENO -#define HANDLER(u, s, n, v) handler(u, s, n, v, lineno) -#else -#define HANDLER(u, s, n, v) handler(u, s, n, v) -#endif - - /* Scan through stream line by line */ - while (reader(line, max_line, stream) != NULL) { -#if INI_ALLOW_REALLOC - offset = strlen(line); - while (offset == max_line - 1 && line[offset - 1] != '\n') { - max_line *= 2; - if (max_line > INI_MAX_LINE) - max_line = INI_MAX_LINE; - new_line = realloc(line, max_line); - if (!new_line) { - free(line); - return -2; - } - line = new_line; - if (reader(line + offset, max_line - offset, stream) == NULL) - break; - if (max_line >= INI_MAX_LINE) - break; - offset += strlen(line + offset); - } -#endif - - lineno++; - - start = line; -#if INI_ALLOW_BOM - if (lineno == 1 && (unsigned char)start[0] == 0xEF && - (unsigned char)start[1] == 0xBB && - (unsigned char)start[2] == 0xBF) { - start += 3; - } -#endif - start = lskip(rstrip(start)); - - if (strchr(INI_START_COMMENT_PREFIXES, *start)) { - /* Start-of-line comment */ - } -#if INI_ALLOW_MULTILINE - else if (*prev_name && *start && start > line) { - /* Non-blank line with leading whitespace, treat as continuation - of previous name's value (as per Python configparser). */ - if (!HANDLER(user, section, prev_name, start) && !error) - error = lineno; - } -#endif - else if (*start == '[') { - /* A "[section]" line */ - end = find_chars_or_comment(start + 1, "]"); - if (*end == ']') { - *end = '\0'; - strncpy0(section, start + 1, sizeof(section)); - *prev_name = '\0'; - } - else if (!error) { - /* No ']' found on section line */ - error = lineno; - } - } - else if (*start) { - /* Not a comment, must be a name[=:]value pair */ - end = find_chars_or_comment(start, "=:"); - if (*end == '=' || *end == ':') { - *end = '\0'; - name = rstrip(start); - value = end + 1; -#if INI_ALLOW_INLINE_COMMENTS - end = find_chars_or_comment(value, NULL); - if (*end) - *end = '\0'; -#endif - value = lskip(value); - rstrip(value); - - /* Valid name[=:]value pair found, call handler */ - strncpy0(prev_name, name, sizeof(prev_name)); - if (!HANDLER(user, section, name, value) && !error) - error = lineno; - } - else if (!error) { - /* No '=' or ':' found on name[=:]value line */ - error = lineno; - } - } - -#if INI_STOP_ON_FIRST_ERROR - if (error) - break; -#endif - } - -#if !INI_USE_STACK - free(line); -#endif - - return error; -} - -/* See documentation in header file. */ -int ini_parse_file(FILE* file, ini_handler handler, void* user) -{ - return ini_parse_stream((ini_reader)fgets, file, handler, user); -} - -/* See documentation in header file. */ -int ini_parse(const char* filename, ini_handler handler, void* user) -{ - FILE* file; - int error; - - file = fopen(filename, "r"); - if (!file) - return -1; - error = ini_parse_file(file, handler, user); - fclose(file); - return error; -} - -/* An ini_reader function to read the next line from a string buffer. This - is the fgets() equivalent used by ini_parse_string(). */ -static char* ini_reader_string(char* str, int num, void* stream) { - ini_parse_string_ctx* ctx = (ini_parse_string_ctx*)stream; - const char* ctx_ptr = ctx->ptr; - size_t ctx_num_left = ctx->num_left; - char* strp = str; - char c; - - if (ctx_num_left == 0 || num < 2) - return NULL; - - while (num > 1 && ctx_num_left != 0) { - c = *ctx_ptr++; - ctx_num_left--; - *strp++ = c; - if (c == '\n') - break; - num--; - } - - *strp = '\0'; - ctx->ptr = ctx_ptr; - ctx->num_left = ctx_num_left; - return str; -} - -/* See documentation in header file. */ -int ini_parse_string(const char* string, ini_handler handler, void* user) { - ini_parse_string_ctx ctx; - - ctx.ptr = string; - ctx.num_left = strlen(string); - return ini_parse_stream((ini_reader)ini_reader_string, &ctx, handler, - user); -} \ No newline at end of file