#include #include #include #include #include #include #include #include #include #include #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 int DEFAULT_SINKPORT = 20169; int 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; } logmsg(LOG_INFO, "CONFIG: sinkServer=%s\n", sinkServer); if (! config_lookup_int(pCfg, SINKPORT_KEY, &sinkPort)) { sinkPort = DEFAULT_SINKPORT; } logmsg(LOG_INFO, "CONFIG: sinkPort=%u\n", sinkPort); if (! config_lookup_string(pCfg, DEVICE_ID_KEY, &deviceId)) { deviceId = DEFAULT_DEVICE_ID; } logmsg(LOG_INFO, "CONFIG: deviceId=%s\n", deviceId); if (! config_lookup_string(pCfg, SHARED_SECRET_KEY, &sharedSecret)) { sharedSecret = DEFAULT_SHARED_SECRET; } secondOfMinute = 0; } static void sinkSenderSendMinute() { led(E_BLUE, true); led(E_RED, false); struct sysinfo info; sysinfo(&info); minuteBuffer.s.totalRunningHours = info.uptime / 3600; minuteBuffer.s.totalPowercycles = 0; minuteBuffer.s.totalWatchdogResets = 0; minuteBuffer.s.version = strtoll(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) { char *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, (struct sockaddr*)&servaddr, sizeof(servaddr)); logmsg(LOG_DEBUG, "%d octets sent", res); } else { led(E_RED, true); logmsg(LOG_ERR, "unable to get socket: %s", strerror(errno)); } } else { led(E_RED, true); logmsg(LOG_ERR, "unknown address type: %d", hptr->h_addrtype); } } else { led(E_RED, true); logmsg(LOG_ERR, "sinkserver %s couldn't be resolved: %s", sinkServer, hstrerror(h_errno)); } led(E_BLUE, false); } void sinkSenderPut(uint32_t seconds, uint32_t frequency) { static bool settled = false; 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; if (settled) { sinkSenderSendMinute(); } else { logmsg(LOG_INFO, "now it is settled"); settled = true; } } led(E_GREEN, true); }