15 #include <sys/types.h>
21 #include <visiontransfer/internal/internalinformation.h>
22 #include <visiontransfer/internal/networking.h>
23 #include <visiontransfer/internal/datachannelservicebase.h>
27 using namespace visiontransfer;
28 using namespace visiontransfer::internal;
30 namespace visiontransfer {
33 DataChannelServiceBase::DataChannelServiceBase() {
35 if((dataChannelSocket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
36 throw std::runtime_error(
"Error creating data channel service socket!");
39 Networking::enableReuseAddress(dataChannelSocket,
true);
42 sockaddr_in localAddr;
43 memset(&localAddr, 0,
sizeof(localAddr));
44 localAddr.sin_family = AF_INET;
45 localAddr.sin_port = htons(InternalInformation::DATACHANNELSERVICE_PORT);
46 localAddr.sin_addr.s_addr = htonl(INADDR_ANY);
47 if(::bind(dataChannelSocket, (sockaddr *)&localAddr,
sizeof(localAddr)) != 0) {
48 throw std::runtime_error(
"Error binding dataChannel socket!");
51 Networking::setSocketBlocking(dataChannelSocket,
false);
54 DataChannelServiceBase::~DataChannelServiceBase() {
55 Networking::closeSocket(dataChannelSocket);
58 void DataChannelServiceBase::process() {
59 static unsigned char buffer[100000];
60 static sockaddr_in senderAddress;
61 static socklen_t senderLength = (socklen_t)
sizeof(senderAddress);
66 received = recvfrom(dataChannelSocket, (
char*) buffer,
sizeof(buffer), 0, (sockaddr *)&senderAddress, &senderLength);
70 message.header.channelID = (DataChannel::ID) raw->channelID;
71 message.header.channelType = (DataChannel::Type) raw->channelType;
72 message.header.payloadSize = ntohl(raw->payloadSize);
75 std::cerr <<
"DataChannelServiceBase: Size mismatch in UDP message, type " << (int) message.header.channelType <<
" ID " << (
int) message.header.channelID <<
" - discarded!" << std::endl;
77 if (!(message.header.channelType)) {
78 handleChannel0Message(message, &senderAddress);
81 auto it = channels.find(message.header.channelID);
82 if (it != channels.end()) {
83 it->second->handleMessage(message, &senderAddress);
92 for (
auto& kv: channels) {
99 int DataChannelServiceBase::sendDataInternal(
unsigned char* compiledMessage,
unsigned int messageSize, sockaddr_in* recipient) {
100 if (!recipient)
throw std::runtime_error(
"Requested sendDataInternal without recipient address");
104 if (messageSize != reportedSize)
throw std::runtime_error(
"Message size does not match");
106 result = sendto(dataChannelSocket, (
char*) compiledMessage, reportedSize, 0, (sockaddr*) recipient,
sizeof(*recipient));
107 if (result != (
int) reportedSize) {
108 std::cerr <<
"Error sending DataChannel message to " << inet_ntoa(recipient->sin_addr) <<
": " << Networking::getLastErrorString() << std::endl;
109 throw std::runtime_error(
"Error during sendto");
115 int DataChannelServiceBase::sendDataIsolatedPacket(DataChannel::ID
id, DataChannel::Type type,
unsigned char* data,
unsigned int dataSize, sockaddr_in* recipient) {
117 unsigned char* buf =
new unsigned char[msgSize]();
119 header->channelID = id;
120 header->channelType = type;
121 header->payloadSize = htonl(dataSize);
124 int result = sendDataInternal(buf, msgSize, recipient);
129 DataChannel::ID DataChannelServiceBase::registerChannel(std::shared_ptr<DataChannel> channel) {
131 DataChannel::ID
id = (DataChannel::ID) channel->getChannelType();
132 if (channels.count(
id)) {
136 if (!channel->initialize())
return 0;
137 channel->setChannelID(
id);
138 channels[id] = channel;
139 channel->setService(shared_from_this());
142 int DataChannel::sendData(
unsigned char* data,
unsigned int dataLen, sockaddr_in* recipient) {
143 if (
auto srv = service.lock()) {
144 return srv->sendDataIsolatedPacket(channelID, getChannelType(), data, dataLen, recipient);