#vomp_platform=crossraspberry
$(info selected $(vomp_platform))
-vomp_options=
+vomp_options=-DIPV6
# uncomment the line below if you want to build vomp application without a reboot option, automatically set for windows!
#vomp_options+= -DVOMP_HAS_EXIT
-OBJECTS1 = command.o tcp.o dsock.o thread.o timers.o i18n.o \
- message.o messagequeue.o udp.o wol.o audio.o video.o log.o mutex.o \
+OBJECTS1 = command.o tcp.o dsock.o thread.o timers.o i18n.o vdp6.o \
+ message.o messagequeue.o udp.o wol.o audio.o video.o log.o mutex.o \
vdr.o recman.o recording.o recinfo.o channel.o rectimer.o event.o \
- directory.o mark.o option.o \
- player.o playerradio.o vfeed.o afeed.o \
- demuxer.o demuxervdr.o demuxerts.o stream.o \
- region.o colour.o boxstack.o boxx.o tbboxx.o \
- vinfo.o vquestion.o vrecordinglist.o vrecordinglistclassic.o vrecordinglistadvanced.o vrecording.o \
- vepgsummary.o vepglistadvanced.o \
+ directory.o mark.o option.o player.o playerradio.o vfeed.o afeed.o \
+ demuxer.o demuxervdr.o demuxerts.o stream.o \
+ region.o colour.o boxstack.o boxx.o tbboxx.o vrecording.o \
+ vinfo.o vquestion.o vrecordinglist.o vrecordinglistclassic.o \
+ vrecordinglistadvanced.o vepgsummary.o vepglistadvanced.o \
vmute.o vvolume.o vtimerlist.o vtimeredit.o vrecordingmenu.o \
vchannellist.o vwelcome.o vvideorec.o vepgsettimer.o \
vchannelselect.o vserverselect.o vconnect.o vepg.o vrecmove.o \
vradiorec.o vaudioselector.o vscreensaver.o vopts.o \
- wselectlist.o wjpeg.o wsymbol.o wbutton.o wtextbox.o \
- woptionpane.o woptionbox.o wremoteconfig.o wtabbar.o \
- remote.o led.o mtd.o osd.o surface.o \
- vpicturebanner.o \
- abstractoption.o \
+ wselectlist.o wjpeg.o wsymbol.o wbutton.o wtextbox.o \
+ woptionpane.o woptionbox.o wremoteconfig.o wtabbar.o led.o \
+ remote.o mtd.o osd.o surface.o vpicturebanner.o abstractoption.o \
eventdispatcher.o vdrrequestpacket.o vdrresponsepacket.o \
- vvideolivetv.o vsleeptimer.o \
- playerlivetv.o playerliveradio.o \
- wprogressbar.o \
- bitmap.o dvbsubtitles.o \
- tfeed.o vteletextview.o teletextdecodervbiebu.o \
- teletxt/txtfont.o movieinfo.o seriesinfo.o wmovieview.o wseriesview.o tvmedia.o wtvmedia.o\
- wpictureview.o
-
-
+ vvideolivetv.o vsleeptimer.o playerlivetv.o playerliveradio.o \
+ wprogressbar.o bitmap.o dvbsubtitles.o tfeed.o vteletextview.o \
+ teletextdecodervbiebu.o teletxt/txtfont.o movieinfo.o seriesinfo.o \
+ wmovieview.o wseriesview.o tvmedia.o wtvmedia.o wpictureview.o
hints.ai_socktype = SOCK_STREAM;
if (getaddrinfo(host, portstring, &hints, &res))
{
+ //printf("[%s] [%s]\n", host, portstring);
return 0;
}
--- /dev/null
+/*
+ Copyright 2019 Chris Tallon
+
+ This file is part of VOMP.
+
+ VOMP is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ VOMP is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with VOMP. If not, see <https://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <net/if.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "defines.h"
+#include "vdr.h"
+#include "log.h"
+#include "vdp6.h"
+
+#if IPV6
+
+VDP6::VDP6()
+{
+}
+
+void VDP6::run()
+{
+ Log* logger = Log::getInstance();
+
+ if (pipe2(pfds, O_NONBLOCK) == -1)
+ {
+ logger->log("VDP6", Log::ERR, "pipe2 error");
+ return;
+ }
+
+ sock = socket(AF_INET6, SOCK_DGRAM, 0);
+ if (sock < 0)
+ {
+ logger->log("VDP6", Log::ERR, "socket error");
+ return;
+ }
+
+ struct sockaddr_in6 saddr;
+ memset(&saddr, 0, sizeof(saddr));
+ saddr.sin6_family = AF_INET6;
+ inet_pton(AF_INET6, "ff15:766f:6d70:2064:6973:636f:7665:7279", &saddr.sin6_addr);
+ saddr.sin6_port = htons(51056);
+
+ receiveThread = std::thread( [this, logger]
+ {
+ socklen_t addrlen = sizeof(struct sockaddr_in6);
+ char vdpreply[1000];
+ fd_set readfds;
+ struct timeval timeout;
+ timeout.tv_sec = 1;
+ timeout.tv_usec = 500000;
+
+ while(1)
+ {
+ FD_ZERO(&readfds);
+ FD_SET(sock, &readfds);
+ FD_SET(pfds[0], &readfds);
+
+ int sresult = select(((sock > pfds[0]) ? sock : pfds[0]) + 1, &readfds, NULL, NULL, &timeout);
+ if (sresult < 1) break;
+
+ if (FD_ISSET(pfds[0], &readfds)) break;
+
+ int mlength;
+ struct sockaddr_in6 theirAddr;
+ mlength = recvfrom(sock, vdpreply, 1000, 0, (struct sockaddr *)&theirAddr, &addrlen);
+ if (mlength == -1)
+ {
+ logger->log("VDP6", Log::ERR, "recvfrom error");
+ break;
+ }
+
+ VDRServer newServer;
+ // FIXME upgrade this to look for a return IP in the reply packet
+ newServer.ip = new char[40];
+ inet_ntop(AF_INET6, &theirAddr.sin6_addr, newServer.ip, sizeof(theirAddr));
+
+ USHORT tempPort;
+ memcpy(&tempPort, &vdpreply[26], 2);
+ newServer.port = ntohs(tempPort);
+
+ ULONG newServerVersion;
+ memcpy(&newServerVersion, &vdpreply[28], 4);
+ newServer.version = ntohl(newServerVersion);
+
+ int newServerNameLength = mlength - 32;
+ newServer.name = new char[newServerNameLength];
+ strcpy(newServer.name, &vdpreply[32]);
+
+ logger->log("VDP6", Log::INFO, "Got response: %s %u %s %lx", newServer.ip, newServer.port, newServer.name, newServer.version);
+ servers.push_back(newServer);
+ }
+ });
+
+ char message[15];
+ memset(message, 0, 15);
+ strcpy(message, "VDP-0001");
+
+ struct if_nameindex* ifs = if_nameindex();
+ int ifIndex;
+
+ for(int i = 0; ifs[i].if_index > 0; i++)
+ {
+ ifIndex = ifs[i].if_index;
+ int d = setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifIndex, sizeof(ifIndex));
+ d = sendto(sock, message, 15, 0, (struct sockaddr*)&saddr, sizeof(saddr));
+ if (d > 0) logger->log("VDP6", Log::DEBUG, "Transmitted IPv6 MC UDP on %s", ifs[i].if_name);
+ }
+
+ if_freenameindex(ifs);
+}
+
+int VDP6::numFound()
+{
+ return servers.size();
+}
+
+void VDP6::stop()
+{
+ write(pfds[1], "X", 1);
+ receiveThread.join();
+
+ close(pfds[0]);
+ close(pfds[1]);
+ close(sock);
+}
+
+#endif
--- /dev/null
+/*
+ Copyright 2019 Chris Tallon
+
+ This file is part of VOMP.
+
+ VOMP is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ VOMP is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with VOMP. If not, see <https://www.gnu.org/licenses/>.
+*/
+
+#ifndef VDP_H
+#define VDP_H
+
+#include <thread>
+#include <vector>
+
+#if IPV6
+
+class VDRServer;
+
+/*
+ * Until VDP is reorganised, getServers must be called after stop
+ * and the buffers pointed to by the VDRServer structs must be freed
+ * by the caller.
+ */
+
+class VDP6
+{
+ public:
+ VDP6();
+
+ void run();
+ void stop();
+ int numFound();
+ vector<VDRServer>* getServers() { return &servers; }
+
+ private:
+ int pfds[2];
+ int sock;
+ std::thread receiveThread;
+ vector<VDRServer> servers;
+};
+
+#endif
+
+
+
+#endif
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with VOMP; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ along with VOMP. If not, see <https://www.gnu.org/licenses/>.
*/
#include "vdr.h"
#include "vdrrequestpacket.h"
#include "vdrresponsepacket.h"
#include "command.h"
+#include "vdp6.h"
#ifdef VOMP_MEDIAPLAYER
#include "media.h"
#include "mediaprovider.h"
strcpy(message, "VDP-0001");
/*tcp->getMAC(&message[9]); put mac here when TCP modified to do this*/
+#if IPV6
+ // FIXME Horrible hack. Rewrite all this.
+ // Change away from relying on the dsock select to do the timing
+ // Do timing here and let UDP4 / UDP6 objects/threads just wait
+ // for responses
+ VDP6 vdp6;
+ vdp6.run();
+#endif
+
DatagramSocket ds(0);
int haveAtLeastOne = 0;
int retval;
else
{
if (haveAtLeastOne) break;
+#if IPV6
+ if (vdp6.numFound()) break;
+#endif
+
waitType = 1;
firstloop = false;
/* For DEBUGGING *
servers.push_back(newServer);
waitType = 2;
haveAtLeastOne = 1;}/ * */
+ }
+ }
+ logger->log("VDR", Log::NOTICE, "END loop");
+#if IPV6
+ vdp6.stop();
+ vector<VDRServer>* servers6 = vdp6.getServers();
+
+ // Add IPv6 found servers to servers vector, if not in servers already
+ // Free buffers from VDRServer objects if not taken. (Itching for that rewrite already).
+
+ for(auto i6 = servers6->begin(); i6 != servers6->end(); i6++)
+ {
+ bool found = false;
+ for(auto i4 = servers.begin(); i4 != servers.end(); i4++)
+ {
+ if (!strcmp(i4->name, i6->name)) { found = true; break; }
+ }
+ if (found)
+ {
+ delete[] i6->name;
+ delete[] i6->ip;
+ }
+ else
+ {
+ servers.push_back(*i6);
}
}
- logger->log("VDR", Log::NOTICE, "END loop");
+
+#endif
+
sort(servers.begin(), servers.end(), ServerSorter());
}
int findingServer;
TCP* tcp;
int port;
- char serverIP[16];
+ char serverIP[40];
USHORT serverPort;
bool connected;
ULONG maxChannelNumber;