throbber
/Users/implicit/Desktop/Source Code/2001.11.01/beads/s…/…/win32/udp.c
`Page 1/21
`Saved: 9/1/01, 11:49:03 PM
`Printed for: Implicit
`
`/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`1
`+++++¬
`…
`¬2
`$Id: udp.c,v 1.16 2001/09/02 04:49:03 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
`---*/¬
`…
`¬22
`#include <windows.h>¬
`23
`#include <winsock2.h>¬
`24
`#include <process.h>¬
`25
`#include <assert.h>¬
`26
`¬27
`#define SOS_DEBUG_ZONE "/classes/socket/udp"¬
`28
`#include <sosstrings.h>¬
`29
`#include <sosisocket.h>¬
`30
`#include "socket.h"¬
`31
`#include "udp.h"¬
`32
`¬33
`SOS_SOURCE_VERSION("$Id: udp.c,v 1.16 2001/09/02 04:49:03 davidc Exp $");¬
`34
`¬35
`/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`36
`+++++¬
`…
`macros¬
`37
`--------------------------------------------------------------------------
`38
`---*/¬
`…
`¬39
`#define ERROR_BIND_FAILED
`40
`
`SOS_Error¬
`
`Page 1 of 21
`
`Implicit Exhibit 2055
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/beads/s…/…/win32/udp.c
`Page 2/21
`Saved: 9/1/01, 11:49:03 PM
`Printed for: Implicit
`
`#define ERROR_SOCKET_FAILED SOS_Error¬
`41
`#define ERROR_BIND_FAILED SOS_Error¬
`42
`#define ERROR_CONNECT_FAILED SOS_Error¬
`43
`#define ERROR_GETSOCKNAME_FAILED SOS_Error¬
`44
`#define ERROR_SETSOCKOPT_FAILED SOS_Error¬
`45
`¬46
`/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`47
`+++++¬
`…
`types¬
`48
`--------------------------------------------------------------------------
`49
`---*/¬
`…
`¬50
`typedef enum _UDP_CONNECTION_FUNCTION_ID {¬
`51
` UDP_CONNECTION_FUNCTION_ID_OnReceive,¬
`52
` UDP_CONNECTION_FUNCTION_ID_OnClose,¬
`53
`} UDP_CONNECTION_FUNCTION_ID;¬
`54
`¬55
`typedef struct _UDP_CONNECTION_PARAM UDP_CONNECTION_PARAM;¬
`56
`¬57
`¬58
`struct _UDP_CONNECTION_PARAM {¬
`59
`¬60
` UDP_CONNECTION_FUNCTION_ID FunctionId;¬
`61
`¬62
` union _UDP_CONNECTION_PARAMS {¬
`63
`¬64
` struct _UDP_CONNECTION_PARAM_ON_RECEIVE {¬
`65
` SOS_ISOCKET_UDP * Socket;¬
`66
` const SOS_ISOCKET_ADDRESS* SocketAddress;¬
`67
` void* Buffer;¬
`68
` size_t BufferLength;¬
`69
` SOS_FREEPROC BufferFree;¬
`70
` } OnReceive;¬
`71
`¬72
` struct _UDP_CONNECTION_PARAM_ON_CLOSE {¬
`73
` SOS_ISOCKET_UDP * Socket;¬
`74
` } OnClose;¬
`75
`¬76
` } Params;¬
`77
`};¬
`78
`¬79
`¬80
`/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`81
`+++++¬
`…
`Constants¬
`82
`
`Page 2 of 21
`
`Implicit Exhibit 2055
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/beads/s…/…/win32/udp.c
`Page 3/21
`Saved: 9/1/01, 11:49:03 PM
`Printed for: Implicit
`
`--------------------------------------------------------------------------
`83
`---*/¬
`…
`/* REVISIT: it would be nice if we could check the size¬
`84
` of the message and allocate the right amount for each¬
`85
` message instead of having to keep a big buffer around¬
`86
` and copy to a buffer of the right size each time... */¬
`87
`static const size_t g_UdpRecvSize = 65535;¬
`88
`¬89
`¬90
`/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`91
`+++++¬
`…
`Data Types¬
`92
`--------------------------------------------------------------------------
`93
`---*/¬
`…
`¬94
`/* UDP socket context to be passed back and forth with caller of this
`95
`library */¬
`…
`struct _SOS_ISOCKET_UDP {¬
`96
` SOCKET NativeSocket;¬
`97
` int RefCount;¬
`98
` SOS_ISOCKET_UDP_RECEIVE RecvCallback;¬
`99
` SOS_ISOCKET_CLOSED ClosedCallback;¬
`100
` struct sockaddr_in RemoteSockAddr;¬
`101
` SOS_ISOCKET_ADDRESS SocketAddr;¬
`102
` void* UserContext;¬
`103
` SOS_BOOLEAN IsCopy;¬
`104

`105
` unsigned long NativeRecvThread;¬
`106
`};¬
`107

`108
`struct _SOS_ISOCKET_UDP_LISTEN {¬
`109
` SOS_ISOCKET_UDP Socket;¬
`110
`};¬
`111

`112

`113

`114
`/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`115
`+++++¬
`…
`Internal Routines¬
`116
`--------------------------------------------------------------------------
`117
`---*/¬
`…

`118
`/*++¬
`119
`Routine Name:¬
`120

`121
`
`Page 3 of 21
`
`Implicit Exhibit 2055
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/beads/s…/…/win32/udp.c
`Page 4/21
`Saved: 9/1/01, 11:49:03 PM
`Printed for: Implicit
`
`122
`123
`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
`
` 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¬
` 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,¬
`
`Page 4 of 21
`
`Implicit Exhibit 2055
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/beads/s…/…/win32/udp.c
`Page 5/21
`Saved: 9/1/01, 11:49:03 PM
`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
`
` 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) {¬

` 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;¬
` }¬

` return udpSocket;¬
`}¬

`/*++¬
`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¬

`
`Page 5 of 21
`
`Implicit Exhibit 2055
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/beads/s…/…/win32/udp.c
`Page 6/21
`Saved: 9/1/01, 11:49:03 PM
`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
`
`--*/¬
`static¬
`void¬
`UdpSocketDestroy(¬
` SOS_ISOCKET_UDP* UdpSocket¬
`)¬
`{¬
` if (UdpSocket) {¬
` assert(UdpSocket->RefCount == 0);¬
` free(UdpSocket);¬
` }¬
`}¬


`/*++¬
`Routine Name:¬

` UdpSocketReference¬

`Routine Description:¬

` This routine adds a reference to a UDP socket struct.¬

`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);¬
` InterlockedIncrement(&UdpSocket->RefCount);¬
` }¬

`
`Page 6 of 21
`
`Implicit Exhibit 2055
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/beads/s…/…/win32/udp.c
`Page 7/21
`Saved: 9/1/01, 11:49:03 PM
`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
`
` 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.¬

`Return Value:¬

` None¬

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

` int oldValue;¬

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

` oldValue = InterlockedDecrement(&UdpSocket->RefCount);¬
` if (oldValue == 0) {¬
` UdpSocketDestroy(UdpSocket);¬
` }¬
` }¬
`}¬


`
`Page 7 of 21
`
`Implicit Exhibit 2055
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/beads/s…/…/win32/udp.c
`Page 8/21
`Saved: 9/1/01, 11:49:03 PM
`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
`



`/*++¬
`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.¬

`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,¬
`
`Page 8 of 21
`
`Implicit Exhibit 2055
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/beads/s…/…/win32/udp.c
`Page 9/21
`Saved: 9/1/01, 11:49:03 PM
`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
`
` 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");¬
` }¬

`}¬


`/*++¬
`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.¬
`
`Page 9 of 21
`
`Implicit Exhibit 2055
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/win32/udp.c
`Page 10/21
`Saved: 9/1/01, 11:49:03 PM
`Printed for: Implicit
`
`387
`388
`389
`390
`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
`

`Parameters:¬

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

`Return Value:¬

` unsigned -¬
` 0, always¬

`--*/¬
`static¬
`unsigned¬
`__stdcall¬
`UdpRecvThread(¬
` void * Context¬
`)¬
`{¬
` SOS_ISOCKET_UDP* const socketContext = Context;¬

` SOS_ISOCKET_ADDRESS socketAddr;¬
` SOS_INT32 ret;¬
` SOS_INT32 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) {¬

`
`Page 10 of 21
`
`Implicit Exhibit 2055
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/win32/udp.c
`Page 11/21
`Saved: 9/1/01, 11:49:03 PM
`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
`
` 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 || ret == SOCKET_ERROR) {¬
` break;¬
` }¬

` littleBuffer = malloc(ret);¬
` 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 =
`
`Page 11 of 21
`
`Implicit Exhibit 2055
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/win32/udp.c
`Page 12/21
`Saved: 9/1/01, 11:49:03 PM
`Printed for: Implicit
`
`476…
`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
`
`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 == SOCKET_ERROR) {¬
` HRESULT result;¬
` result = WSAGetLastError();¬

` /* BUG: (davidc)¬
` There is currently no way for PortalSock to distinguish¬
` between a half-close and a reset socket. If the socket is¬
` reset (WSA error 10054), PsUdp will think it's just a
`half-close¬
` 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 0;¬
`}¬



`
`Page 12 of 21
`
`Implicit Exhibit 2055
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/win32/udp.c
`Page 13/21
`Saved: 9/1/01, 11:49:03 PM
`Printed for: Implicit
`
`520
`…
`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
`
`/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`+++++¬
`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) {¬

` SOCKET nativeSocket;¬
` struct sockaddr_in saddr_local;¬
` struct sockaddr_in saddr_remote;¬
` int ret, size;¬
` SOS_ISOCKET_UDP* context;¬
` int optionValue;¬

` unsigned threadAddr;¬

` *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 == INVALID_SOCKET) {¬
`
`Page 13 of 21
`
`Implicit Exhibit 2055
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/win32/udp.c
`Page 14/21
`Saved: 9/1/01, 11:49:03 PM
`Printed for: Implicit
`
`563
`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
`
` return ERROR_SOCKET_FAILED;¬
` }¬

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

` /* Bind the socket to the local address */¬
` ret = bind(nativeSocket, (struct sockaddr*)&saddr_local,
`sizeof(saddr_local));¬
` if (ret == SOCKET_ERROR) {¬
` closesocket(nativeSocket);¬
` return ERROR_BIND_FAILED;¬
` }¬

` /* Find out the local IP used */¬
` size = sizeof(saddr_local);¬
` ret = getsockname(nativeSocket, (struct sockaddr*)&saddr_local,
`&size);¬
` if (ret == SOCKET_ERROR) {¬
` closesocket(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);¬
`
`Page 14 of 21
`
`Implicit Exhibit 2055
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/win32/udp.c
`Page 15/21
`Saved: 9/1/01, 11:49:03 PM
`Printed for: Implicit
`
`606
`607
`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
`
` if (context != NULL) {¬

` /* Spawn a thread to listen for incoming messages */¬
` UdpSocketReference(context);¬
` context->NativeRecvThread = _beginthreadex(¬
` NULL, /* no security descriptor */¬
` 0, /* default stack size */¬
` UdpRecvThread,¬
` context,¬
` 0, /* no creation flags */¬
` &threadAddr /* thread ID out param */¬
` );¬
` if (context->NativeRecvThread != -1) {¬
` 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;¬
` }¬
` }¬

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


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

` return status;¬
`}¬





`static¬
`
`Page 15 of 21
`
`Implicit Exhibit 2055
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/win32/udp.c
`Page 16/21
`Saved: 9/1/01, 11:49:03 PM
`Printed for: Implicit
`
`651
`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
`
`void¬
`Socket_UdpListenCancelExternal(¬
` void * Parameter¬
`)¬
`{¬
` SOS_ISOCKET_UDP_LISTEN* const listenHandle = Parameter;¬

` BOOL val = SOS_True;¬

` /* the socket context will be freed in UdpRecvThread just after this
`call is made */¬
` setsockopt(¬
` listenHandle->Socket.NativeSocket,¬
` SOL_SOCKET,¬
` SO_DONTLINGER,¬
` (const char FAR *)&val,¬
` sizeof(BOOL));¬

` closesocket(listenHandle->Socket.NativeSocket);¬


` /* make sure that UdpRecvThread exits */¬
` WaitForSingleObject(¬
` (HANDLE)listenHandle->Socket.NativeRecvThread,¬
` 10000);¬

` CloseHandle((HANDLE)listenHandle->Socket.NativeRecvThread);¬

` 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¬
`
`Page 16 of 21
`
`Implicit Exhibit 2055
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/win32/udp.c
`Page 17/21
`Saved: 9/1/01, 11:49:03 PM
`Printed for: Implicit
`
`695
`696
`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
`
` 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;¬
` DWORD externalWorkerThreadId;¬

` 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);¬

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

` int ret;¬

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

` /* fill my context */¬
` context = (SOS_ISOCKET_UDP_LISTEN *) UdpSocketCreate(¬
` nativeSocket,¬
` RecvCallback,¬
` NULL,¬
`
`Page 17 of 21
`
`Implicit Exhibit 2055
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/win32/udp.c
`Page 18/21
`Saved: 9/1/01, 11:49:03 PM
`Printed for: Implicit
`
`740
`741
`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
`
` NULL,¬
` SocketAddr,¬
` NULL);¬

` if (context != NULL) {¬

` /* Spawn a thread to accept packets */¬
` UdpSocketReference((SOS_ISOCKET_UDP*) context);¬
` context->Socket.NativeRecvThread = _beginthreadex(¬
` NULL, /* no security
`descriptor */¬
` 0, /* default stack size
`*/¬
` UdpRecvThread,¬
` context,¬
` 0, /* no creation flags
`*/¬
` &externalWorkerThreadId /* thread ID out param
`*/¬
` );¬
` if (context->Socket.NativeRecvThread != -1) {¬
` 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
`*/¬
` UdpSocketRelease((SOS_ISOCKET_UDP*) context);¬
` context = NULL;¬
` }¬
` }¬

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


`
`Page 18 of 21
`
`Implicit Exhibit 2055
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/win32/udp.c
`Page 19/21
`Saved: 9/1/01, 11:49:03 PM
`Printed for: Implicit
`
`779
`780
`781
`782
`783
`784
`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
`
` /* undo side effects on error */¬
` if (SOS_FAILED(status)) {¬
` closesocket(nativeSocket);¬
` }¬
` }¬
` else {¬
` status = ERROR_SOCKET_FAILED;¬
` }¬

` *ListenHandle = context;¬
` }¬

` return status;¬
`}¬



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

` WaitForSingleObject(¬
` (HANDLE)socket->NativeRecvThread,¬
` 10000);¬
` CloseHandle((HANDLE)socket->NativeRecvThread);¬
`}¬


`/* closes a socket that was created for sending, and causes¬
` the recv thread to exit */¬
`SOS_STATUS¬
`Socket_UdpClose(¬
` SOS_ISOCKET* Interface,¬
` SOS_ISOCKET_UDP* Socket¬
`)¬
`{¬
` if (Socket->UserContext) {¬

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

`
`Page 19 of 21
`
`Implicit Exhibit 2055
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/win32/udp.c
`Page 20/21
`Saved: 9/1/01, 11:49:03 PM
`Printed for: Implicit
`
`824
`…
`825
`826
`827
`828
`…
`829
`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
`
` /* the socket context will be freed in UdpRecvThread just after
`this call is made */¬
` ret = closesocket(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,¬
` size_t BufferLen,¬
` SOS_FREEPROC BufferFree¬
`)¬
`{¬
` if (BufferLen) {¬

` int remotesize;¬
` int ret;¬

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

`
`Page 20 of 21
`
`Implicit Exhibit 2055
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/win32/udp.c
`Page 21/21
`Saved: 9/1/01, 11:49:03 PM
`Printed for: Implicit
`
` ret = sendto(¬
` Socket->NativeSocket,¬
` Buffer,¬
` BufferLen,¬
` 0,¬
` (struct sockaddr*)(&Socket->RemoteSockAddr),¬
` remotesize);¬

` if (ret == -1) {¬
` HRESULT result;¬
` result = WSAGetLastError();¬
` /* SOS_ASSERT_ASSUMPTION(0,"sendto() failed"); */¬
` }¬

` BufferFree(Buffer);¬
` }¬

` return SOS_Success;¬
`}¬

`
`867
`868
`869
`870
`871
`872
`873
`874
`875
`876
`877
`878
`879
`880
`881
`882
`883
`884
`885
`886
`887
`
`Page 21 of 21
`
`Implicit Exhibit 2055
`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