throbber
/Users/implicit/Desktop/Source Code/2001.11.01/beads/s…/…/posix/udp.c
`Page 1/21
`Saved: 9/2/01, 12:21:54 AM
`Printed for: Implicit
`
`/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`1
`+++++¬
`…
`¬2
`$Id: udp.c,v 1.10 2001/09/02 05:21:54 davidc Exp $¬
`3
`¬4
`Copyright (c) 2001 BeComm Corporation¬
`5
`¬6
`Filename:¬
`7
`¬8
` udp.c¬
`9
`¬10
`Abstract:¬
`11
`¬12
` The implementation of the UDP portion of the SocketLib API. This is
`13
`the¬
`…
` Win32 (NT/95/CE) version using the standard sockets interface exported¬
`14
` by WinSock.¬
`15
`¬16
`Owner:¬
`17
`¬18
` David Costanzo (davidc)¬
`19
`¬20
`--------------------------------------------------------------------------
`21
`---*/¬
`…
`#include <stdlib.h>¬
`22
`#include <stdio.h>¬
`23
`#include <string.h>¬
`24
`#include <pthread.h>¬
`25
`#include <assert.h>¬
`26
`#include <errno.h>¬
`27
`¬28
`#include <sys/time.h>¬
`29
`#include <unistd.h>¬
`30
`¬31
`#include <netdb.h>¬
`32
`#include <sys/socket.h>¬
`33
`#include <sys/types.h>¬
`34
`#include <netinet/in.h>¬
`35
`¬36
`#define SOS_DEBUG_ZONE "/classes/socket/udp"¬
`37
`#include <sosstrings.h>¬
`38
`#include <sosisocket.h>¬
`39
`#include "socket.h"¬
`40
`#include "udp.h"¬
`41
`¬42
`
`Page 1 of 21
`
`Implicit Exhibit 2053
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/beads/s…/…/posix/udp.c
`Page 2/21
`Saved: 9/2/01, 12:21:54 AM
`Printed for: Implicit
`
`SOS_SOURCE_VERSION("$Id: udp.c,v 1.10 2001/09/02 05:21:54 davidc Exp $");¬
`43
`¬44
`/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`45
`+++++¬
`…
`macros¬
`46
`--------------------------------------------------------------------------
`47
`---*/¬
`…
`¬48
`#define ERROR_BIND_FAILED SOS_Error¬
`49
`#define ERROR_SOCKET_FAILED SOS_Error¬
`50
`#define ERROR_BIND_FAILED SOS_Error¬
`51
`#define ERROR_CONNECT_FAILED SOS_Error¬
`52
`#define ERROR_GETSOCKNAME_FAILED SOS_Error¬
`53
`#define ERROR_SETSOCKOPT_FAILED SOS_Error¬
`54
`¬55
`/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`56
`+++++¬
`…
`types¬
`57
`--------------------------------------------------------------------------
`58
`---*/¬
`…
`¬59
`typedef enum _UDP_CONNECTION_FUNCTION_ID {¬
`60
` UDP_CONNECTION_FUNCTION_ID_OnReceive,¬
`61
` UDP_CONNECTION_FUNCTION_ID_OnClose,¬
`62
`} UDP_CONNECTION_FUNCTION_ID;¬
`63
`¬64
`typedef struct _UDP_CONNECTION_PARAM UDP_CONNECTION_PARAM;¬
`65
`¬66
`¬67
`struct _UDP_CONNECTION_PARAM {¬
`68
`¬69
` UDP_CONNECTION_FUNCTION_ID FunctionId;¬
`70
`¬71
` union _UDP_CONNECTION_PARAMS {¬
`72
`¬73
` struct _UDP_CONNECTION_PARAM_ON_RECEIVE {¬
`74
` SOS_ISOCKET_UDP * Socket;¬
`75
` const SOS_ISOCKET_ADDRESS * SocketAddress;¬
`76
` void* Buffer;¬
`77
` size_t BufferLength;¬
`78
` SOS_FREEPROC BufferFree;¬
`79
` } OnReceive;¬
`80
`¬81
` struct _UDP_CONNECTION_PARAM_ON_CLOSE {¬
`82
` SOS_ISOCKET_UDP * Socket;¬
`83
`
`Page 2 of 21
`
`Implicit Exhibit 2053
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/beads/s…/…/posix/udp.c
`Page 3/21
`Saved: 9/2/01, 12:21:54 AM
`Printed for: Implicit
`
` } OnClose;¬
`84
`¬85
` } Params;¬
`86
`};¬
`87
`¬88
`typedef int SOCKET;¬
`89
`¬90
`/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`91
`+++++¬
`…
`Constants¬
`92
`--------------------------------------------------------------------------
`93
`---*/¬
`…
`/* REVISIT: it would be nice if we could check the size¬
`94
` of the message and allocate the right amount for each¬
`95
` message instead of having to keep a big buffer around¬
`96
` and copy to a buffer of the right size each time... */¬
`97
`static const size_t g_UdpRecvSize = 65535;¬
`98
`¬99

`100
`/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`101
`+++++¬
`…
`Data Types¬
`102
`--------------------------------------------------------------------------
`103
`---*/¬
`…

`104
`/* UDP socket context to be passed back and forth with caller of this
`105
`library */¬
`…
`struct _SOS_ISOCKET_UDP {¬
`106
` SOCKET NativeSocket;¬
`107

`108
` pthread_mutex_t Mutex; /* non-recursive */¬
`109
` int RefCount;¬
`110

`111
` SOS_ISOCKET_UDP_RECEIVE RecvCallback;¬
`112
` SOS_ISOCKET_CLOSED ClosedCallback;¬
`113
` struct sockaddr_in RemoteSockAddr;¬
`114
` SOS_ISOCKET_ADDRESS SocketAddr;¬
`115
` void* UserContext;¬
`116
` SOS_BOOLEAN IsCopy;¬
`117

`118
` pthread_t NativeRecvThread;¬
`119
`};¬
`120

`121
`struct _SOS_ISOCKET_UDP_LISTEN {¬
`122
` SOS_ISOCKET_UDP Socket;¬
`123
`
`Page 3 of 21
`
`Implicit Exhibit 2053
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/beads/s…/…/posix/udp.c
`Page 4/21
`Saved: 9/2/01, 12:21:54 AM
`Printed for: Implicit
`
`124
`125
`126
`127
`…
`128
`129
`…
`130
`131
`132
`133
`134
`135
`136
`137
`138
`139
`140
`141
`142
`143
`144
`145
`146
`147
`148
`149
`150
`151
`152
`153
`154
`155
`156
`157
`158
`159
`160
`161
`162
`163
`164
`165
`166
`
`};¬


`/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`+++++¬
`Internal Routines¬
`--------------------------------------------------------------------------
`---*/¬

`/*++¬
`Routine Name:¬

` UdpSocketCreate¬

`Routine Description:¬

` This routine allocates and initializes an SOS_ISOCKET_UDP struct.¬
` It does not call any sockets routines.¬
` The structure is returned with a reference count of 1.¬

`Parameters:¬

` SOCKET NativeSocket - [in]¬
` The native socket handle.¬

` SOS_ISOCKET_UDP_RECEIVE RecvCallback - [in]¬
` The user-defined RecvCallback.¬

` SOS_ISOCKET_CLOSED ClosedCallback - [in]¬
` The user-defined ClosedCallback.¬

` const struct sockaddr_in* RemoteSockAddr - [in]¬
` The remote socket address.¬
` This parameter is optional.¬

` const SOS_ISOCKET_ADDRESS* SocketAddr - [in]¬
` The socket address.¬

` void* UserContext - [in]¬
` The user context to pass into RecvCallback and ClosedCallback.¬

`Return Value:¬

` SOS_ISOCKET_UDP* -¬
` A pointer to a newly allocated SOS_ISOCKET_UDP structure with¬
`
`Page 4 of 21
`
`Implicit Exhibit 2053
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/beads/s…/…/posix/udp.c
`Page 5/21
`Saved: 9/2/01, 12:21:54 AM
`Printed for: Implicit
`
`167
`168
`169
`170
`171
`172
`173
`174
`175
`176
`177
`178
`179
`180
`181
`182
`183
`184
`185
`186
`187
`188
`189
`190
`191
`192
`193
`194
`195
`196
`197
`198
`199
`200
`201
`202
`203
`204
`205
`206
`207
`208
`209
`210
`211
`
` a reference count of 1.¬
` NULL, if the structure could not be created.¬

`--*/¬
`static¬
`SOS_ISOCKET_UDP*¬
`UdpSocketCreate(¬
` SOCKET NativeSocket,¬
` SOS_ISOCKET_UDP_RECEIVE RecvCallback,¬
` SOS_ISOCKET_CLOSED ClosedCallback,¬
` const struct sockaddr_in * RemoteSockAddr,¬
` const SOS_ISOCKET_ADDRESS * SocketAddr,¬
` void* UserContext¬
`)¬
`{¬
` SOS_ISOCKET_UDP* udpSocket;¬

` /* allocate enough size for the larger SOS_ISOCKET_UDP_LISTEN */¬
` udpSocket = malloc(sizeof(SOS_ISOCKET_UDP_LISTEN));¬
` if (udpSocket != NULL) {¬

` int initStatus;¬

` initStatus = pthread_mutex_init(&udpSocket->Mutex, NULL);¬
` if (initStatus == 0) {¬

` udpSocket->NativeSocket = NativeSocket;¬
` udpSocket->ClosedCallback = ClosedCallback;¬
` udpSocket->RecvCallback = RecvCallback;¬
` if (RemoteSockAddr) {¬
` udpSocket->RemoteSockAddr = *RemoteSockAddr;¬
` }¬
` udpSocket->SocketAddr = *SocketAddr;¬
` udpSocket->UserContext = UserContext;¬
` udpSocket->IsCopy = SOS_False;¬

` udpSocket->RefCount = 1;¬
` }¬
` else {¬
` free(udpSocket);¬
` udpSocket = NULL;¬
` }¬
` }¬

` return udpSocket;¬
`
`Page 5 of 21
`
`Implicit Exhibit 2053
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/beads/s…/…/posix/udp.c
`Page 6/21
`Saved: 9/2/01, 12:21:54 AM
`Printed for: Implicit
`
`212
`213
`214
`215
`216
`217
`218
`219
`220
`221
`222
`223
`224
`225
`226
`227
`228
`229
`230
`231
`232
`233
`234
`235
`236
`237
`238
`239
`240
`241
`242
`243
`244
`245
`246
`247
`248
`249
`250
`251
`252
`253
`254
`255
`256
`
`}¬

`/*++¬
`Routine Name:¬

` UdpSocketDestroy¬

`Routine Description:¬

` This is the SOS_FREEPROC for udp sockets. It simply unallocated¬
` the structure. It does not make any socket-specific calls, such¬
` as closing the socket handle.¬

`Parameters:¬

` SOS_ISOCKET_UDP* UdpSocket - [consumed]¬
` The UdpSocket structure to destroy.¬

`Return Value:¬

` None¬

`--*/¬
`static¬
`void¬
`UdpSocketDestroy(¬
` SOS_ISOCKET_UDP* UdpSocket¬
`)¬
`{¬
` if (UdpSocket) {¬
` assert(UdpSocket->RefCount == 0);¬
` pthread_mutex_destroy(&UdpSocket->Mutex);¬
` free(UdpSocket);¬
` }¬
`}¬


`/*++¬
`Routine Name:¬

` UdpSocketReference¬

`Routine Description:¬

` This routine adds a reference to a UDP socket struct.¬
`
`Page 6 of 21
`
`Implicit Exhibit 2053
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/beads/s…/…/posix/udp.c
`Page 7/21
`Saved: 9/2/01, 12:21:54 AM
`Printed for: Implicit
`
`257
`258
`259
`260
`261
`262
`263
`264
`265
`266
`267
`268
`269
`270
`271
`272
`273
`274
`275
`276
`277
`278
`279
`280
`281
`282
`283
`284
`285
`286
`287
`288
`289
`290
`291
`292
`293
`294
`295
`296
`297
`298
`299
`300
`…
`

`Parameters:¬

` SOS_ISOCKET_UDP* UdpSocket - [in]¬
` The UDP socket whose reference count should be incremented.¬

`Return Value:¬

` SOS_ISOCKET_UDP* -¬
` The argument UdpSocket.¬

`--*/¬
`static¬
`SOS_ISOCKET_UDP*¬
`UdpSocketReference(¬
` SOS_ISOCKET_UDP* UdpSocket¬
`)¬
`{¬
` if (UdpSocket) {¬
` assert(0 < UdpSocket->RefCount);¬

` pthread_mutex_lock(&UdpSocket->Mutex);¬
` UdpSocket->RefCount++;¬
` pthread_mutex_unlock(&UdpSocket->Mutex);¬
` }¬

` return UdpSocket;¬
`}¬


`/*++¬
`Routine Name:¬

` UdpSocketRelease¬

`Routine Description:¬

` This routine removes a reference from a UDP socket struct.¬
` If the reference count becomes zero, the structure is destroyed.¬

`Parameters:¬

` SOS_ISOCKET_UDP* UdpSocket - [in]¬
` The UdpSocket structure whose reference count is to be
`decremented.¬
`
`Page 7 of 21
`
`Implicit Exhibit 2053
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/beads/s…/…/posix/udp.c
`Page 8/21
`Saved: 9/2/01, 12:21:54 AM
`Printed for: Implicit
`
`301
`302
`303
`304
`305
`306
`307
`308
`309
`310
`311
`312
`313
`314
`315
`316
`317
`318
`319
`320
`321
`322
`323
`324
`325
`326
`327
`328
`329
`330
`331
`332
`333
`334
`335
`336
`337
`338
`339
`340
`341
`342
`343
`344
`345
`

`Return Value:¬

` None¬

`--*/¬
`static¬
`void¬
`UdpSocketRelease(¬
` SOS_ISOCKET_UDP* UdpSocket¬
`)¬
`{¬
` if (UdpSocket) {¬

` int newValue;¬

` assert(0 < UdpSocket->RefCount);¬

` pthread_mutex_lock(&UdpSocket->Mutex);¬
` newValue = --UdpSocket->RefCount;¬
` pthread_mutex_unlock(&UdpSocket->Mutex);¬

` if (newValue == 0) {¬
` UdpSocketDestroy(UdpSocket);¬
` }¬
` }¬
`}¬





`/*++¬
`Routine Name:¬

` UdpRecvCloseWorkerThread¬

`Thread Context:¬

` Internal¬

`Routine Description:¬

` This is a worker proc that calls into Strings. It calls¬
` both the OnReceive callback and the OnClose callback.¬
`
`Page 8 of 21
`
`Implicit Exhibit 2053
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/beads/s…/…/posix/udp.c
`Page 9/21
`Saved: 9/2/01, 12:21:54 AM
`Printed for: Implicit
`
`346
`347
`348
`349
`350
`351
`352
`353
`354
`355
`356
`357
`358
`359
`360
`361
`362
`363
`364
`365
`366
`367
`368
`369
`370
`371
`372
`373
`374
`375
`376
`377
`378
`379
`380
`381
`382
`383
`384
`385
`386
`387
`388
`389
`390
`

`Parameters:¬

` void* InternalThreadParams - [in]¬
` The marshalled up parameters to call the callback with.¬

`Return Value:¬

` None¬

`--*/¬
`static¬
`void¬
`UdpRecvCloseWorkerThread(¬
` void * InternalThreadParams¬
`)¬
`{¬
` UDP_CONNECTION_PARAM* const params = InternalThreadParams;¬

` switch (params->FunctionId) {¬
` case UDP_CONNECTION_FUNCTION_ID_OnReceive:¬

` params->Params.OnReceive.Socket->RecvCallback(¬
` &g_ISocket,¬
` params->Params.OnReceive.Socket,¬
` params->Params.OnReceive.SocketAddress,¬
` params->Params.OnReceive.Socket->UserContext,¬
` params->Params.OnReceive.Buffer,¬
` params->Params.OnReceive.BufferLength,¬
` params->Params.OnReceive.BufferFree¬
` );¬

` break;¬

` case UDP_CONNECTION_FUNCTION_ID_OnClose:¬

` params->Params.OnClose.Socket->ClosedCallback(¬
` &g_ISocket,¬
` params->Params.OnClose.Socket->UserContext¬
` );¬

` break;¬

` default:¬
` SOS_ASSERT_ASSUMPTION(0, "Can't Happen");¬
`
`Page 9 of 21
`
`Implicit Exhibit 2053
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/posix/udp.c
`Page 10/21
`Saved: 9/2/01, 12:21:54 AM
`Printed for: Implicit
`
`391
`392
`393
`394
`395
`396
`397
`398
`399
`400
`401
`402
`403
`404
`405
`406
`407
`408
`…
`409
`410
`411
`…
`412
`…
`413
`…
`414
`415
`416
`417
`418
`419
`420
`421
`422
`423
`424
`425
`426
`427
`428
`429
`430
`431
`
` }¬

`}¬


`/*++¬
`Routine Name:¬

` UdpRecvThread¬

`Thread Context:¬

` External¬

`Routine Description:¬

` This thread loops receiving UDP datagrams on a socket. Since UDP listen¬
` sockets are are bound only to local port number, messages for a number
`of¬
` different address 4-tuples can come into the same thread here. When a¬
` datagram is received, we call the user's RecvCallback with the data and¬
` an address struct with the address data for that particular message.
`The¬
` recvfrom() call blocks until data is ready of the socket is closed.
`NOTE:¬
` this call the the RecvCallback must be an entire UDP message, which
`could¬
` be as large as 64K. The recvfrom() call will not return more than one¬
` datagram.¬

`Parameters:¬

` void* Context - [in]¬
` This is the UDP socket handle that is receiving data.¬

`Return Value:¬

` unsigned -¬
` 0, always¬

`--*/¬
`static¬
`void *¬
`UdpRecvThread(¬
` void * Context¬
`
`Page 10 of 21
`
`Implicit Exhibit 2053
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/posix/udp.c
`Page 11/21
`Saved: 9/2/01, 12:21:54 AM
`Printed for: Implicit
`
`432
`433
`434
`435
`436
`437
`438
`439
`440
`441
`442
`443
`444
`445
`446
`447
`448
`449
`450
`451
`452
`453
`454
`455
`456
`457
`458
`459
`460
`461
`462
`463
`464
`465
`466
`467
`468
`469
`470
`471
`472
`473
`474
`475
`476
`
`)¬
`{¬
` SOS_ISOCKET_UDP* const socketContext = Context;¬

` SOS_ISOCKET_ADDRESS socketAddr;¬
` SOS_INT32 ret;¬
` size_t remotesize;¬
` struct sockaddr_in saddr_remote;¬
` void* bigBuffer;¬
` void* littleBuffer;¬


` /* REVISIT: We allocate a 64K buffer (since that is the largest¬
` possible UDP packet) and receive an entire UDP message into it.¬
` Then, we see how big the message is, allocate an appropriately¬
` sized buffer and copy the message into it. The big 64K buffer¬
` is then reused for the next message.¬

` It would be nicer if we could figure out a way to determine how¬
` big each UDP message is and allocate the correct size buffer for¬
` it and read directly into it instead of having to do the copy. */¬

` bigBuffer = malloc(g_UdpRecvSize);¬

` socketAddr = socketContext->SocketAddr;¬

` while (1) {¬

` UDP_CONNECTION_PARAM params;¬

` remotesize = sizeof(saddr_remote);¬
` ret = recvfrom(¬
` socketContext->NativeSocket,¬
` bigBuffer,¬
` g_UdpRecvSize,¬
` 0,¬
` (struct sockaddr*)&(saddr_remote),¬
` &remotesize);¬

` /* if the connection was closed or there was an error... */¬
` if (ret <= 0) {¬
` break;¬
` }¬

` littleBuffer = malloc(ret);¬
`
`Page 11 of 21
`
`Implicit Exhibit 2053
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/posix/udp.c
`Page 12/21
`Saved: 9/2/01, 12:21:54 AM
`Printed for: Implicit
`
`477
`478
`479
`480
`481
`482
`483
`484
`485
`486
`487
`488
`489
`490
`491
`492
`493
`494
`495
`496
`497
`498
`499
`500
`501
`502
`503
`504
`…
`505
`506
`507
`508
`509
`510
`511
`512
`513
`514
`515
`516
`517
`518
`519
`520
`
` if (littleBuffer) {¬
` SOS_ISOCKET_UDP* socketContextCopy;¬
` ¬
` memcpy(littleBuffer, bigBuffer, ret);¬

` /* fill in the address that the message was received on */¬
` socketAddr.RemoteAddr = ntohl(saddr_remote.sin_addr.s_addr);¬
` socketAddr.RemotePort = ntohs(saddr_remote.sin_port);¬

` socketContext->RemoteSockAddr = saddr_remote;¬

` /* copy the socket context for the user */¬

` /* CONSIDER for speed: a memcpy would be much faster */¬
` socketContextCopy = UdpSocketCreate(¬
` socketContext->NativeSocket,¬
` socketContext->RecvCallback,¬
` socketContext->ClosedCallback,¬
` &socketContext->RemoteSockAddr,¬
` &socketContext->SocketAddr,¬
` socketContext->UserContext);¬
` if (socketContextCopy != NULL) {¬

` socketContextCopy->IsCopy = SOS_True;¬

` params.FunctionId = UDP_CONNECTION_FUNCTION_ID_OnReceive;¬

` params.Params.OnReceive.Socket =
`socketContextCopy;¬
` params.Params.OnReceive.SocketAddress = &socketAddr;¬
` params.Params.OnReceive.Buffer = littleBuffer;¬
` params.Params.OnReceive.BufferLength = ret;¬
` params.Params.OnReceive.BufferFree = free;¬

` SOS_Internal_Call(UdpRecvCloseWorkerThread, &params);¬
` }¬
` }¬

` }¬

` if (ret < 0) {¬
` /* BUG: (davidc)¬
` There is currently no way for PortalSock to distinguish¬
` between a half-close and a reset socket. If the socket is¬
` reset, PsUdp will think it's just a half-close¬
`
`Page 12 of 21
`
`Implicit Exhibit 2053
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/posix/udp.c
`Page 13/21
`Saved: 9/2/01, 12:21:54 AM
`Printed for: Implicit
`
`521
`522
`523
`524
`525
`526
`527
`528
`529
`530
`531
`532
`533
`534
`535
`536
`537
`538
`539
`540
`541
`542
`543
`544
`…
`545
`546
`…
`547
`548
`549
`550
`551
`552
`553
`554
`555
`556
`557
`558
`559
`560
`561
`562
`563
`
` and still try to send on this socket, which crashes.¬
` */¬
` }¬

` if (socketContext->ClosedCallback) {¬
` /* only call this for non-listen sockets */¬

` UDP_CONNECTION_PARAM params;¬

` params.FunctionId = UDP_CONNECTION_FUNCTION_ID_OnClose;¬
` params.Params.OnClose.Socket = socketContext;¬

` SOS_Internal_Call(UdpRecvCloseWorkerThread, &params);¬
` }¬

` UdpSocketRelease(socketContext);¬
` free(bigBuffer);¬

` return NULL;¬
`}¬



`/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`+++++¬
`SocketLib API -- UDP¬
`--------------------------------------------------------------------------
`---*/¬
`/* create a UDP socket to send on and start a recv thread¬
` to get any incoming data on that socket */¬

`SOS_STATUS¬
`Socket_UdpCreate(¬
` SOS_ISOCKET* Interface,¬
` SOS_ISOCKET_ADDRESS* SocketAddr,¬
` void* UserContext,¬
` SOS_ISOCKET_UDP_RECEIVE RecvCallback,¬
` SOS_ISOCKET_CLOSED ClosedCallback,¬
` SOS_ISOCKET_UDP** Socket¬
`)¬
`{¬
` SOS_STATUS status = SOS_ErrorParameter;¬

` if (Socket != NULL) {¬

`
`Page 13 of 21
`
`Implicit Exhibit 2053
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/posix/udp.c
`Page 14/21
`Saved: 9/2/01, 12:21:54 AM
`Printed for: Implicit
`
`564
`565
`566
`567
`568
`569
`570
`571
`572
`573
`574
`575
`576
`577
`578
`579
`580
`581
`582
`583
`584
`585
`586
`587
`588
`589
`590
`591
`592
`593
`594
`595
`596
`597
`598
`599
`600
`601
`602
`603
`604
`…
`605
`606
`607
`
` SOCKET nativeSocket;¬
` struct sockaddr_in saddr_local;¬
` struct sockaddr_in saddr_remote;¬
` int ret, size;¬
` SOS_ISOCKET_UDP* context;¬
` int optionValue;¬

` *Socket = NULL;¬

` saddr_local.sin_family = PF_INET;¬
` saddr_local.sin_port = htons(SocketAddr->LocalPort);¬
` saddr_local.sin_addr.s_addr = htonl(INADDR_ANY);¬

` memset(&saddr_remote, 0, sizeof(saddr_remote));¬
` saddr_remote.sin_family = PF_INET;¬
` saddr_remote.sin_port = htons(SocketAddr->RemotePort);¬
` saddr_remote.sin_addr.s_addr = htonl(SocketAddr->RemoteAddr);¬

` /* Create a UDP socket. */¬
` nativeSocket = socket(PF_INET, SOCK_DGRAM, 0);¬
` if (nativeSocket < 0) {¬
` return ERROR_SOCKET_FAILED;¬
` }¬

` /* Enable broadcast on this socket */¬
` if (SocketAddr->RemoteAddr == 0xFFFFFFFF) {¬
` optionValue = SOS_True;¬
` ret = setsockopt(¬
` nativeSocket,¬
` SOL_SOCKET,¬
` SO_BROADCAST,¬
` (char *)&optionValue,¬
` sizeof(optionValue));¬
` if (ret < 0) {¬
` close(nativeSocket);¬
` return ERROR_SETSOCKOPT_FAILED;¬
` }¬
` }¬

` /* Bind the socket to the local address */¬
` ret = bind(nativeSocket, (struct sockaddr*)&saddr_local,
`sizeof(saddr_local));¬
` if (ret < 0) {¬
` close(nativeSocket);¬
` return ERROR_BIND_FAILED;¬
`
`Page 14 of 21
`
`Implicit Exhibit 2053
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/posix/udp.c
`Page 15/21
`Saved: 9/2/01, 12:21:54 AM
`Printed for: Implicit
`
`608
`609
`610
`611
`612
`…
`613
`614
`615
`616
`617
`618
`619
`620
`621
`622
`623
`624
`625
`626
`627
`628
`629
`630
`631
`632
`633
`634
`635
`636
`637
`638
`639
`640
`641
`642
`643
`644
`645
`646
`647
`648
`649
`650
`651
`
` }¬

` /* Find out the local IP used */¬
` size = sizeof(saddr_local);¬
` ret = getsockname(nativeSocket, (struct sockaddr*)&saddr_local,
`&size);¬
` if (ret < 0) {¬
` close(nativeSocket);¬
` return ERROR_GETSOCKNAME_FAILED;¬
` }¬
` SocketAddr->LocalAddr = ntohl(saddr_local.sin_addr.s_addr);¬
` SocketAddr->LocalPort = ntohs(saddr_local.sin_port);¬

` /* fill my context */¬
` context = UdpSocketCreate(¬
` nativeSocket,¬
` RecvCallback,¬
` ClosedCallback,¬
` &saddr_remote,¬
` SocketAddr,¬
` UserContext);¬
` if (context != NULL) {¬

` /* Spawn a thread to listen for incoming messages */¬
` UdpSocketReference(context);¬
` ret = pthread_create(¬
` &context->NativeRecvThread,¬
` NULL, /* no security descriptor */¬
` UdpRecvThread,¬
` context);¬
` if (ret == 0) {¬
` status = SOS_Success;¬
` }¬
` else {¬
` /* release the reference that the thread didn't take */¬
` UdpSocketRelease(context);¬
` status = SOS_ErrorResourceAllocation;¬
` }¬

` /* clean up side effects on error */¬
` if (SOS_FAILED(status)) {¬
` UdpSocketRelease(context);¬
` context = NULL;¬
` }¬
` }¬
`
`Page 15 of 21
`
`Implicit Exhibit 2053
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/posix/udp.c
`Page 16/21
`Saved: 9/2/01, 12:21:54 AM
`Printed for: Implicit
`
`652
`653
`654
`655
`656
`657
`658
`659
`660
`661
`662
`663
`664
`665
`666
`667
`668
`669
`670
`671
`672
`673
`674
`675
`676
`677
`678
`679
`680
`681
`682
`683
`684
`685
`686
`687
`688
`689
`690
`691
`692
`693
`694
`695
`696
`

` if (SOS_FAILED(status)) {¬
` close(nativeSocket);¬
` }¬


` /* "return" my context */¬
` *Socket = context;¬
` }¬

` return status;¬
`}¬





`static¬
`void¬
`Socket_UdpListenCancelExternal(¬
` void * Parameter¬
`)¬
`{¬
` SOS_ISOCKET_UDP_LISTEN* const listenHandle = Parameter;¬

` struct linger olinger;¬

` olinger.l_onoff = 0;¬
` olinger.l_linger = 1;¬

` setsockopt(¬
` listenHandle->Socket.NativeSocket,¬
` SOL_SOCKET,¬
` SO_LINGER,¬
` (char*)&olinger,¬
` sizeof(olinger));¬

` /* make sure that UdpRecvThread exits */¬
` shutdown(listenHandle->Socket.NativeSocket, 2);¬
` close(listenHandle->Socket.NativeSocket);¬

` pthread_join(¬
` listenHandle->Socket.NativeRecvThread,¬
` NULL);¬

`
`Page 16 of 21
`
`Implicit Exhibit 2053
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/posix/udp.c
`Page 17/21
`Saved: 9/2/01, 12:21:54 AM
`Printed for: Implicit
`
`697
`698
`699
`700
`701
`702
`703
`704
`705
`706
`707
`708
`709
`710
`711
`712
`713
`714
`715
`716
`717
`718
`719
`720
`721
`722
`723
`724
`725
`726
`727
`728
`729
`730
`731
`732
`733
`734
`735
`736
`737
`738
`739
`740
`741
`

` UdpSocketRelease((SOS_ISOCKET_UDP*) listenHandle);¬
`}¬

`/* cancels a listen socket, causing the recv thread¬
` to exit */¬
`SOS_STATUS¬
`Socket_UdpListenCancel(¬
` SOS_ISOCKET* Interface,¬
` SOS_ISOCKET_UDP_LISTEN* ListenHandle¬
`)¬
`{¬
` SOS_External_Call(Socket_UdpListenCancelExternal, ListenHandle);¬

` return SOS_Success;¬
`}¬



`/* create a socket bound just to the local port and¬
` start a thread to receive those packets. No¬
` callbacks other than the RecvCallback are registered¬
` here because this socket not going to be closed by¬
` the user except through a call to Socket_UdpListenCancel */¬

`SOS_STATUS¬
`Socket_UdpListen(¬
` SOS_ISOCKET* Interface,¬
` const SOS_ISOCKET_ADDRESS * SocketAddr,¬
` SOS_ISOCKET_UDP_RECEIVE RecvCallback,¬
` SOS_ISOCKET_UDP_LISTEN ** ListenHandle¬
`)¬
`{¬
` SOS_STATUS status = SOS_Error;¬

` SOCKET nativeSocket;¬
` struct sockaddr_in saddr_local;¬

` if (ListenHandle) {¬
` SOS_ISOCKET_UDP_LISTEN* context = NULL;¬

` /* set addresses in winsock addr struct */¬
` saddr_local.sin_family = PF_INET;¬
` saddr_local.sin_port = htons(SocketAddr->LocalPort);¬
` saddr_local.sin_addr.s_addr = htonl(INADDR_ANY);¬
`
`Page 17 of 21
`
`Implicit Exhibit 2053
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/posix/udp.c
`Page 18/21
`Saved: 9/2/01, 12:21:54 AM
`Printed for: Implicit
`
`742
`743
`744
`745
`746
`747
`748
`749
`750
`751
`752
`753
`754
`755
`756
`757
`758
`759
`760
`761
`762
`763
`764
`765
`766
`767
`768
`769
`770
`771
`772
`773
`774
`775
`776
`777
`778
`…
`779
`780
`781
`782
`783
`784
`785
`

` /* Create a UDP socket */¬
` nativeSocket = socket(PF_INET, SOCK_DGRAM, 0);¬
` if (0 <= nativeSocket) {¬

` int ret;¬

` /* Bind the socket to the local address */¬
` ret = bind(¬
` nativeSocket,¬
` (struct sockaddr*)&saddr_local,¬
` sizeof(saddr_local));¬
` if (0 <= ret) {¬

` /* fill my context */¬
` context = (SOS_ISOCKET_UDP_LISTEN *) UdpSocketCreate(¬
` nativeSocket,¬
` RecvCallback,¬
` NULL,¬
` NULL,¬
` SocketAddr,¬
` NULL);¬

` if (context != NULL) {¬

` /* Spawn a thread to accept packets */¬
` UdpSocketReference((SOS_ISOCKET_UDP*) context);¬
` ret = pthread_create(¬
` &context->Socket.NativeRecvThread,¬
` NULL,¬
` UdpRecvThread,¬
` context);¬
` if (ret == 0) {¬
` status = SOS_Success;¬
` }¬
` else {¬
` /* release the reference that the thread didn't
`take */¬
` UdpSocketRelease((SOS_ISOCKET_UDP*) context);¬
` status = SOS_ErrorResourceAllocation;¬
` }¬


` if (SOS_FAILED(status)) {¬
` /* release the reference that the caller won't get
`
`Page 18 of 21
`
`Implicit Exhibit 2053
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/posix/udp.c
`Page 19/21
`Saved: 9/2/01, 12:21:54 AM
`Printed for: Implicit
`
`785…
`786
`787
`788
`789
`790
`791
`792
`793
`794
`795
`796
`797
`798
`799
`800
`801
`802
`803
`804
`805
`806
`807
`808
`809
`810
`811
`812
`813
`814
`815
`816
`817
`818
`819
`820
`821
`822
`823
`824
`825
`826
`827
`828
`829
`
`*/¬
` UdpSocketRelease((SOS_ISOCKET_UDP*) context);¬
` context = NULL;¬
` }¬
` }¬

` }¬
` else {¬
` status = ERROR_BIND_FAILED;¬
` }¬


` /* undo side effects on error */¬
` if (SOS_FAILED(status)) {¬
` close(nativeSocket);¬
` }¬
` }¬
` else {¬
` status = ERROR_SOCKET_FAILED;¬
` }¬

` *ListenHandle = context;¬
` }¬

` return status;¬
`}¬



`static¬
`void¬
`WaitForAndCloseRecvThreadProc(¬
` void * Parameter¬
`)¬
`{¬
` SOS_ISOCKET_UDP* const udpSocket = Parameter;¬

` pthread_join(¬
` udpSocket->NativeRecvThread,¬
` NULL);¬
`}¬


`/* closes a socket that was created for sending, and causes¬
` the recv thread to exit */¬
`
`Page 19 of 21
`
`Implicit Exhibit 2053
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/posix/udp.c
`Page 20/21
`Saved: 9/2/01, 12:21:54 AM
`Printed for: Implicit
`
`830
`831
`832
`833
`834
`835
`836
`837
`838
`839
`840
`841
`…
`842
`843
`844
`845
`846
`…
`847
`848
`849
`850
`851
`852
`853
`854
`855
`856
`857
`858
`859
`860
`861
`862
`863
`864
`865
`866
`867
`868
`869
`870
`871
`872
`
`SOS_STATUS¬
`Socket_UdpClose(¬
` SOS_ISOCKET* Interface,¬
` SOS_ISOCKET_UDP* Socket¬
`)¬
`{¬
` if (Socket->UserContext) {¬

` /* this is not a listen socket */¬
` int ret;¬

` /* the socket context will be freed in UdpRecvThread just after
`this call is made */¬
` ret = shutdown(Socket->NativeSocket, 2);¬
` ret = close(Socket->NativeSocket);¬

` if (!Socket->IsCopy) {¬
` /* switch to an external thread to shut down the recv thread
`*/¬
` SOS_External_Call(WaitForAndCloseRecvThreadProc, Socket);¬
` }¬
` }¬

` return SOS_Success;¬
`}¬


`/* releases a reference on an SOS_ISOCKET_UDP. */¬
`SOS_STATUS¬
`Socket_UdpRelease(¬
` SOS_ISOCKET* Interface,¬
` SOS_ISOCKET_UDP* Socket¬
`)¬
`{¬
` UdpSocketRelease(Socket);¬

` return SOS_Success;¬
`}¬

`/* send an entire datagram on the given socket */¬
`SOS_STATUS¬
`Socket_UdpSend(¬
` SOS_ISOCKET* Interface,¬
` SOS_ISOCKET_UDP* Socket,¬
` void* Buffer,¬
`
`Page 20 of 21
`
`Implicit Exhibit 2053
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/posix/udp.c
`Page 21/21
`Saved: 9/2/01, 12:21:54 AM
`Printed for: Implicit
`
` size_t BufferLen,¬
` SOS_FREEPROC BufferFree¬
`)¬
`{¬
` if (BufferLen) {¬

` int remotesize;¬
` int ret;¬

` remotesize = sizeof(Socket->RemoteSockAddr);¬

` ret = sendto(¬
` Socket->NativeSocket,¬
` Buffer,¬
` BufferLen,¬
` MSG_NOSIGNAL,¬
` (struct sockaddr*)(&Socket->RemoteSockAddr),¬
` remotesize);¬

` BufferFree(Buffer);¬
` }¬

` return SOS_Success;¬
`}¬
`
`873
`874
`875
`876
`877
`878
`879
`880
`881
`882
`883
`884
`885
`886
`887
`888
`889
`890
`891
`892
`893
`894
`895
`896
`897
`
`Page 21 of 21
`
`Implicit Exhibit 2053
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

This document is available on Docket Alarm but you must sign up to view it.


Or .

Accessing this document will incur an additional charge of $.

After purchase, you can access this document again without charge.

Accept $ Charge
throbber

Still Working On It

This document is taking longer than usual to download. This can happen if we need to contact the court directly to obtain the document and their servers are running slowly.

Give it another minute or two to complete, and then try the refresh button.

throbber

A few More Minutes ... Still Working

It can take up to 5 minutes for us to download a document if the court servers are running slowly.

Thank you for your continued patience.

This document could not be displayed.

We could not find this document within its docket. Please go back to the docket page and check the link. If that does not work, go back to the docket and refresh it to pull the newest information.

Your account does not support viewing this document.

You need a Paid Account to view this document. Click here to change your account type.

Your account does not support viewing this document.

Set your membership status to view this document.

With a Docket Alarm membership, you'll get a whole lot more, including:

  • Up-to-date information for this case.
  • Email alerts whenever there is an update.
  • Full text search for other cases.
  • Get email alerts whenever a new case matches your search.

Become a Member

One Moment Please

The filing “” is large (MB) and is being downloaded.

Please refresh this page in a few minutes to see if the filing has been downloaded. The filing will also be emailed to you when the download completes.

Your document is on its way!

If you do not receive the document in five minutes, contact support at support@docketalarm.com.

Sealed Document

We are unable to display this document, it may be under a court ordered seal.

If you have proper credentials to access the file, you may proceed directly to the court's system using your government issued username and password.


Access Government Site

We are redirecting you
to a mobile optimized page.





Document Unreadable or Corrupt

Refresh this Document
Go to the Docket

We are unable to display this document.

Refresh this Document
Go to the Docket