116 lines
3.5 KiB
C
116 lines
3.5 KiB
C
#include <stdint.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <libconfig.h>
|
|
#include <netdb.h>
|
|
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
#include <errno.h>
|
|
|
|
#include "sinkSender.h"
|
|
#include "logging.h"
|
|
#include "led.h"
|
|
#include "sinkStruct.h"
|
|
#include "sha256.h"
|
|
|
|
|
|
const char SINKSERVER_KEY[] = "sinkServer";
|
|
const char DEFAULT_SINKSERVER[] = "sink.hottis.de";
|
|
const char *sinkServer;
|
|
const char SINKPORT_KEY[] = "sinkPort";
|
|
const uint16_t DEFAULT_SINKPORT = 20169;
|
|
uint16_t sinkPort;
|
|
const char DEVICE_ID_KEY[] = "deviceId";
|
|
const char DEFAULT_DEVICE_ID[] = "mainscnt00";
|
|
const char *deviceId;
|
|
const char SHARED_SECRET_KEY[] = "sharedSecret";
|
|
const char DEFAULT_SHARED_SECRET[] = "1234567890123456789012345678901";
|
|
const char *sharedSecret;
|
|
|
|
static t_minuteBuffer minuteBuffer;
|
|
static uint32_t secondOfMinute;
|
|
|
|
extern char VERSION[];
|
|
|
|
|
|
void sinkSenderInit(config_t *pCfg) {
|
|
if (! config_lookup_string(pCfg, SINKSERVER_KEY, &sinkServer)) {
|
|
sinkServer = DEFAULT_SINKSERVER;
|
|
}
|
|
fprintf(stderr, "CONFIG: sinkServer=%s\n", sinkServer);
|
|
if (! config_lookup_int(pCfg, SINKPORT_KEY, &sinkPort)) {
|
|
sinkPort = DEFAULT_SINKPORT;
|
|
}
|
|
fprintf(stderr, "CONFIG: sinkPort=%u\n", sinkPort);
|
|
if (! config_lookup_string(pCfg, DEVICE_ID_KEY, &deviceId)) {
|
|
deviceId = DEFAULT_DEVICE_ID;
|
|
}
|
|
fprintf(stderr, "CONFIG: deviceId=%s\n", deviceId);
|
|
if (! config_lookup_string(pCfg, SHARED_SECRET_KEY, &sharedSecret)) {
|
|
sharedSecret = DEFAULT_SHARED_SECRET;
|
|
}
|
|
fprintf(stderr, "CONFIG: sharedSecret=%s\n", sharedSecret);
|
|
|
|
|
|
secondOfMinute = 0;
|
|
}
|
|
|
|
void sinkSenderPut(uint32_t seconds, uint32_t frequency) {
|
|
led(E_GREEN, false);
|
|
logmsg(LOG_DEBUG, "s: %lu, f: %lu", seconds, frequency);
|
|
|
|
if (secondOfMinute == 0) {
|
|
minuteBuffer.s.timestamp = seconds;
|
|
}
|
|
minuteBuffer.s.frequency[secondOfMinute] = frequency;
|
|
secondOfMinute += 1;
|
|
|
|
if (secondOfMinute == SECONDS_PER_MINUTE) {
|
|
logmsg(LOG_DEBUG, "minute is full");
|
|
secondOfMinute = 0;
|
|
|
|
minuteBuffer.s.totalRunningHours = 0;
|
|
minuteBuffer.s.totalPowercycles = 0;
|
|
minuteBuffer.s.totalWatchdogResets = 0;
|
|
minuteBuffer.s.version = strtol(VERSION, NULL, 16);
|
|
|
|
memset(minuteBuffer.s.deviceId, 0, sizeof(minuteBuffer.s.deviceId));
|
|
strcpy(minuteBuffer.s.deviceId, deviceId);
|
|
|
|
memcpy(minuteBuffer.s.hash, sharedSecret, SHA256_BLOCK_SIZE);
|
|
SHA256_CTX ctx;
|
|
sha256_init(&ctx);
|
|
sha256_update(&ctx, minuteBuffer.b, sizeof(minuteBuffer.b));
|
|
sha256_final(&ctx, minuteBuffer.s.hash);
|
|
|
|
struct hostent *hptr = gethostbyname(sinkServer);
|
|
if (hptr) {
|
|
if (hptr->h_addrtype == AF_INET) {
|
|
uint8_t *sinkAddr = hptr->h_addr_list[0];
|
|
logmsg(LOG_DEBUG, "sink addr: %d.%d.%d.%d", sinkAddr[0], sinkAddr[1], sinkAddr[2], sinkAddr[3]);
|
|
|
|
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
|
if (sockfd != -1) {
|
|
struct sockaddr_in servaddr;
|
|
memset(&servaddr, 0, sizeof(servaddr));
|
|
servaddr.sin_family = AF_INET;
|
|
servaddr.sin_port = htons(sinkPort);
|
|
memcpy(&servaddr.sin_addr.s_addr, sinkAddr, 4);
|
|
|
|
ssize_t res = sendto(sockfd, minuteBuffer.b, sizeof(minuteBuffer.b), 0, &servaddr, sizeof(servaddr));
|
|
logmsg(LOG_DEBUG, "%d octets sent", res);
|
|
} else {
|
|
logmsg(LOG_ERR, "unable to get socket: %s", strerror(errno));
|
|
}
|
|
} else {
|
|
logmsg(LOG_ERR, "unknown address type: %d", hptr->h_addrtype);
|
|
}
|
|
} else {
|
|
logmsg(LOG_ERR, "sinkserver %s couldn't be resolved: %s", sinkServer, hstrerror(h_errno));
|
|
}
|
|
|
|
}
|
|
|
|
|
|
led(E_GREEN, true);
|
|
} |