summaryrefslogtreecommitdiffstats
path: root/Src/Multiplexer/udp-stream.c
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Multiplexer/udp-stream.c')
-rw-r--r--Src/Multiplexer/udp-stream.c127
1 files changed, 127 insertions, 0 deletions
diff --git a/Src/Multiplexer/udp-stream.c b/Src/Multiplexer/udp-stream.c
new file mode 100644
index 0000000..c830789
--- /dev/null
+++ b/Src/Multiplexer/udp-stream.c
@@ -0,0 +1,127 @@
+/*
+ * Video On Demand Samples
+ *
+ * Copyright (C) 2015 Microchip Technology Germany II GmbH & Co. KG
+ *
+ * This program 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * You may also obtain this software under a propriety license from Microchip.
+ * Please contact Microchip for further information.
+ *
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <errno.h>
+#include "Console.h"
+
+/*----------------------------------------------------------*/
+/*! \brief Private structure used by UdpStream component.
+ */
+/*----------------------------------------------------------*/
+typedef struct localVar_tag
+{
+ ///Socket handle.
+ int sock;
+ ///Target port.
+ int port;
+ ///Target IP address as zero terminated string.
+ char targetIpAddress[32];
+ ///SocketAddress structure to address remote node.
+ struct sockaddr_in destination;
+ ///Helper variable to suppress a lot of error messages.
+ bool errorMode;
+} localVar_t;
+
+static localVar_t udpLocal;
+
+bool UdpStream_Init( const char *targetIp, int targetPort )
+{
+ if( ( NULL == targetIp ) || ( 0 == targetPort ) )
+ {
+ return false;
+ }
+ ConsolePrintf( PRIO_HIGH, "Sending UDP stream to IP:'%s', port:%d\n", targetIp, targetPort );
+ strcpy( udpLocal.targetIpAddress, targetIp );
+ udpLocal.port = targetPort;
+ udpLocal.errorMode = false;
+
+ memset( &udpLocal.destination, 0, sizeof( udpLocal.destination ) );
+
+ /* Default send address */
+ udpLocal.destination.sin_family = AF_INET;
+ udpLocal.destination.sin_addr.s_addr = inet_addr( udpLocal.targetIpAddress );
+ udpLocal.destination.sin_port = htons( udpLocal.port );
+
+ if( ( udpLocal.sock = socket( PF_INET, SOCK_DGRAM, IPPROTO_UDP ) ) < 0 )
+ {
+ ConsolePrintf( PRIO_ERROR, RED"Failed to create socket"RESETCOLOR"\n" );
+ return false;
+ }
+#if defined (SO_REUSEADDR) && defined (SO_REUSEPORT)
+ int one = 1;
+ setsockopt(udpLocal.sock, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &one, sizeof(one));
+#endif
+
+ /* set default destination */
+ setsockopt( udpLocal.sock, IPPROTO_IP, IP_MULTICAST_IF, &udpLocal.destination, sizeof( udpLocal.destination ) );
+
+ // this call is what allows broadcast packets to be sent:
+ int enableSocketFlag = 1;
+ if( setsockopt( udpLocal.sock, SOL_SOCKET, SO_BROADCAST, &enableSocketFlag, sizeof( enableSocketFlag ) ) < 0 )
+ {
+ ConsolePrintf( PRIO_ERROR, RED"setsockopt (SO_BROADCAST) failed"RESETCOLOR"\n" );
+ return false;
+ }
+ int ttl = 5;
+ if (!(setsockopt( udpLocal.sock, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)))) {
+ ConsolePrintf( PRIO_HIGH, "TTL set successfully to %d\n", ttl );
+ } else {
+ ConsolePrintf( PRIO_ERROR, "Error setting TTL: %s\n", strerror(errno));
+ }
+
+ return true;
+}
+
+void UdpStream_Close()
+{
+ close( udpLocal.sock );
+}
+
+bool UdpStream_Send( const uint8_t *data, uint32_t length )
+{
+ int is_length = sendto( udpLocal.sock, data, length,
+ 0, ( struct sockaddr * )&udpLocal.destination, sizeof( udpLocal.destination ) );
+ if( is_length != length )
+ {
+ if( !udpLocal.errorMode )
+ {
+ udpLocal.errorMode = true;
+ ConsolePrintf( PRIO_ERROR, RED"Send failed; shall len = %d; is length = %d"RESETCOLOR"\n", length, is_length );
+ }
+ return false;
+ }
+ else
+ udpLocal.errorMode = false;
+
+ return true;
+}