diff --git a/modules/juce_osc/juce_osc.h b/modules/juce_osc/juce_osc.h index 6195b449b231..28e5326b0969 100644 --- a/modules/juce_osc/juce_osc.h +++ b/modules/juce_osc/juce_osc.h @@ -61,6 +61,35 @@ #pragma once #define JUCE_OSC_H_INCLUDED +/** Config: JUCE_ALLOW_SPECIAL_CHARS_IN_ADDRESS + Enables the use of characters in adress that are not allowed by the OSC specifications (like spaces), but that are used + by some applications anyway (e.g. /my spaced/address) +*/ +#ifndef JUCE_ALLOW_SPECIAL_CHARS_IN_ADDRESS +#define JUCE_ALLOW_SPECIAL_CHARS_IN_ADDRESS 0 +#endif + +/** Config: JUCE_ENABLE_BROADCAST_BY_DEFAULT + Automatically enables broadcast on bound port in OSCReceiver +*/ +#ifndef JUCE_ENABLE_BROADCAST_BY_DEFAULT +#define JUCE_ENABLE_BROADCAST_BY_DEFAULT 0 +#endif + +/** Config: JUCE_EXCLUSIVE_BINDING_BY_DEFAULT + If enabled, this will make the binding of this port exclusive, so no other process can bind it. +*/ +#ifndef JUCE_EXCLUSIVE_BINDING_BY_DEFAULT +#define JUCE_EXCLUSIVE_BINDING_BY_DEFAULT 0 +#endif + +/** Config: JUCE_IP_AND_PORT_DETECTION + If enabled, this will add remoteIP and remotePort variables to osc packets, corresponding to the sender's ip and port when receiving messages. +*/ +#ifndef JUCE_IP_AND_PORT_DETECTION +#define JUCE_IP_AND_PORT_DETECTION 0 +#endif + #include #include diff --git a/modules/juce_osc/osc/juce_OSCAddress.cpp b/modules/juce_osc/osc/juce_OSCAddress.cpp index c13872cf7ece..8b6540ff89bc 100644 --- a/modules/juce_osc/osc/juce_OSCAddress.cpp +++ b/modules/juce_osc/osc/juce_OSCAddress.cpp @@ -283,10 +283,17 @@ namespace return c >= ' ' && c <= '~'; } - static bool isDisallowedChar (juce_wchar c) noexcept +#if JUCE_ALLOW_SPECIAL_CHARS_IN_ADDRESS + static bool isDisallowedChar (juce_wchar) noexcept { - return CharPointer_ASCII (Traits::getDisallowedChars()).indexOf (c, false) >= 0; + return false; + } +#else + static bool isDisallowedChar(juce_wchar c) noexcept + { + return CharPointer_ASCII(Traits::getDisallowedChars()).indexOf(c, false) >= 0; } +#endif static bool containsOnlyAllowedPrintableASCIIChars (const String& string) noexcept { diff --git a/modules/juce_osc/osc/juce_OSCMessage.cpp b/modules/juce_osc/osc/juce_OSCMessage.cpp index 47f0021cabc4..4a6da3d4d31d 100644 --- a/modules/juce_osc/osc/juce_OSCMessage.cpp +++ b/modules/juce_osc/osc/juce_OSCMessage.cpp @@ -50,6 +50,26 @@ OSCAddressPattern OSCMessage::getAddressPattern() const noexcept return addressPattern; } +#if JUCE_IP_AND_PORT_DETECTION +String OSCMessage::getSenderIPAddress() const noexcept +{ + return senderIPAddress; +} + +void OSCMessage::setSenderIPAddress(const String& ip) noexcept +{ + senderIPAddress = ip; +} + +int OSCMessage::getSenderPortNumber() const noexcept +{ + return senderPortNumber; +} +void OSCMessage::setSenderPortNumber(int port) noexcept +{ + senderPortNumber = port; +} +#endif //============================================================================== int OSCMessage::size() const noexcept { diff --git a/modules/juce_osc/osc/juce_OSCMessage.h b/modules/juce_osc/osc/juce_OSCMessage.h index f49e931c61a4..b07eac5c5a10 100644 --- a/modules/juce_osc/osc/juce_OSCMessage.h +++ b/modules/juce_osc/osc/juce_OSCMessage.h @@ -91,6 +91,16 @@ class JUCE_API OSCMessage /** Returns the address pattern of the OSCMessage. */ OSCAddressPattern getAddressPattern() const noexcept; +#if JUCE_IP_AND_PORT_DETECTION + /** Returns the sender's IP Address. */ + String getSenderIPAddress() const noexcept; + void setSenderIPAddress(const String& ip) noexcept; + + /** Returns the sender's port number. */ + int getSenderPortNumber() const noexcept; + void setSenderPortNumber(int port) noexcept; +#endif + /** Returns the number of OSCArgument objects that belong to this OSCMessage. */ int size() const noexcept; @@ -178,6 +188,11 @@ class JUCE_API OSCMessage //============================================================================== OSCAddressPattern addressPattern; Array arguments; + +#if JUCE_IP_AND_PORT_DETECTION + String senderIPAddress; + int senderPortNumber = 0; +#endif }; diff --git a/modules/juce_osc/osc/juce_OSCReceiver.cpp b/modules/juce_osc/osc/juce_OSCReceiver.cpp index 545a289299cc..d6959dd2170b 100644 --- a/modules/juce_osc/osc/juce_OSCReceiver.cpp +++ b/modules/juce_osc/osc/juce_OSCReceiver.cpp @@ -56,9 +56,18 @@ namespace @param sourceData the block of data to use as the stream's source @param sourceDataSize the number of bytes in the source data block */ + +#if JUCE_IP_AND_PORT_DETECTION + OSCInputStream (const void* sourceData, size_t sourceDataSize, const String& senderIPAddress, const int& senderPortNumber) : + input(sourceData, sourceDataSize, false), + senderIPAddress(senderIPAddress), + senderPortNumber(senderPortNumber) + {} +#else OSCInputStream (const void* sourceData, size_t sourceDataSize) : input (sourceData, sourceDataSize, false) {} +#endif //============================================================================== /** Returns a pointer to the source data block from which this stream is reading. */ @@ -273,6 +282,11 @@ namespace private: MemoryInputStream input; +#if JUCE_IP_AND_PORT_DETECTION + String senderIPAddress; + int senderPortNumber; +#endif + //============================================================================== void readPaddingZeros (size_t bytesRead) { @@ -340,7 +354,16 @@ struct OSCReceiver::Pimpl : private Thread, if (! disconnect()) return false; - socket.setOwned (new DatagramSocket (false)); +#if JUCE_ENABLE_BROADCAST_BY_DEFAULT + DatagramSocket* datagram = new DatagramSocket(true); +#else + DatagramSocket* datagram = new DatagramSocket(false); +#endif + socket.setOwned(datagram); + +#if JUCE_EXCLUSIVE_BINDING_BY_DEFAULT + socket->setEnablePortReuse(false); +#endif if (! socket->bindToPort (portNumber)) return false; @@ -427,10 +450,15 @@ struct OSCReceiver::Pimpl : private Thread, }; //============================================================================== - void handleBuffer (const char* data, size_t dataSize) +#if JUCE_IP_AND_PORT_DETECTION + void handleBuffer(const char* data, size_t dataSize, const String& senderIPAddress, const int& senderPortNumber) { - OSCInputStream inStream (data, dataSize); - + OSCInputStream inStream(data, dataSize, senderIPAddress, senderPortNumber); +#else + void handleBuffer(const char* data, size_t dataSize) + { + OSCInputStream inStream(data, dataSize); +#endif try { auto content = inStream.readElementWithKnownSize (dataSize); @@ -477,10 +505,19 @@ struct OSCReceiver::Pimpl : private Thread, if (ready == 0) continue; + +#if JUCE_IP_AND_PORT_DETECTION + String senderIPAddress = ""; + int senderPortNumber = 0; + auto bytesRead = (size_t) socket->read (oscBuffer.getData(), bufferSize, false, senderIPAddress, senderPortNumber); + if (bytesRead >= 4) + handleBuffer(oscBuffer.getData(), bytesRead, senderIPAddress, senderPortNumber); +#else auto bytesRead = (size_t) socket->read (oscBuffer.getData(), bufferSize, false); if (bytesRead >= 4) handleBuffer (oscBuffer.getData(), bytesRead); +#endif } }