5std::unique_ptr<Timer> OSCInterface::mTimer;
6int OSCInterface::sInstances = 0;
7WDL_PtrList<OSCDevice> gDevices;
12void XSleep(
int ms) { usleep(ms?ms*1000:100); }
17 mHasOutput = dest !=
nullptr;
18 mHasInput = listen_addr !=
nullptr;
20 memset(&mSendAddress, 0,
sizeof(mSendAddress));
21 mMaxMacketSize = maxpacket > 0 ? maxpacket : 1024;
22 mSendSleep = sendsleep >= 0 ? sendsleep : 10;
23 mSendSocket = socket(AF_INET, SOCK_DGRAM, 0);
25 if (mSendSocket == INVALID_SOCKET)
31 mReceiveAddress = *listen_addr;
33 setsockopt(mSendSocket, SOL_SOCKET, SO_BROADCAST, (
char*)&on,
sizeof(on));
34 if (!bind(mSendSocket, (
struct sockaddr*) & mReceiveAddress,
sizeof(
struct sockaddr)))
36 SET_SOCK_BLOCK(mSendSocket,
false);
40 closesocket(mSendSocket);
41 mSendSocket = INVALID_SOCKET;
46 mDestination.Set(dest);
50 char* p = strstr(tmp.Get(),
":");
56 if (!sendport) sendport = 8000;
58 mSendAddress.sin_family = AF_INET;
59 mSendAddress.sin_addr.s_addr = inet_addr(tmp.Get());
60 mSendAddress.sin_port = htons(sendport);
63 setsockopt(mSendSocket, SOL_SOCKET, SO_BROADCAST, (
char*)&on,
sizeof(on));
64 SET_SOCK_BLOCK(mSendSocket,
false);
68OSCDevice::~OSCDevice()
70 if (mSendSocket != INVALID_SOCKET)
72 shutdown(mSendSocket, SHUT_RDWR);
73 closesocket(mSendSocket);
74 mSendSocket = INVALID_SOCKET;
80 if (mSendSocket == INVALID_SOCKET)
83 struct sockaddr* p = mDestination.GetLength() ? nullptr : (
struct sockaddr*) & mSendAddress;
89 socklen_t plen = (socklen_t)
sizeof(mSendAddress);
90 const int len = (int)recvfrom(mSendSocket, buf,
sizeof(buf), 0, p, p ? &plen :
nullptr);
95 OnMessage(1, (
const unsigned char*)buf, len);
101 static char hdr[16] = {
'#',
'b',
'u',
'n',
'd',
'l',
'e', 0, 0, 0, 0, 0, 1, 0, 0, 0 };
104 if (mSendQueue.Available() <= 16)
106 if (mSendQueue.Available() > 0) mSendQueue.Clear();
111 char* packetstart = (
char*)mSendQueue.Get();
113 bool hasbundle =
false;
114 mSendQueue.Advance(16);
116 SET_SOCK_BLOCK(mSendSocket,
true);
118 while (mSendQueue.Available() >=
sizeof(
int))
120 int len = *(
int*)mSendQueue.Get();
121 OSC_MAKEINTMEM4BE((
char*)&len);
123 if (len < 1 || len > MAX_OSC_MSG_LEN || len > mSendQueue.Available())
break;
125 if (packetlen > 16 && packetlen +
sizeof(
int) + len > mMaxMacketSize)
135 memcpy(packetstart, hdr, 16);
138 sendto(mSendSocket, packetstart, packetlen, 0, (
struct sockaddr*) & mSendAddress,
sizeof(mSendAddress));
142 packetstart = (
char*)mSendQueue.Get() - 16;
147 if (packetlen > 16) hasbundle =
true;
148 mSendQueue.Advance(
sizeof(
int) + len);
149 packetlen +=
sizeof(int) + len;
161 memcpy(packetstart, hdr, 16);
163 sendto(mSendSocket, packetstart, packetlen, 0, (
struct sockaddr*) & mSendAddress,
sizeof(mSendAddress));
167 SET_SOCK_BLOCK(mSendSocket,
false);
174 const rec r = { callback, d1, dev_idx };
180 const int n = mInstances.GetSize();
181 const rec* r = mInstances.Get();
182 for (
int x = 0; x < n; x++)
183 if (r[x].callback) r[x].callback(r[x].data1, r[x].dev_idx, len, (
void*)msg);
188 if (!mSendQueue.GetSize())
189 mSendQueue.Add(
nullptr, 16);
192 OSC_MAKEINTMEM4BE(&tlen);
193 mSendQueue.Add(&tlen,
sizeof(tlen));
194 mSendQueue.Add(src, len);
198void OSCInterface::MessageCallback(
void* d1,
int dev_idx,
int len,
void* msg)
204 if (_this->mIncomingEvents.GetSize() < 65536 * 8)
206 const int this_sz = ((
sizeof(incomingEvent) + (len - 3)) + 7) & ~7;
208 _this->mIncomingEvents_mutex.Enter();
209 const int oldsz = _this->mIncomingEvents.GetSize();
210 _this->mIncomingEvents.Resize(oldsz + this_sz,
false);
212 if (_this->mIncomingEvents.GetSize() == oldsz + this_sz)
214 incomingEvent* item = (incomingEvent*)((
char*)_this->mIncomingEvents.Get() + oldsz);
215 item->dev_ptr = _this->mDevices.Get(dev_idx);
217 memcpy(item->msg, msg, len);
219 _this->mIncomingEvents_mutex.Leave();
224void OSCInterface::OnTimer(
Timer& timer)
226 const int nDevices = gDevices.GetSize();
228 for (
auto i = 0; i < nDevices; i++)
230 auto* pDev = gDevices.Get(i);
235 if (mIncomingEvents.GetSize())
237 static WDL_HeapBuf tmp;
239 mIncomingEvents_mutex.Enter();
240 tmp.CopyFrom(&mIncomingEvents,
false);
241 mIncomingEvents.Resize(0,
false);
242 mIncomingEvents_mutex.Leave();
245 const int endpos = tmp.GetSize();
246 while (pos < endpos + 1 -
sizeof(incomingEvent))
248 incomingEvent* evt = (incomingEvent*)((
char*)tmp.Get() + pos);
250 const int this_sz = ((
sizeof(incomingEvent) + (evt->sz - 3)) + 7) & ~7;
252 if (pos + this_sz > endpos)
break;
257 if (evt->sz > 20 && !strcmp((
char*)evt->msg,
"#bundle"))
259 rd_sz = *(
int*)(evt->msg + 16);
260 OSC_MAKEINTMEM4BE(&rd_sz);
265 while (rd_pos + rd_sz <= evt->sz && rd_sz >= 0)
269 const char* mstr = rmsg.GetMessage();
274 if (rd_pos >= evt->sz)
break;
276 rd_sz = *(
int*)(evt->msg + rd_pos - 4);
277 OSC_MAKEINTMEM4BE(&rd_sz);
282 for (
auto i = 0; i < nDevices; i++)
284 auto* pDev = gDevices.Get(i);
285 if (pDev->mHasOutput)
293 JNL::open_socketlib();
296 mTimer = std::unique_ptr<Timer>(Timer::Create(std::bind(&OSCInterface::OnTimer,
this, std::placeholders::_1), OSC_TIMER_RATE));
301OSCInterface::~OSCInterface()
303 if (--sInstances == 0) {
305 gDevices.Empty(
true);
311 const char buf[] =
"127.0.0.1";
313 struct sockaddr_in addr;
314 addr.sin_addr.s_addr = INADDR_ANY;
315 addr.sin_family = AF_INET;
316 if (buf[0] && buf[0] !=
'*') addr.sin_addr.s_addr = inet_addr(buf);
317 if (addr.sin_addr.s_addr == INADDR_NONE) addr.sin_addr.s_addr = INADDR_ANY;
318 addr.sin_port = htons(port);
321 bool isReuse =
false;
323 for (x = 0; x < gDevices.GetSize(); x++)
326 if (dev && dev->mHasInput)
328 if (dev->mReceiveAddress.sin_port == addr.sin_port && dev->mReceiveAddress.sin_addr.s_addr == addr.sin_addr.s_addr)
333 log.AppendFormatted(1024,
"Attached to already-opened listener '%s:%i'\r\n", buf, port);
342 std::unique_ptr<OSCDevice> device(
new OSCDevice(
nullptr, 0, -1, &addr));
344 if (device->mSendSocket == INVALID_SOCKET)
346 log.AppendFormatted(1024,
"Error listening for '%s:%i'\r\n", buf, port);
350 r = device.release();
351 log.AppendFormatted(1024,
"Listening for OSC on '%s:%i'\r\n", buf, port);
357 r->
AddInstance(MessageCallback,
this, mDevices.GetSize());
370 destStr.SetFormatted(256,
"%s:%i", ip, port);
372 bool isReuse =
false;
373 for (
auto x = 0; x < gDevices.GetSize(); x++)
376 if (d && d->mHasOutput)
378 if (!strcmp(d->mDestination.Get(), destStr.Get()))
390 std::unique_ptr<OSCDevice> device(
new OSCDevice(destStr.Get(), 0, -1,
nullptr));
391 if (device->mSendSocket == INVALID_SOCKET)
393 log.AppendFormatted(1024,
"Warning: failed creating destination for output '%s'\n", destStr.Get());
397 r = device.release();
403 log.AppendFormatted(1024,
"Set destination: '%s'\n", destStr.Get());
405 r->
AddInstance(MessageCallback,
this, mDevices.GetSize());
424 if (strcmp(ip, mDestIP.Get()) || port != mPort)
429 if (mDevice !=
nullptr)
431 gDevices.DeletePtr(mDevice,
true);
445 const char* msgStr = msg.GetBuffer(&len);
459 if (mDevice !=
nullptr)
461 gDevices.DeletePtr(mDevice,
true);
void OnMessage(char type, const unsigned char *msg, int len)
void SendOSC(const char *src, int len)
OSCDevice(const char *dest, int maxpacket, int sendsleep, struct sockaddr_in *listen_addr)
Construct a new OSCDevice object.
void AddInstance(void(*callback)(void *d1, int dev_idx, int msglen, void *msg), void *d1, int dev_idx)
OSCDevice * CreateReceiver(WDL_String &log, int port=8000)
Create a Receiver object.
OSCDevice * CreateSender(WDL_String &log, const char *ip="127.0.0.1", int port=8000)
Create a Sender object.
virtual void OnOSCMessage(OscMessageRead &msg)
OSCInterface(OSCLogFunc logFunc=nullptr)
Construct a new OSCInterface object.
OSCReceiver(int port=8000, OSCLogFunc logFunc=nullptr)
Construct a new OSCReceiver object.
void SetReceivePort(int port)
Set the Receive Port object.
void SetDestination(const char *ip, int port)
Set the Destination object.
OSCSender(const char *destIP="127.0.0.1", int port=8000, OSCLogFunc logFunc=nullptr)
Construct a new OSCSender object.
void SendOSCMessage(OscMessageWrite &msg)