diff --git a/CronosAgent.c b/CronosAgent.c index 67ff0df..fdf1c90 100644 --- a/CronosAgent.c +++ b/CronosAgent.c @@ -10,14 +10,19 @@ #include #include +#include #include #include #include #include #include +#include + +#ifdef USE_OPENSSL +#include +#endif -// #include #ifndef HEADER_SHA_H #include "sha256.h" #define SHA256_DIGEST_LENGTH SHA256_BLOCK_SIZE @@ -50,6 +55,13 @@ #include "Rewind.h" #include "Version.h" +#include "RingBuffer.h" + +// #include "DMR.h" +#ifndef DMR_H +#define TDMA_FRAME_DURATION 60 +#endif + // #include "ASNTools.h" #ifndef ASNTOOLS_H #define ASN_SEQUENCE 0x10 @@ -110,14 +122,15 @@ #endif -#define MODE_CONSOLE (1 << 0) -#define MODE_SYSLOG (1 << 1) -#define MODE_DAEMON (1 << 2) +#define MODE_CONSOLE (1 << 0) +#define MODE_SYSLOG (1 << 1) +#define MODE_DAEMON (1 << 2) -#define EVENT_LIST_LENGTH (4 + 1 + 4) +#define EVENT_LIST_LENGTH (4 + 2 + 4) -#define BUFFER_SIZE 4096 -#define EXPIRATION_TIME 20 +#define BUFFER_SIZE 2048 // 2 KB +#define EXPIRATION_TIME 60 // 1 minute +#define INITIAL_INTERVAL 100 * 1000000 // 100 milliseconds int serviceMode = MODE_CONSOLE; @@ -224,7 +237,7 @@ int main(int argc, const char* argv[]) " --repeater-port \n" " --server-password \n" " --server-address \n" - " --server-port \n" + " --server-port \n" " --trap-port \n" " --service-mode \n" " bit 0 - print to standard output\n" @@ -235,6 +248,12 @@ int main(int argc, const char* argv[]) return EXIT_FAILURE; } + if (serviceMode & MODE_SYSLOG) + { + // Set proper origin for syslog (required by OpenWRT) + openlog("CronosAgent", LOG_NOWAIT | LOG_PID, LOG_USER); + } + #ifdef __linux__ if ((serviceMode & MODE_DAEMON) && (daemon(-1, -1) < 0)) @@ -297,38 +316,41 @@ int main(int argc, const char* argv[]) int trapHandle; int mediaHandle; int remoteHandle; + int socketOptionValue; struct sockaddr_in proxySocketAddress; socklen_t proxySocketLength = sizeof(proxySocketAddress); - int socketOptionValue = true; proxySocketAddress.sin_family = AF_INET; proxySocketAddress.sin_addr.s_addr = htonl(INADDR_ANY); proxySocketAddress.sin_port = htons(proxyTrapPort); trapHandle = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if((trapHandle < 0) || - (bind(trapHandle, (struct sockaddr*)&proxySocketAddress, proxySocketLength) < 0)) + if ((trapHandle < 0) || + (bind(trapHandle, (struct sockaddr*)&proxySocketAddress, proxySocketLength) < 0)) { print("Error opening port for SNMP Traps\n"); return EXIT_FAILURE; } + socketOptionValue = true; proxySocketAddress.sin_port = 0; remoteHandle = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if((remoteHandle < 0) || - (bind(remoteHandle, (struct sockaddr*)&proxySocketAddress, proxySocketLength) < 0) || - (setsockopt(remoteHandle, IPPROTO_IP, IP_PKTINFO, &socketOptionValue, sizeof(socketOptionValue)) < 0)) + if ((remoteHandle < 0) || + (bind(remoteHandle, (struct sockaddr*)&proxySocketAddress, proxySocketLength) < 0) || + (setsockopt(remoteHandle, IPPROTO_IP, IP_PKTINFO, &socketOptionValue, sizeof(socketOptionValue)) < 0)) { print("Error opening port for Remote Control\n"); return EXIT_FAILURE; } + socketOptionValue = IPTOS_LOWDELAY; proxySocketAddress.sin_port = 0; mediaHandle = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if((mediaHandle < 0) || - (bind(mediaHandle, (struct sockaddr*)&proxySocketAddress, proxySocketLength) < 0) || - (getsockname(mediaHandle, (struct sockaddr*)&proxySocketAddress, &proxySocketLength) < 0)) + if ((mediaHandle < 0) || + (bind(mediaHandle, (struct sockaddr*)&proxySocketAddress, proxySocketLength) < 0) || + (getsockname(mediaHandle, (struct sockaddr*)&proxySocketAddress, &proxySocketLength) < 0) || + (setsockopt(mediaHandle, IPPROTO_IP, IP_TOS, &socketOptionValue, sizeof(socketOptionValue)) < 0)) { print("Error opening port for External Server\n"); return EXIT_FAILURE; @@ -345,8 +367,8 @@ int main(int argc, const char* argv[]) uplinkSocketAddress.sin6_scope_id = 0; uplinkHandle = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); - if((uplinkHandle < 0) || - (bind(uplinkHandle, (struct sockaddr*)&uplinkSocketAddress, sizeof(uplinkSocketAddress)) < 0)) + if ((uplinkHandle < 0) || + (bind(uplinkHandle, (struct sockaddr*)&uplinkSocketAddress, sizeof(uplinkSocketAddress)) < 0)) { print("Error opening port for Rewind Uplink\n"); return EXIT_FAILURE; @@ -356,15 +378,22 @@ int main(int argc, const char* argv[]) // Initialize timer handle - int timerHandle; + int timerHandle1; + int timerHandle2; struct itimerspec timerInterval; - memset(&timerInterval, 0, sizeof(timerInterval)); - timerInterval.it_interval.tv_sec = REWIND_KEEP_ALIVE_INTERVAL; - timerInterval.it_value.tv_sec = REWIND_KEEP_ALIVE_INTERVAL; - timerHandle = timerfd_create(CLOCK_MONOTONIC, 0); - timerfd_settime(timerHandle, 0, &timerInterval, NULL); + timerInterval.it_value.tv_nsec = INITIAL_INTERVAL; + timerInterval.it_interval.tv_sec = REWIND_KEEP_ALIVE_INTERVAL; + + timerHandle1 = timerfd_create(CLOCK_MONOTONIC, 0); + timerfd_settime(timerHandle1, 0, &timerInterval, NULL); + + timerInterval.it_interval.tv_sec = 0; + timerInterval.it_interval.tv_nsec = TDMA_FRAME_DURATION * 1000000; + + timerHandle2 = timerfd_create(CLOCK_MONOTONIC, 0); + timerfd_settime(timerHandle2, 0, &timerInterval, NULL); // Initialize signal handle @@ -404,7 +433,11 @@ int main(int argc, const char* argv[]) epoll_ctl(pollHandle, EPOLL_CTL_ADD, event.data.fd, &event); event.events = EPOLLIN; - event.data.fd = timerHandle; + event.data.fd = timerHandle1; + epoll_ctl(pollHandle, EPOLL_CTL_ADD, event.data.fd, &event); + + event.events = EPOLLIN; + event.data.fd = timerHandle2; epoll_ctl(pollHandle, EPOLL_CTL_ADD, event.data.fd, &event); event.events = EPOLLIN; @@ -450,6 +483,9 @@ int main(int argc, const char* argv[]) EV_SET(change, 1, EVFILT_TIMER, EV_ADD | EV_ENABLE, NOTE_SECONDS, REWIND_KEEP_ALIVE_INTERVAL, 0); change ++; + EV_SET(change, 2, EVFILT_TIMER, EV_ADD | EV_ENABLE, NOTE_USECONDS, TDMA_FRAME_DURATION, 0); + change ++; + EV_SET(change, SIGINT, EVFILT_SIGNAL, EV_ADD | EV_ENABLE, 0, 0, 0); change ++; @@ -472,7 +508,9 @@ int main(int argc, const char* argv[]) #endif - // Prepare uplink buffers + // Prepare buffers + + void* controlBuffer = alloca(BUFFER_SIZE); struct RewindData* incomingBuffer = (struct RewindData*)alloca(sizeof(struct RewindData) + BUFFER_SIZE); struct RewindData* outgoingBuffer = (struct RewindData*)alloca(sizeof(struct RewindData) + BUFFER_SIZE); @@ -483,7 +521,10 @@ int main(int argc, const char* argv[]) size_t passwordLength = strlen(serverPassword); time_t watchDog = now.tv_sec + EXPIRATION_TIME; - uint32_t sequenceNumbers[] = + struct RingBuffer ringBuffers[2]; + memset(ringBuffers, 0, sizeof(ringBuffers)); + + uint32_t sequenceNumbers[] = { 0, 0, @@ -491,6 +532,9 @@ int main(int argc, const char* argv[]) 0 }; + struct utsname systemName; + uname(&systemName); + // Main loop bool running = true; @@ -542,6 +586,21 @@ int main(int argc, const char* argv[]) if (type == REWIND_TYPE_EXTERNAL_SERVER) { + uint16_t flags = le16toh(incomingBuffer->flags); + uint32_t number = le32toh(incomingBuffer->number); + + if (flags & REWIND_FLAG_REAL_TIME_1) + { + PokeData(ringBuffers + 0, number, incomingBuffer->data, length); + continue; + } + + if (flags & REWIND_FLAG_REAL_TIME_2) + { + PokeData(ringBuffers + 1, number, incomingBuffer->data, length); + continue; + } + repeaterSocketAddress.sin_port = htons(KAIROS_HAM_DEFAULT_PORT); sendto(mediaHandle, incomingBuffer->data, length, 0, (struct sockaddr*)&repeaterSocketAddress, sizeof(struct sockaddr_in)); continue; @@ -580,6 +639,10 @@ int main(int argc, const char* argv[]) outgoingBuffer->length = htole16(SHA256_DIGEST_LENGTH); sendto(uplinkHandle, outgoingBuffer, sizeof(struct RewindData) + SHA256_DIGEST_LENGTH, 0, serverAddress->ai_addr, serverAddress->ai_addrlen); + + socketOptionValue = true; + setsockopt(remoteHandle, IPPROTO_IP, IP_PKTINFO, &socketOptionValue, sizeof(socketOptionValue)); + continue; } @@ -646,7 +709,7 @@ int main(int argc, const char* argv[]) message.msg_namelen = sizeof(address); message.msg_iov = &vector; message.msg_iovlen = 1; - message.msg_control = alloca(BUFFER_SIZE); + message.msg_control = controlBuffer; message.msg_controllen = BUFFER_SIZE; message.msg_flags = 0; @@ -724,15 +787,16 @@ int main(int argc, const char* argv[]) // Handle timer to transmit keep-alive #ifdef __linux__ - if (event->data.fd == timerHandle) + if (event->data.fd == timerHandle1) { uint64_t information; - read(timerHandle, &information, sizeof(information)); + read(timerHandle1, &information, sizeof(information)); clock_gettime(CLOCK_MONOTONIC, &now); #endif #ifdef __MACH__ - if (event->filter == EVFILT_TIMER) + if ((event->ident == 1) && + (event->filter == EVFILT_TIMER)) { clock_get_time(clockService, &now); #endif @@ -748,18 +812,41 @@ int main(int argc, const char* argv[]) data->number = htole32(repeaterNumber); data->service = REWIND_SERVICE_CRONOS_AGENT; - length += sprintf(data->description, "CronosAgent " STRING(VERSION) " " BUILD); + + length += sprintf(data->description, + "CronosAgent " STRING(VERSION) " %s %s " BUILD, + systemName.sysname, + systemName.machine); outgoingBuffer->type = htole16(REWIND_TYPE_KEEP_ALIVE); outgoingBuffer->flags = htole16(REWIND_FLAG_DEFAULT_SET); outgoingBuffer->number = htole32(++ sequenceNumbers[0]); - outgoingBuffer->length = htobe16(length); + outgoingBuffer->length = htole16(length); length += sizeof(struct RewindData); sendto(uplinkHandle, outgoingBuffer, length, 0, serverAddress->ai_addr, serverAddress->ai_addrlen); continue; } + // Handle timer to process RingBuffer + +#ifdef __linux__ + if (event->data.fd == timerHandle2) + { + uint64_t information; + read(timerHandle2, &information, sizeof(information)); +#endif +#ifdef __MACH__ + if ((event->ident == 2) && + (event->filter == EVFILT_TIMER)) + { +#endif + repeaterSocketAddress.sin_port = htons(KAIROS_HAM_DEFAULT_PORT); + ProcessBuffer(ringBuffers + 0, mediaHandle, &repeaterSocketAddress); + ProcessBuffer(ringBuffers + 1, mediaHandle, &repeaterSocketAddress); + continue; + } + // Handle signal from the kernel #ifdef __linux__ @@ -792,10 +879,6 @@ int main(int argc, const char* argv[]) break; } - // SIGHUP - - socketOptionValue = true; - setsockopt(remoteHandle, IPPROTO_IP, IP_PKTINFO, &socketOptionValue, sizeof(socketOptionValue)); } } } @@ -811,7 +894,8 @@ int main(int argc, const char* argv[]) #ifdef __linux__ close(pollHandle); - close(timerHandle); + close(timerHandle1); + close(timerHandle2); close(signalHandle); #endif #ifdef __MACH__