3
Fork 0

Initial import

This commit is contained in:
Artem Prilutskiy 2016-11-01 12:17:27 +03:00
commit 12ffb10726
7 changed files with 795 additions and 0 deletions

74
Makefile Normal file
View file

@ -0,0 +1,74 @@
BUILD := $(shell date -u +%Y%m%d-%H%M%S)
OS := $(shell uname -s)
PREFIX = $(DESTDIR)/opt/TellusAgent
TOOLKIT = ../..
DIRECTORIES = \
$(TOOLKIT)/Common \
$(TOOLKIT)/Rewind
ifeq ($(OS), Linux)
FLAGS += -rdynamic
KIND := $(shell grep -E "^6.0" /etc/debian_version > /dev/null ; echo $?)
ifneq ($(KIND), 0)
LIBRARIES += rt
endif
endif
ifeq ($(OS), Darwin)
FLAGS += -Wno-deprecated-declarations
endif
OBJECTS = \
TellusAgent.o
FLAGS += -g -fno-omit-frame-pointer -O3 -MMD $(foreach directory, $(DIRECTORIES), -I$(directory)) -DBUILD=\"$(BUILD)\"
LIBS += $(foreach library, $(LIBRARIES), -l$(library))
CC = gcc
CFLAGS += $(FLAGS) -std=gnu99
ifneq ($(strip $(DEPENDENCIES)),)
FLAGS += $(shell pkg-config --cflags $(DEPENDENCIES))
LIBS += $(shell pkg-config --libs $(DEPENDENCIES))
endif
all: build
build: $(PREREQUISITES) $(OBJECTS)
$(CC) $(OBJECTS) $(FLAGS) $(LIBS) -o tellusagent
install:
install -D -d $(PREFIX)
install -o root -g root tellusagent $(PREFIX)
install -o root -g root tellusagent.sh $(PREFIX)
install -o root -g root tellusagent.conf $(PREFIX)
ifeq ($(OS), Linux)
install -o root -g root tellusagent-init $(PREFIX)
install -m 644 -o root -g root tellusagent-monit $(PREFIX)
install -m 644 -o root -g root tellusagent.service $(PREFIX)
endif
ifeq ($(OS), Darwin)
install -m 644 -o root -g root tellusagent.plist $(DESTDIR)/Library/LaunchDaemons
endif
clean:
rm -f $(PREREQUISITES) $(OBJECTS) tellusagent
rm -f *.d $(TOOLKIT)/*/*.d
version:
echo "#define VERSION $(shell date -u +%Y%m%d)" > Version.h
debian-package:
./UpdateLog.sh
ifdef ARCH
dpkg-buildpackage -b -a$(ARCH) -tc
else
dpkg-buildpackage -b -tc
endif
macos-archive: build
zip ../TellusAgent-macOS.zip tellusagent tellusagent.sh tellusagent.conf tellusagent.plist
.PHONY: all build clean install

103
Rewind.h Normal file
View file

@ -0,0 +1,103 @@
#ifndef REWIND_H
#define REWIND_H
#include <stdint.h>
#include <netinet/in.h>
#ifdef __cplusplus
extern "C"
{
#endif
#pragma pack(push, 1)
#define REWIND_KEEP_ALIVE_INTERVAL 5
#define REWIND_SIGN_LENGTH 8
#define REWIND_PROTOCOL_SIGN "REWIND01"
#define REWIND_CLASS_REWIND_CONTROL 0x0000
#define REWIND_CLASS_SYSTEM_CONSOLE 0x0100
#define REWIND_CLASS_SERVER_NOTICE 0x0200
#define REWIND_CLASS_DEVICE_DATA 0x0800
#define REWIND_CLASS_APPLICATION 0x0900
#define REWIND_CLASS_KAIROS_DATA (REWIND_CLASS_DEVICE_DATA + 0x00)
#define REWIND_CLASS_TELLUS_DATA (REWIND_CLASS_DEVICE_DATA + 0x10)
#define REWIND_TYPE_KEEP_ALIVE (REWIND_CLASS_REWIND_CONTROL + 0)
#define REWIND_TYPE_CLOSE (REWIND_CLASS_REWIND_CONTROL + 1)
#define REWIND_TYPE_CHALLENGE (REWIND_CLASS_REWIND_CONTROL + 2)
#define REWIND_TYPE_AUTHENTICATION (REWIND_CLASS_REWIND_CONTROL + 3)
#define REWIND_TYPE_REPORT (REWIND_CLASS_SYSTEM_CONSOLE + 0)
#define REWIND_TYPE_BUSY_NOTICE (REWIND_CLASS_SERVER_NOTICE + 0)
#define REWIND_TYPE_ADDRESS_NOTICE (REWIND_CLASS_SERVER_NOTICE + 1)
#define REWIND_TYPE_BINDING_NOTICE (REWIND_CLASS_SERVER_NOTICE + 2)
#define REWIND_TYPE_EXTERNAL_SERVER (REWIND_CLASS_KAIROS_DATA + 0)
#define REWIND_TYPE_REMOTE_CONTROL (REWIND_CLASS_KAIROS_DATA + 1)
#define REWIND_TYPE_SNMP_TRAP (REWIND_CLASS_KAIROS_DATA + 2)
#define REWIND_TYPE_PEER_DATA (REWIND_CLASS_TELLUS_DATA + 0)
#define REWIND_TYPE_RDAC_DATA (REWIND_CLASS_TELLUS_DATA + 1)
#define REWIND_TYPE_MEDIA_DATA (REWIND_CLASS_TELLUS_DATA + 2)
#define REWIND_TYPE_SUBSCRIPTION (REWIND_CLASS_APPLICATION + 0x00)
#define REWIND_TYPE_DMR_DATA_BASE (REWIND_CLASS_APPLICATION + 0x10)
#define REWIND_TYPE_DMR_AUDIO_FRAME (REWIND_CLASS_APPLICATION + 0x20)
#define REWIND_FLAG_NONE 0
#define REWIND_FLAG_REAL_TIME_1 (1 << 0)
#define REWIND_FLAG_REAL_TIME_2 (1 << 1)
#define REWIND_FLAG_DEFAULT_SET REWIND_FLAG_NONE
#define REWIND_ROLE_REPEATER_AGENT 0x10
#define REWIND_ROLE_APPLICATION 0x20
#define REWIND_SERVICE_CRONOS_AGENT (REWIND_ROLE_REPEATER_AGENT + 0)
#define REWIND_SERVICE_TELLUS_AGENT (REWIND_ROLE_REPEATER_AGENT + 1)
#define REWIND_SERVICE_SIMPLE_APPLICATION (REWIND_ROLE_APPLICATION + 0)
struct RewindVersionData
{
uint32_t number; // Remote ID
uint8_t service; // REWIND_SERVICE_*
char description[0]; // Software name and version
};
struct RewindAddressData
{
struct in_addr address;
uint16_t port;
};
struct RewindBindingData
{
uint16_t ports[0];
};
struct RewindSubscriptionData
{
uint32_t type;
uint32_t number;
};
struct RewindData
{
char sign[REWIND_SIGN_LENGTH];
uint16_t type; // REWIND_TYPE_*
uint16_t flags; // REWIND_FLAG_*
uint32_t number; // Packet sequence number
uint16_t length; // Length of following data
uint8_t data[0]; //
};
#pragma pack(pop)
#ifdef __cplusplus
}
#endif
#endif

574
TellusAgent.c Normal file
View file

@ -0,0 +1,574 @@
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdarg.h>
#include <getopt.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <unistd.h>
#include <syslog.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/utsname.h>
#ifdef __linux__
#include <endian.h>
#include <byteswap.h>
#include <sys/epoll.h>
#include <sys/signalfd.h>
#endif
#ifdef __MACH__
#include <launch.h>
#include <stdbool.h>
#include <sys/event.h>
#include <mach/mach.h>
#include <machine/endian.h>
#endif
#include "Rewind.h"
#include "Version.h"
#define HELPER(value) #value
#define STRING(value) HELPER(value)
#define COUNT(array) sizeof(array) / sizeof(array[0])
#ifdef __cplusplus
#define CAST(type, value) const_cast<type>(value)
#else
#define CAST(type, value) (type)value
#ifndef bool
#define bool int
#define true 1
#define false 0
#endif
#endif
#ifdef __linux__
#define CHECK(event, handle) (event->data.fd == handle)
#endif
#ifdef __MACH__
#define CHECK(event, handle) (event->ident == handle) && (event->filter == EVFILT_READ)
#define htobe16(value) OSSwapHostToBigInt16(value)
#define be16toh(value) OSSwapBigToHostInt16(value)
#define htobe32(value) OSSwapHostToBigInt32(value)
#define be32toh(value) OSSwapBigToHostInt32(value)
#define htole16(value) OSSwapHostToLittleInt16(value)
#define le16toh(value) OSSwapLittleToHostInt16(value)
#define htole32(value) OSSwapHostToLittleInt32(value)
#define le32toh(value) OSSwapLittleToHostInt32(value)
#define __bswap_16(value) OSSwapConstInt16(value)
#define __bswap_32(value) OSSwapConstInt32(value)
#endif
#define MODE_CONSOLE (1 << 0)
#define MODE_SYSLOG (1 << 1)
#define MODE_DAEMON (1 << 2)
#define EVENT_LIST_LENGTH (4 + 4)
#define BUFFER_SIZE 2048
#define PROXY_PORT_COUNT 3
int serviceMode = MODE_CONSOLE;
void print(const char* format, ...)
{
va_list arguments;
va_start(arguments, format);
if (serviceMode & MODE_CONSOLE)
vprintf(format, arguments);
if (serviceMode & MODE_SYSLOG)
vsyslog(LOG_INFO, format, arguments);
va_end(arguments);
}
int main(int argc, const char* argv[])
{
print("\n");
print("TellusAgent for BrandMeister DMR Master Server\n");
print("Copyright 2016 Artem Prilutskiy (R3ABM, cyanide.burnout@gmail.com)\n");
print("Software revision " STRING(VERSION) " build " BUILD "\n");
print("\n");
// Parameters for server
const char* serverPort = "54003";
const char* serverLocation = NULL;
struct addrinfo* serverAddress = NULL;
// Parameters for repeater
uint16_t proxyPorts[PROXY_PORT_COUNT] =
{
htobe16(50000),
htobe16(50001),
htobe16(50002)
};
// Start up
struct option options[] =
{
{ "connect-port", required_argument, NULL, 'c' },
{ "control-port", required_argument, NULL, 'r' },
{ "media-port", required_argument, NULL, 'd' },
{ "server-address", required_argument, NULL, 's' },
{ "server-port", required_argument, NULL, 'p' },
{ "service-mode", required_argument, NULL, 'm' },
{ NULL, 0, NULL, 0 }
};
int selection = 0;
while ((selection = getopt_long(argc, CAST(char* const*, argv), "c:r:d:s:p:m:", options, NULL)) != EOF)
switch (selection)
{
case 'c':
proxyPorts[0] = htons(strtol(optarg, NULL, 10));
break;
case 'r':
proxyPorts[1] = htons(strtol(optarg, NULL, 10));
break;
case 'd':
proxyPorts[2] = htons(strtol(optarg, NULL, 10));
break;
case 's':
serverLocation = optarg;
break;
case 'p':
serverPort = optarg;
break;
case 'm':
serviceMode = strtol(optarg, NULL, 10);
break;
}
if (serverLocation == NULL)
{
print(
"Usage:\n"
" %s\n"
" --connect-port <local port for P2P service>\n"
" --control-port <local port for RDAC service>\n"
" --media-port <local port for DMR service>\n"
" --server-address <domain name of BrandMeister DMR Server>\n"
" --server-port <service port of BrandMeister DMR Server>\n"
" --service-mode <set of bits>\n"
" bit 0 - print to standard output\n"
" bit 1 - print to system log\n"
" bit 2 - run as daemon\n"
"\n",
argv[0]);
return EXIT_FAILURE;
}
if (serviceMode & MODE_SYSLOG)
{
// Set proper origin for syslog (required by OpenWRT)
openlog("TellusAgent", LOG_NOWAIT | LOG_PID, LOG_USER);
}
#ifdef __linux__
if ((serviceMode & MODE_DAEMON) &&
(daemon(-1, -1) < 0))
{
print("Error launching daemon");
return EXIT_FAILURE;
}
#endif
#ifdef __MACH__
if (serviceMode & MODE_DAEMON)
{
launch_data_t request = launch_data_new_string(LAUNCH_KEY_CHECKIN);
launch_data_t response = launch_msg(request);
launch_data_free(request);
if (response == NULL)
{
print("Error calling launchd");
return EXIT_FAILURE;
}
launch_data_type_t type = launch_data_get_type(response);
launch_data_free(response);
if (type == LAUNCH_DATA_ERRNO)
{
print("launchd returned error %d\n", launch_data_get_errno(response));
return EXIT_FAILURE;
}
// launchd will return dictionary of job for successful check-in
if (type != LAUNCH_DATA_DICTIONARY)
{
print("Error launching daemon");
return EXIT_FAILURE;
}
}
#endif
// Resolve server address
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_socktype = SOCK_DGRAM;
#ifdef __linux__
hints.ai_flags = AI_ADDRCONFIG;
hints.ai_family = AF_UNSPEC;
#endif
#ifdef __MACH__
hints.ai_flags = AI_V4MAPPED;
hints.ai_family = AF_INET6;
#endif
if (getaddrinfo(serverLocation, serverPort, &hints, &serverAddress) != 0)
{
print("Error resolving server address %s\n", serverLocation);
return EXIT_FAILURE;
}
// Initialize proxy sockets
int proxyHandles[PROXY_PORT_COUNT];
struct sockaddr_in proxySocketAddress;
socklen_t proxySocketLength = sizeof(proxySocketAddress);
proxySocketAddress.sin_family = AF_INET;
proxySocketAddress.sin_addr.s_addr = htonl(INADDR_ANY);
for (selection = 0; selection < PROXY_PORT_COUNT; selection ++)
{
int handle;
proxySocketAddress.sin_port = proxyPorts[selection];
handle = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if((handle < 0) ||
(bind(handle, (struct sockaddr*)&proxySocketAddress, proxySocketLength) < 0))
{
print("Error opening port for Multi-Site Connect\n");
return EXIT_FAILURE;
}
proxyHandles[selection] = handle;
}
// Initialize uplink socket
int uplinkHandle;
struct sockaddr_in6 uplinkSocketAddress;
uplinkSocketAddress.sin6_family = AF_INET6;
uplinkSocketAddress.sin6_addr = in6addr_any;
uplinkSocketAddress.sin6_port = 0;
uplinkSocketAddress.sin6_scope_id = 0;
uplinkHandle = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
if((uplinkHandle < 0) ||
(bind(uplinkHandle, (struct sockaddr*)&uplinkSocketAddress, sizeof(uplinkSocketAddress)) < 0))
{
print("Error opening port for Rewind Uplink\n");
return EXIT_FAILURE;
}
#ifdef __linux__
// Initialize signal handle
int signalHandle;
sigset_t signalMask;
sigemptyset(&signalMask);
sigaddset(&signalMask, SIGINT);
sigaddset(&signalMask, SIGHUP);
sigaddset(&signalMask, SIGTERM);
sigaddset(&signalMask, SIGQUIT);
sigprocmask(SIG_BLOCK, &signalMask, NULL);
signalHandle = signalfd(-1, &signalMask, 0);
// Initialize ePoll
int pollHandle;
struct epoll_event event;
pollHandle = epoll_create(EVENT_LIST_LENGTH);
event.events = EPOLLIN;
event.data.fd = proxyHandles[0];
epoll_ctl(pollHandle, EPOLL_CTL_ADD, event.data.fd, &event);
event.events = EPOLLIN;
event.data.fd = proxyHandles[1];
epoll_ctl(pollHandle, EPOLL_CTL_ADD, event.data.fd, &event);
event.events = EPOLLIN;
event.data.fd = proxyHandles[2];
epoll_ctl(pollHandle, EPOLL_CTL_ADD, event.data.fd, &event);
event.events = EPOLLIN;
event.data.fd = uplinkHandle;
epoll_ctl(pollHandle, EPOLL_CTL_ADD, event.data.fd, &event);
event.events = EPOLLIN;
event.data.fd = signalHandle;
epoll_ctl(pollHandle, EPOLL_CTL_ADD, event.data.fd, &event);
#endif
#ifdef __MACH__
// Prepare signal handlers
signal(SIGINT, SIG_IGN);
signal(SIGHUP, SIG_IGN);
signal(SIGTERM, SIG_IGN);
signal(SIGQUIT, SIG_IGN);
// Initialize KQueue
int queueHandle;
struct kevent changes[EVENT_LIST_LENGTH];
struct kevent* change = changes;
queueHandle = kqueue();
EV_SET(change, proxyHandles[0], EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, 0);
change ++;
EV_SET(change, proxyHandles[1], EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, 0);
change ++;
EV_SET(change, proxyHandles[2], EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, 0);
change ++;
EV_SET(change, uplinkHandle, EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, 0);
change ++;
EV_SET(change, SIGINT, EVFILT_SIGNAL, EV_ADD | EV_ENABLE, 0, 0, 0);
change ++;
EV_SET(change, SIGHUP, EVFILT_SIGNAL, EV_ADD | EV_ENABLE, 0, 0, 0);
change ++;
EV_SET(change, SIGTERM, EVFILT_SIGNAL, EV_ADD | EV_ENABLE, 0, 0, 0);
change ++;
EV_SET(change, SIGQUIT, EVFILT_SIGNAL, EV_ADD | EV_ENABLE, 0, 0, 0);
change ++;
#endif
// 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);
memset(outgoingBuffer, 0, sizeof(struct RewindData));
memcpy(outgoingBuffer, REWIND_PROTOCOL_SIGN, REWIND_SIGN_LENGTH);
struct utsname systemName;
uname(&systemName);
struct sockaddr_in repeaterSocketAddresses[3];
memset(repeaterSocketAddresses, 0, sizeof(repeaterSocketAddresses));
// Main loop
bool running = true;
print("Server started\n");
while (running)
{
#ifdef __linux__
struct epoll_event events[EVENT_LIST_LENGTH];
int count = epoll_wait(pollHandle, events, EVENT_LIST_LENGTH, -1);
#endif
#ifdef __MACH__
struct kevent events[EVENT_LIST_LENGTH];
int count = kevent(queueHandle, changes, EVENT_LIST_LENGTH, events, EVENT_LIST_LENGTH, NULL);
#endif
if (count < 0)
{
int error = errno;
print("Error processing handles: %s (%d)\n", strerror(error), error);
break;
}
for (size_t index = 0; index < count; index ++)
{
#ifdef __linux__
struct epoll_event* event = events + index;
#endif
#ifdef __MACH__
struct kevent* event = events + index;
#endif
// Handle packet from the uplink
if (CHECK(event, uplinkHandle))
{
struct sockaddr_in6 address;
socklen_t size = sizeof(address);
size_t length = recvfrom(uplinkHandle, incomingBuffer, BUFFER_SIZE, 0, (struct sockaddr*)&address, &size);
if ((length >= sizeof(struct RewindData)) &&
((serverAddress->ai_addr->sa_family == AF_INET) || /* Work-around for Linux */
(memcmp(&address, serverAddress->ai_addr, serverAddress->ai_addrlen) == 0)) &&
(memcmp(incomingBuffer->sign, REWIND_PROTOCOL_SIGN, REWIND_SIGN_LENGTH) == 0))
{
uint16_t type = le16toh(incomingBuffer->type);
size_t length = le16toh(incomingBuffer->length);
if ((type <= REWIND_TYPE_PEER_DATA) &&
(type >= REWIND_TYPE_MEDIA_DATA))
{
int handle;
struct sockaddr_in* address;
selection = type - REWIND_TYPE_PEER_DATA;
address = repeaterSocketAddresses + selection;
handle = proxyHandles[selection];
sendto(handle, incomingBuffer->data, length, 0, (struct sockaddr*)address, sizeof(struct sockaddr_in));
continue;
}
if (type == REWIND_TYPE_REPORT)
{
incomingBuffer->data[length] = '\0';
print("Server message: %s\n", incomingBuffer->data);
continue;
}
if (type == REWIND_TYPE_CLOSE)
{
print("Disconnect request received\n");
running = false;
break;
}
}
}
// Handle packet from the repeater
if (CHECK(event, proxyHandles[0]))
{
struct msghdr message;
struct iovec vectors[2];
outgoingBuffer->type = htole16(REWIND_TYPE_BINDING_NOTICE);
outgoingBuffer->length = htole16(sizeof(proxyPorts));
vectors[0].iov_base = outgoingBuffer;
vectors[0].iov_len = sizeof(struct RewindData);
vectors[1].iov_base = proxyPorts;
vectors[1].iov_len = sizeof(proxyPorts);
message.msg_name = serverAddress->ai_addr;
message.msg_namelen = serverAddress->ai_addrlen;
message.msg_iov = vectors;
message.msg_iovlen = 2;
message.msg_control = NULL;
message.msg_controllen = 0;
message.msg_flags = 0;
sendmsg(uplinkHandle, &message, 0);
}
for (selection = 0; selection < PROXY_PORT_COUNT; selection ++)
{
int handle = proxyHandles[selection];
if (CHECK(event, handle))
{
socklen_t size = sizeof(struct sockaddr_in);
uint8_t* buffer = (uint8_t*)outgoingBuffer->data;
struct sockaddr_in* address = repeaterSocketAddresses + selection;
size_t length = recvfrom(handle, buffer, BUFFER_SIZE, 0, (struct sockaddr*)address, &size);
outgoingBuffer->type = htole16(REWIND_CLASS_TELLUS_DATA + selection);
outgoingBuffer->length = htole16(length);
length += sizeof(struct RewindData);
sendto(uplinkHandle, outgoingBuffer, length, 0, serverAddress->ai_addr, serverAddress->ai_addrlen);
}
}
// Handle signal from the kernel
#ifdef __linux__
if (event->data.fd == signalHandle)
{
struct signalfd_siginfo information;
read(signalHandle, &information, sizeof(information));
#endif
#ifdef __MACH__
if (event->filter == EVFILT_SIGNAL)
{
#endif
outgoingBuffer->type = htole16(REWIND_TYPE_CLOSE);
outgoingBuffer->length = 0;
sendto(uplinkHandle, outgoingBuffer, sizeof(struct RewindData), 0, serverAddress->ai_addr, serverAddress->ai_addrlen);
#ifdef __linux__
if ((information.ssi_signo == SIGINT) ||
(information.ssi_signo == SIGTERM) ||
(information.ssi_signo == SIGQUIT))
#endif
#ifdef __MACH__
if ((event->ident == SIGINT) ||
(event->ident == SIGTERM) ||
(event->ident == SIGQUIT))
#endif
{
running = false;
break;
}
}
}
}
print("Server stopped\n");
// Clean up
close(uplinkHandle);
close(proxyHandles[0]);
close(proxyHandles[1]);
close(proxyHandles[2]);
#ifdef __linux__
close(pollHandle);
close(signalHandle);
#endif
#ifdef __MACH__
close(queueHandle);
#endif
freeaddrinfo(serverAddress);
return EXIT_SUCCESS;
};

1
Version.h Normal file
View file

@ -0,0 +1 @@
#define VERSION 20161101

6
tellusagent.conf Normal file
View file

@ -0,0 +1,6 @@
CONNECT_PORT=50000
CONTROL_PORT=50001
MEDIA_PORT=50002
SERVER_ADDRESS=aesyle.dstar.su
SERVICE_MODE=1

33
tellusagent.sh Executable file
View file

@ -0,0 +1,33 @@
#!/bin/sh
DIRECTORY=$(dirname $0)
if [ -f $DIRECTORY/tellusagent.conf ]
then
# Read configuration from text file
# Dot is equivalent of bash's source
. $DIRECTORY/tellusagent.conf
fi
if [ -f /etc/config/tellusagent ]
then
# Read configuration from UCI/LuCI on OpenWRT
CONNECT_PORT=$(uci get tellusagent.@tellusagent[0].connectPort)
CONTROL_PORT=$(uci get tellusagent.@tellusagent[0].controlPort)
MEDIA_PORT=$(uci get tellusagent.@tellusagent[0].mediaPort)
fi
if [ -n "$1" ]
then
# 1 - print to standard output
# 2 - print to system log
# 6 - run as daemon and print to system log
SERVICE_MODE=$1
fi
$DIRECTORY/tellusagent \
--connect-port ${CONNECT_PORT} \
--control-port ${CONTROL_PORT} \
--media-port ${MEDIA_PORT} \
--server-address ${SERVER_ADDRESS} \
--service-mode ${SERVICE_MODE}

4
test.sh Executable file
View file

@ -0,0 +1,4 @@
#/bin/bash
make
./tellusagent.sh
make clean