3
Fork 0

Updated to support brand new External Server Interface

This commit is contained in:
R3ABM Artem 2016-07-08 15:25:19 +04:00
parent ee57e48d53
commit 4ea54ae61a
5 changed files with 129 additions and 94 deletions

View file

@ -45,11 +45,11 @@
#define ASN_CONSTRUCTOR 0x20
#endif
// #include "RA-RTP.h"
#ifndef RA_RTP_H
#define RTP_PROTOCOL_VERSION 2
#define RTP_CONTROL_VERSION_SHIFT 6
#define RTP_HEADER_MINIMAL_LENGTH 12
// #include "KAIROS-HAM.h"
#ifndef KAIROS_HAM_H
#define KAIROS_HAM_DEFAULT_PORT 65472
#define KAIROS_HAM_RECORD_ID 0xcbfaded8
#define KAIROS_EXCHANGE_HEADER_LENGTH 12
#endif
// #include "RemoteControl.h"
@ -99,8 +99,7 @@
#define MODE_SYSLOG (1 << 1)
#define MODE_DAEMON (1 << 2)
#define MEDIA_PORT_COUNT (REWIND_TYPE_ANALOG_DATA - REWIND_TYPE_SLOT_1_VOICE + 1)
#define EVENT_LIST_LENGTH (4 + 1 + 3 + MEDIA_PORT_COUNT)
#define EVENT_LIST_LENGTH (4 + 1 + 4)
#define BUFFER_SIZE 4096
#define EXPIRATION_TIME 20
@ -136,7 +135,7 @@ int main(int argc, const char* argv[])
// Parameters of repeater
int proxyTrapPort = 162;
int proxyBasePort = 40000;
int proxyMediaPort = KAIROS_HAM_DEFAULT_PORT;
uint32_t repeaterNumber = 0;
int repeaterControlPort = REMOTE_DEFAULT_PORT;
@ -155,7 +154,7 @@ int main(int argc, const char* argv[])
{ "server-password", required_argument, NULL, 'w' },
{ "server-address", required_argument, NULL, 's' },
{ "server-port", required_argument, NULL, 'p' },
{ "base-port", required_argument, NULL, 'b' },
{ "media-port", required_argument, NULL, 'b' },
{ "trap-port", required_argument, NULL, 't' },
{ "service-mode", required_argument, NULL, 'm' },
{ NULL, 0, NULL, 0 }
@ -190,7 +189,7 @@ int main(int argc, const char* argv[])
break;
case 'b':
proxyBasePort = strtol(optarg, NULL, 10);
proxyMediaPort = strtol(optarg, NULL, 10);
break;
case 't':
@ -215,8 +214,8 @@ int main(int argc, const char* argv[])
" --repeater-port <port number of interface Remote Control>\n"
" --server-password <access password of BrandMeister DMR Server>\n"
" --server-address <domain name of BrandMeister DMR Server>\n"
" --server-port <port number of RadioActivity Console>\n"
" --base-port <base port for RTP Media>\n"
" --server-port <local port for BrandMeister DMR Server>\n"
" --media-port <media port for KAIROS External Servier>\n"
" --trap-port <port for SNMP Traps>\n"
" --service-mode <set of bits>\n"
" bit 0 - print to standard output\n"
@ -287,8 +286,8 @@ int main(int argc, const char* argv[])
// Initialize proxy sockets
int trapHandle;
int mediaHandle;
int remoteHandle;
int mediaHandles[MEDIA_PORT_COUNT];
struct sockaddr_in proxySocketAddress;
proxySocketAddress.sin_family = AF_INET;
@ -312,17 +311,13 @@ int main(int argc, const char* argv[])
return EXIT_FAILURE;
}
for (size_t index = 0; index < MEDIA_PORT_COUNT; index ++)
proxySocketAddress.sin_port = htons(proxyMediaPort);
mediaHandle = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if((mediaHandle < 0) ||
(bind(mediaHandle, (struct sockaddr*)&proxySocketAddress, sizeof(proxySocketAddress)) < 0))
{
proxySocketAddress.sin_port = htons(proxyBasePort + index * 10);
int handle = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if((handle < 0) ||
(bind(handle, (struct sockaddr*)&proxySocketAddress, sizeof(proxySocketAddress)) < 0))
{
print("Error opening port for RTP Media\n");
return EXIT_FAILURE;
}
mediaHandles[index] = handle;
print("Error opening port for KAIROS External Server\n");
return EXIT_FAILURE;
}
// Initialize uplink socket
@ -343,6 +338,11 @@ int main(int argc, const char* argv[])
return EXIT_FAILURE;
}
// Configure socket options
int value = true;
setsockopt(remoteHandle, IPPROTO_IP, IP_PKTINFO, &value, sizeof(value));
#ifdef __linux__
// Initialize timer handle
@ -378,12 +378,9 @@ int main(int argc, const char* argv[])
pollHandle = epoll_create(EVENT_LIST_LENGTH);
for (size_t index = 0; index < MEDIA_PORT_COUNT; index ++)
{
event.events = EPOLLIN;
event.data.fd = mediaHandles[index];
epoll_ctl(pollHandle, EPOLL_CTL_ADD, event.data.fd, &event);
}
event.events = EPOLLIN;
event.data.fd = mediaHandle;
epoll_ctl(pollHandle, EPOLL_CTL_ADD, event.data.fd, &event);
event.events = EPOLLIN;
event.data.fd = trapHandle;
@ -429,11 +426,8 @@ int main(int argc, const char* argv[])
queueHandle = kqueue();
for (size_t index = 0; index < MEDIA_PORT_COUNT; index ++)
{
EV_SET(change, mediaHandles[index], EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, 0);
change ++;
}
EV_SET(change, mediaHandle, EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, 0);
change ++;
EV_SET(change, uplinkHandle, EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, 0);
change ++;
@ -479,7 +473,14 @@ int main(int argc, const char* argv[])
size_t passwordLength = strlen(serverPassword);
time_t watchDog = now.tv_sec + EXPIRATION_TIME;
uint32_t sequenceNumber = 0;
uint32_t sequenceNumbers[] =
{
0,
0,
0,
0
};
// Main loop
@ -530,13 +531,10 @@ int main(int argc, const char* argv[])
uint16_t type = le16toh(incomingBuffer->type);
size_t length = le16toh(incomingBuffer->length);
if ((type >= REWIND_TYPE_SLOT_1_VOICE) &&
(type <= REWIND_TYPE_ANALOG_DATA))
if (type == REWIND_TYPE_EXTERNAL_SERVER)
{
size_t index = type - REWIND_TYPE_SLOT_1_VOICE;
repeaterSocketAddress.sin_port = htons(proxyBasePort + index * 10);
sendto(mediaHandles[index], incomingBuffer->data, length, 0, (struct sockaddr*)&repeaterSocketAddress, sizeof(struct sockaddr_in));
repeaterSocketAddress.sin_port = htons(proxyMediaPort);
sendto(mediaHandle, incomingBuffer->data, length, 0, (struct sockaddr*)&repeaterSocketAddress, sizeof(struct sockaddr_in));
continue;
}
@ -544,7 +542,6 @@ int main(int argc, const char* argv[])
{
repeaterSocketAddress.sin_port = htons(repeaterControlPort);
sendto(remoteHandle, incomingBuffer->data, length, 0, (struct sockaddr*)&repeaterSocketAddress, sizeof(struct sockaddr_in));
continue;
}
@ -563,7 +560,7 @@ int main(int argc, const char* argv[])
SHA256(incomingBuffer->data, length + passwordLength, outgoingBuffer->data);
outgoingBuffer->type = htole16(REWIND_TYPE_AUTHENTICATION);
outgoingBuffer->number = htole32(++ sequenceNumber);
outgoingBuffer->number = htole32(++ sequenceNumbers[0]);
outgoingBuffer->length = htole16(SHA256_DIGEST_LENGTH);
sendto(uplinkHandle, outgoingBuffer, sizeof(struct RewindData) + SHA256_DIGEST_LENGTH, 0, serverAddress->ai_addr, serverAddress->ai_addrlen);
@ -591,30 +588,29 @@ int main(int argc, const char* argv[])
}
}
// Handle packet of RTP
// Handle packet of External Server
for (size_t index = 0; index < MEDIA_PORT_COUNT; index ++)
if (CHECK(event, mediaHandle))
{
if (CHECK(event, mediaHandles[index]))
{
struct sockaddr_in address;
socklen_t size = sizeof(address);
uint8_t* buffer = (uint8_t*)outgoingBuffer->data;
size_t length = recvfrom(mediaHandles[index], buffer, BUFFER_SIZE, 0, (struct sockaddr*)&address, &size);
struct sockaddr_in address;
socklen_t size = sizeof(address);
uint8_t* buffer = (uint8_t*)outgoingBuffer->data;
size_t length = recvfrom(mediaHandle, buffer, BUFFER_SIZE, 0, (struct sockaddr*)&address, &size);
if ((size == sizeof(struct sockaddr_in)) &&
(address.sin_addr.s_addr == repeaterSocketAddress.sin_addr.s_addr) &&
((buffer[0] >> RTP_CONTROL_VERSION_SHIFT) == RTP_PROTOCOL_VERSION) &&
(length >= RTP_HEADER_MINIMAL_LENGTH))
{
outgoingBuffer->type = htole16(index + REWIND_TYPE_SLOT_1_VOICE);
outgoingBuffer->number = htole32(++ sequenceNumber);
outgoingBuffer->length = htole16(length);
length += sizeof(struct RewindData);
sendto(uplinkHandle, outgoingBuffer, length, 0, serverAddress->ai_addr, serverAddress->ai_addrlen);
}
break;
if ((size == sizeof(struct sockaddr_in)) &&
(address.sin_addr.s_addr == repeaterSocketAddress.sin_addr.s_addr) &&
(length >= KAIROS_EXCHANGE_HEADER_LENGTH) &&
(le32toh(*(uint32_t*)buffer) == KAIROS_HAM_RECORD_ID))
{
uint16_t number = ++ sequenceNumbers[buffer[8] & 3];
outgoingBuffer->type = htole16(REWIND_TYPE_EXTERNAL_SERVER);
outgoingBuffer->flags = htole16(buffer[8] < 4);
outgoingBuffer->number = htole32(number);
outgoingBuffer->length = htole16(length);
length += sizeof(struct RewindData);
sendto(uplinkHandle, outgoingBuffer, length, 0, serverAddress->ai_addr, serverAddress->ai_addrlen);
}
continue;
}
// Handle packet of Remote Control
@ -622,22 +618,62 @@ int main(int argc, const char* argv[])
if (CHECK(event, remoteHandle))
{
struct sockaddr_in address;
socklen_t size = sizeof(address);
uint8_t* buffer = (uint8_t*)outgoingBuffer->data;
size_t length = recvfrom(remoteHandle, buffer, BUFFER_SIZE, 0, (struct sockaddr*)&address, &size);
if ((size == sizeof(struct sockaddr_in)) &&
struct iovec vector;
vector.iov_base = buffer;
vector.iov_len = BUFFER_SIZE;
struct msghdr message;
message.msg_name = &address;
message.msg_namelen = sizeof(address);
message.msg_iov = &vector;
message.msg_iovlen = 1;
message.msg_control = alloca(BUFFER_SIZE);
message.msg_controllen = BUFFER_SIZE;
message.msg_flags = 0;
size_t length = recvmsg(remoteHandle, &message, 0);
if ((message.msg_namelen == sizeof(struct sockaddr_in)) &&
(address.sin_addr.s_addr == repeaterSocketAddress.sin_addr.s_addr) &&
(buffer[0] == REMOTE_STX) &&
(buffer[length - 1] == REMOTE_ETX) &&
(length >= 8))
{
outgoingBuffer->type = htole16(REWIND_TYPE_REMOTE_CONTROL);
outgoingBuffer->number = htole32(++ sequenceNumber);
outgoingBuffer->number = htole32(++ sequenceNumbers[0]);
outgoingBuffer->length = htole16(length);
length += sizeof(struct RewindData);
sendto(uplinkHandle, outgoingBuffer, length, 0, serverAddress->ai_addr, serverAddress->ai_addrlen);
// Transmit destination address of received packet
// to make correct messages for External Server interface
struct cmsghdr* control = CMSG_FIRSTHDR(&message);
while (control != NULL)
{
if (control->cmsg_type == IP_PKTINFO)
{
struct in_pktinfo* information = (struct in_pktinfo*)CMSG_DATA(control);
size_t length = sizeof(struct RewindAddressData);
struct RewindAddressData* data = (struct RewindAddressData*)outgoingBuffer->data;
data->address = information->ipi_addr;
data->port = htons(proxyMediaPort);
outgoingBuffer->type = htole16(REWIND_TYPE_ADDRESS_NOTICE);
outgoingBuffer->number = htole32(++ sequenceNumbers[0]);
outgoingBuffer->length = htobe16(length);
length += sizeof(struct RewindData);
sendto(uplinkHandle, outgoingBuffer, length, 0, serverAddress->ai_addr, serverAddress->ai_addrlen);
break;
}
control = CMSG_NXTHDR(&message, control);
}
}
continue;
}
@ -656,7 +692,7 @@ int main(int argc, const char* argv[])
(length >= 20))
{
outgoingBuffer->type = htole16(REWIND_TYPE_SNMP_TRAP);
outgoingBuffer->number = htole32(++ sequenceNumber);
outgoingBuffer->number = htole32(++ sequenceNumbers[0]);
outgoingBuffer->length = htole16(length);
length += sizeof(struct RewindData);
sendto(uplinkHandle, outgoingBuffer, length, 0, serverAddress->ai_addr, serverAddress->ai_addrlen);
@ -692,7 +728,7 @@ int main(int argc, const char* argv[])
data->number = htole32(repeaterNumber);
outgoingBuffer->type = htole16(REWIND_TYPE_KEEP_ALIVE);
outgoingBuffer->number = htole32(++ sequenceNumber);
outgoingBuffer->number = htole32(++ sequenceNumbers[0]);
outgoingBuffer->length = htobe16(length);
length += sizeof(struct RewindData);
sendto(uplinkHandle, outgoingBuffer, length, 0, serverAddress->ai_addr, serverAddress->ai_addrlen);
@ -713,7 +749,7 @@ int main(int argc, const char* argv[])
{
#endif
outgoingBuffer->type = htole16(REWIND_TYPE_CLOSE);
outgoingBuffer->number = htole32(++ sequenceNumber);
outgoingBuffer->number = htole32(++ sequenceNumbers[0]);
outgoingBuffer->length = 0;
sendto(uplinkHandle, outgoingBuffer, sizeof(struct RewindData), 0, serverAddress->ai_addr, serverAddress->ai_addrlen);
#ifdef __linux__
@ -740,14 +776,9 @@ int main(int argc, const char* argv[])
close(uplinkHandle);
close(remoteHandle);
close(mediaHandle);
close(trapHandle);
for (size_t index = 0; index < MEDIA_PORT_COUNT; index ++)
{
int handle = mediaHandles[index];
close(handle);
}
#ifdef __linux__
close(pollHandle);
close(timerHandle);

View file

@ -2,11 +2,8 @@ BUILD := $(shell date -u +%Y%m%d-%H%M%S)
OS := $(shell uname -s)
PREFIX = $(DESTDIR)/opt/CronosAgent
TOOLKIT = ../..
DIRECTORIES = \
$(TOOLKIT)/Common \
$(TOOLKIT)/KAIROS
DIRECTORIES =
ifeq ($(OS), Linux)
LIBRARIES += \
@ -46,14 +43,14 @@ install:
install -D -d $(PREFIX)
install -o root -g root cronosagent $(PREFIX)
install -o root -g root cronosagent.sh $(PREFIX)
install -o root -g root cronosagent-init $(PREFIX)
install -m 644 -o root -g root Main/brandmeister-monit $(PREFIX)
install -m 644 -o root -g root Main/brandmeister.plist $(PREFIX)
install -m 644 -o root -g root Main/brandmeister.service $(PREFIX)
# install -o root -g root cronosagent-init $(PREFIX)
# install -m 644 -o root -g root cronosagent-monit $(PREFIX)
# install -m 644 -o root -g root cronosagent.plist $(PREFIX)
install -m 644 -o root -g root cronosagent.service $(PREFIX)
clean:
rm -f $(PREREQUISITES) $(OBJECTS) cronosagent
rm -f *.d $(TOOLKIT)/*/*.d
rm -f *.d
version:
echo "#define VERSION $(shell svn info | grep -E "^Revision:" | grep -o -E "[0-9]+")" > Version.h

View file

@ -2,6 +2,7 @@
#define REWIND_H
#include <stdint.h>
#include <netinet/in.h>
#ifdef __cplusplus
extern "C"
@ -29,15 +30,13 @@ extern "C"
#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_REMOTE_CONTROL (REWIND_CLASS_KAIROS_DATA + 0)
#define REWIND_TYPE_SNMP_TRAP (REWIND_CLASS_KAIROS_DATA + 1)
#define REWIND_TYPE_SLOT_1_VOICE (REWIND_CLASS_KAIROS_DATA + 2)
#define REWIND_TYPE_SLOT_2_VOICE (REWIND_CLASS_KAIROS_DATA + 3)
#define REWIND_TYPE_ANALOG_VOICE (REWIND_CLASS_KAIROS_DATA + 4)
#define REWIND_TYPE_SLOT_1_DATA (REWIND_CLASS_KAIROS_DATA + 5)
#define REWIND_TYPE_SLOT_2_DATA (REWIND_CLASS_KAIROS_DATA + 6)
#define REWIND_TYPE_ANALOG_DATA (REWIND_CLASS_KAIROS_DATA + 7)
#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_FLAG_REAL_TIME (1 << 0)
struct RewindVersionData
{
@ -45,6 +44,12 @@ struct RewindVersionData
char version[0]; // Software version
};
struct RewindAddressData
{
struct in_addr address;
uint16_t port;
};
struct RewindData
{
char sign[REWIND_SIGN_LENGTH];

View file

@ -10,6 +10,8 @@
<array>
<string>6</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
</dict>

View file

@ -1,4 +1,4 @@
#/bin/bash
#!/bin/bash
REPEATER_NUMBER=250304
REPEATER_ADDRESS=172.33.20.136