diff --git a/protocoludp.c b/protocoludp.c index e688c45..e4eb66b 100644 --- a/protocoludp.c +++ b/protocoludp.c @@ -35,59 +35,25 @@ cIptvProtocolUdp::~cIptvProtocolUdp() free(sourceAddr); } -bool cIptvProtocolUdp::JoinMulticast(void) -{ - debug("cIptvProtocolUdp::JoinMulticast()\n"); - // Check that stream address is valid - if (!isActive && !isempty(streamAddr)) { - // Ensure that socket is valid - OpenSocket(socketPort, isempty(sourceAddr) ? INADDR_ANY : inet_addr(sourceAddr)); - // Join a new multicast group - struct ip_mreq mreq; - mreq.imr_multiaddr.s_addr = inet_addr(streamAddr); - mreq.imr_interface.s_addr = htonl(INADDR_ANY); - int err = setsockopt(socketDesc, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, - sizeof(mreq)); - ERROR_IF_RET(err < 0, "setsockopt()", return false); - // Update multicasting flag - isActive = true; - } - return true; -} - -bool cIptvProtocolUdp::DropMulticast(void) -{ - debug("cIptvProtocolUdp::DropMulticast()\n"); - // Check that stream address is valid - if (isActive && !isempty(streamAddr)) { - // Ensure that socket is valid - OpenSocket(socketPort, isempty(sourceAddr) ? INADDR_ANY : inet_addr(sourceAddr)); - // Drop the multicast group - struct ip_mreq mreq; - mreq.imr_multiaddr.s_addr = inet_addr(streamAddr); - mreq.imr_interface.s_addr = htonl(INADDR_ANY); - int err = setsockopt(socketDesc, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, - sizeof(mreq)); - ERROR_IF_RET(err < 0, "setsockopt()", return false); - // Update multicasting flag - isActive = false; - } - return true; -} - bool cIptvProtocolUdp::Open(void) { debug("cIptvProtocolUdp::Open()\n"); - // Join a new multicast group - JoinMulticast(); + if (!isempty(streamAddr)) { + // Join a new multicast group + OpenSocket(socketPort, isempty(sourceAddr) ? INADDR_ANY : inet_addr(sourceAddr)); + JoinMulticast(inet_addr(streamAddr)); + } return true; } bool cIptvProtocolUdp::Close(void) { debug("cIptvProtocolUdp::Close()\n"); - // Drop the multicast group - DropMulticast(); + if (!isempty(streamAddr)) { + // Drop the multicast group + OpenSocket(socketPort, isempty(sourceAddr) ? INADDR_ANY : inet_addr(sourceAddr)); + DropMulticast(inet_addr(streamAddr)); + } // Close the socket CloseSocket(); return true; @@ -103,7 +69,10 @@ bool cIptvProtocolUdp::Set(const char* Location, const int Parameter, const int debug("cIptvProtocolUdp::Set(): Location=%s Parameter=%d Index=%d\n", Location, Parameter, Index); if (!isempty(Location)) { // Drop the multicast group - DropMulticast(); + if (!isempty(streamAddr)) { + OpenSocket(socketPort, isempty(sourceAddr) ? INADDR_ANY : inet_addr(sourceAddr)); + DropMulticast(inet_addr(streamAddr)); + } // Update stream address and port streamAddr = strcpyrealloc(streamAddr, Location); char *p = strstr(streamAddr, ";"); @@ -115,7 +84,10 @@ bool cIptvProtocolUdp::Set(const char* Location, const int Parameter, const int sourceAddr = strcpyrealloc(sourceAddr, ""); socketPort = Parameter; // Join a new multicast group - JoinMulticast(); + if (!isempty(streamAddr)) { + OpenSocket(socketPort, isempty(sourceAddr) ? INADDR_ANY : inet_addr(sourceAddr)); + JoinMulticast(inet_addr(streamAddr)); + } } return true; } diff --git a/protocoludp.h b/protocoludp.h index 1d35f53..3cfe0af 100644 --- a/protocoludp.h +++ b/protocoludp.h @@ -17,10 +17,6 @@ private: char* streamAddr; char* sourceAddr; -private: - bool JoinMulticast(void); - bool DropMulticast(void); - public: cIptvProtocolUdp(); virtual ~cIptvProtocolUdp(); diff --git a/socket.c b/socket.c index 62c67a1..05ade5d 100644 --- a/socket.c +++ b/socket.c @@ -113,6 +113,39 @@ void cIptvUdpSocket::CloseSocket(void) cIptvSocket::CloseSocket(); } +bool cIptvUdpSocket::JoinMulticast(const in_addr_t StreamAddr) +{ + debug("cIptvUdpSocket::JoinMulticast()\n"); + // Check if socket exists + if (!isActive && (socketDesc >= 0)) { + // Join a new multicast group + struct ip_mreq mreq; + mreq.imr_multiaddr.s_addr = StreamAddr; + mreq.imr_interface.s_addr = htonl(INADDR_ANY); + ERROR_IF_RET(setsockopt(socketDesc, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0, "setsockopt(IP_ADD_MEMBERSHIP)", return false); + // Update multicasting flag + isActive = true; + } + return true; +} + +bool cIptvUdpSocket::DropMulticast(const in_addr_t StreamAddr) +{ + debug("cIptvUdpSocket::DropMulticast()\n"); + // Check if socket exists + if (isActive && (socketDesc >= 0)) { + // Drop the existing multicast group + struct ip_mreq mreq; + mreq.imr_multiaddr.s_addr = StreamAddr; + mreq.imr_interface.s_addr = htonl(INADDR_ANY); + ERROR_IF_RET(setsockopt(socketDesc, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq)) < 0, "setsockopt(IP_DROP_MEMBERSHIP)", return false); + // Update multicasting flag + isActive = false; + } + return true; +} + + int cIptvUdpSocket::Read(unsigned char* BufferAddr, unsigned int BufferLen) { //debug("cIptvUdpSocket::Read()\n"); diff --git a/socket.h b/socket.h index 0abae60..3331cc5 100644 --- a/socket.h +++ b/socket.h @@ -36,6 +36,8 @@ public: virtual int Read(unsigned char* BufferAddr, unsigned int BufferLen); bool OpenSocket(const int Port, const in_addr_t SourceAddr = INADDR_ANY); void CloseSocket(void); + bool JoinMulticast(const in_addr_t StreamAddr); + bool DropMulticast(const in_addr_t StreamAddr); }; class cIptvTcpSocket : public cIptvSocket {