throbber
/Users/implicit/Desktop/Source Code/2001.11.01/beads/s…/…/win32/tcp.c
`Page 1/25
`Saved: 8/9/01, 8:59:00 PM
`Printed for: Implicit
`
`/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`1
`++++++¬
`…
`¬2
`$Id: tcp.c,v 1.17 2001/08/10 01:59:00 davidc Exp $¬
`3
`¬4
`Copyright (c) 2001 BeComm Corporation¬
`5
`¬6
`Filename:¬
`7
`¬8
` tcp.c¬
`9
`¬10
`Abstract:¬
`11
`¬12
` The implementation of the TCP portion of the SocketLib API. This is
`13
`the¬
`…
` Win32 (NT/95/CE) version using the standard sockets interface
`14
`exported¬
`…
` 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/tcp"¬
`28
`#include <sosstrings.h>¬
`29
`#include <sosisocket.h>¬
`30
`#include "socket.h"¬
`31
`#include "tcp.h"¬
`32
`¬33
`SOS_SOURCE_VERSION("$Id: tcp.c,v 1.17 2001/08/10 01:59:00 davidc Exp $");¬
`34
`¬35
`/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`36
`++++++¬
`…
`Constants¬
`37
`-------------------------------------------------------------------------
`38
`----*/¬
`…
`¬39
`
`Page 1 of 25
`
`Implicit Exhibit 2054
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/beads/s…/…/win32/tcp.c
`Page 2/25
`Saved: 8/9/01, 8:59:00 PM
`Printed for: Implicit
`
`#define ERROR_BIND_FAILED SOS_Error¬
`40
`#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
`¬45
`¬46
`/* size of buffer to allocate for each read */¬
`47
`static const size_t g_TcpRecvSize = 1500;¬
`48
`¬49
`/* largest amount to call send() with */¬
`50
`static const size_t g_MaxSendSize = 2048;¬
`51
`¬52
`¬53
`/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`54
`++++++¬
`…
`Data Types¬
`55
`-------------------------------------------------------------------------
`56
`----*/¬
`…
`¬57
`/* TCP socket context to be passed back and¬
`58
` forth with caller of this library */¬
`59
`struct _SOS_ISOCKET_TCP {¬
`60
` SOCKET NativeSocket;¬
`61
` int RefCount;¬
`62
` SOS_ISOCKET_TCP_CONNECT ConnectedCallback;¬
`63
` SOS_ISOCKET_TCP_RECEIVE RecvCallback;¬
`64
` SOS_ISOCKET_CLOSED ClosedCallback;¬
`65
` SOS_ISOCKET_ADDRESS SocketAddr;¬
`66
` void* UserContext;¬
`67
`¬68
` SOS_BOOLEAN PeerHasClosed;¬
`69
` SOS_BOOLEAN WeHaveClosed;¬
`70
`¬71
` unsigned long NativeConnectionThread;¬
`72
`};¬
`73
`¬74
`¬75
`struct _SOS_ISOCKET_TCP_LISTEN {¬
`76
` SOS_ISOCKET_TCP Socket;¬
`77
` unsigned long NativeListenThread;¬
`78
`};¬
`79
`¬80
`¬81
`/* TcpConnectionWorkerProc types */¬
`82
`
`Page 2 of 25
`
`Implicit Exhibit 2054
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/beads/s…/…/win32/tcp.c
`Page 3/25
`Saved: 8/9/01, 8:59:00 PM
`Printed for: Implicit
`
`¬83
`typedef struct _CONNECTION_PARAM CONNECTION_PARAM;¬
`84
`¬85
`typedef enum _TCP_CONNECT_FUNCTION_ID {¬
`86
` TCP_CONNECT_FUNCTION_ID_TcpOnConnect,¬
`87
` TCP_CONNECT_FUNCTION_ID_TcpOnReceive,¬
`88
` TCP_CONNECT_FUNCTION_ID_TcpOnClose,¬
`89
`} TCP_CONNECT_FUNCTION_ID;¬
`90
`¬91
`struct _CONNECTION_PARAM {¬
`92
`¬93
` TCP_CONNECT_FUNCTION_ID FunctionId;¬
`94
`¬95
` union _CONNECTION_PARAMS {¬
`96
`¬97
` struct _CONNECTION_PARAM_ON_CONNECT {¬
`98
` SOS_ISOCKET_TCP * Socket;¬
`99
` void * OutUserContext;¬
`100
` } OnConnect;¬
`101

`102

`103
` struct _CONNECTION_PARAM_ON_RECEIVE {¬
`104
` SOS_ISOCKET_TCP * Socket;¬
`105
` void* Buffer;¬
`106
` size_t BufferLength;¬
`107
` SOS_FREEPROC BufferFree;¬
`108
` } OnReceive;¬
`109

`110

`111
` struct _CONNECTION_PARAM_ON_CLOSE {¬
`112
` SOS_ISOCKET_TCP * Socket;¬
`113
` } OnClose;¬
`114

`115
` } Params;¬
`116
`};¬
`117

`118

`119
`/* TcpSendWorkerProc types */¬
`120

`121
`typedef struct _TCP_SEND_WORKER_PROC TCP_SEND_WORKER_PROC;¬
`122

`123
`struct _TCP_SEND_WORKER_PROC {¬
`124
` SOCKET NativeSocket;¬
`125
` void * Buffer;¬
`126
` size_t BufferLength;¬
`127
`
`Page 3 of 25
`
`Implicit Exhibit 2054
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/beads/s…/…/win32/tcp.c
`Page 4/25
`Saved: 8/9/01, 8:59:00 PM
`Printed for: Implicit
`
`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
`167
`168
`169
`170
`
` SOS_STATUS OutStatus;¬
`};¬


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


`/*++¬
`Routine Name:¬

` TcpSocketCreate¬

`Routine Description:¬

` This routine allocates and initializes an SOS_ISOCKET_TCP 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_TCP_CONNECT ConnectedCallback - [in]¬
` The user-defined function to call when a socket connection¬
` has been established.¬

` SOS_ISOCKET_TCP_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]¬
`
`Page 4 of 25
`
`Implicit Exhibit 2054
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/beads/s…/…/win32/tcp.c
`Page 5/25
`Saved: 8/9/01, 8:59:00 PM
`Printed for: Implicit
`
`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
`212
`213
`214
`215
`
` The user context to pass into RecvCallback and ClosedCallback.¬

`Return Value:¬

` SOS_ISOCKET_TCP* -¬
` A pointer to a newly allocated SOS_ISOCKET_TCP structure with¬
` a reference count of 1.¬
` NULL, if the structure could not be created.¬

`--*/¬
`static¬
`SOS_ISOCKET_TCP*¬
`TcpSocketCreate(¬
` SOCKET NativeSocket,¬
` SOS_ISOCKET_TCP_CONNECT ConnectedCallback,¬
` SOS_ISOCKET_TCP_RECEIVE RecvCallback,¬
` SOS_ISOCKET_CLOSED ClosedCallback,¬
` const SOS_ISOCKET_ADDRESS * SocketAddr,¬
` void* UserContext¬
`)¬
`{¬
` SOS_ISOCKET_TCP* tcpSocket;¬

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

` tcpSocket->NativeSocket = NativeSocket;¬
` tcpSocket->ConnectedCallback = ConnectedCallback;¬
` tcpSocket->ClosedCallback = ClosedCallback;¬
` tcpSocket->RecvCallback = RecvCallback;¬
` tcpSocket->SocketAddr = *SocketAddr;¬
` tcpSocket->UserContext = UserContext;¬


` tcpSocket->PeerHasClosed = SOS_False;¬
` tcpSocket->WeHaveClosed = SOS_False;¬

` tcpSocket->RefCount = 1;¬
` }¬

` return tcpSocket;¬
`}¬

`/*++¬
`
`Page 5 of 25
`
`Implicit Exhibit 2054
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/beads/s…/…/win32/tcp.c
`Page 6/25
`Saved: 8/9/01, 8:59:00 PM
`Printed for: Implicit
`
`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
`257
`258
`259
`260
`
`Routine Name:¬

` TcpSocketDestroy¬

`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_TCP* TcpSocket - [consumed]¬
` The TcpSocket structure to destroy.¬

`Return Value:¬

` None¬

`--*/¬
`static¬
`void¬
`TcpSocketDestroy(¬
` SOS_ISOCKET_TCP* TcpSocket¬
`)¬
`{¬
` if (TcpSocket) {¬
` assert(TcpSocket->RefCount == 0);¬
` assert(TcpSocket->PeerHasClosed);¬
` assert(TcpSocket->WeHaveClosed);¬
` free(TcpSocket);¬
` }¬
`}¬


`/*++¬
`Routine Name:¬

` TcpSocketReference¬

`Routine Description:¬

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

`Parameters:¬
`
`Page 6 of 25
`
`Implicit Exhibit 2054
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/beads/s…/…/win32/tcp.c
`Page 7/25
`Saved: 8/9/01, 8:59:00 PM
`Printed for: Implicit
`
`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
`301
`302
`303
`304
`

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

`Return Value:¬

` SOS_ISOCKET_TCP* -¬
` The argument TcpSocket.¬

`--*/¬
`static¬
`SOS_ISOCKET_TCP*¬
`TcpSocketReference(¬
` SOS_ISOCKET_TCP* TcpSocket¬
`)¬
`{¬
` if (TcpSocket) {¬
` assert(0 < TcpSocket->RefCount);¬
` InterlockedIncrement(&TcpSocket->RefCount);¬
` }¬

` return TcpSocket;¬
`}¬

`/*++¬
`Routine Name:¬

` TcpSocketRelease¬

`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_TCP* TcpSocket - [in]¬
` The TcpSocket structure whose reference count is to be
`decremented.¬

`Return Value:¬

` None¬

`--*/¬
`
`Page 7 of 25
`
`Implicit Exhibit 2054
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/beads/s…/…/win32/tcp.c
`Page 8/25
`Saved: 8/9/01, 8:59:00 PM
`Printed for: Implicit
`
`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
`346
`347
`348
`349
`
`static¬
`void¬
`TcpSocketRelease(¬
` SOS_ISOCKET_TCP* TcpSocket¬
`)¬
`{¬
` if (TcpSocket) {¬

` int oldValue;¬

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

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



`/*¬
` must be called from an internal thread context.¬
`*/¬
`static¬
`void¬
`TcpConnectionWorkerProc(¬
` void * InternalThreadParams¬
`)¬
`{¬
` CONNECTION_PARAM* const params = InternalThreadParams;¬

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

` params->Params.OnConnect.OutUserContext =¬
` params->Params.OnConnect.Socket->ConnectedCallback(¬
` &g_ISocket,¬
` params->Params.OnReceive.Socket,¬
` &params->Params.OnReceive.Socket->SocketAddr¬
` );¬

` break;¬

` case TCP_CONNECT_FUNCTION_ID_TcpOnReceive:¬
`
`Page 8 of 25
`
`Implicit Exhibit 2054
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/beads/s…/…/win32/tcp.c
`Page 9/25
`Saved: 8/9/01, 8:59:00 PM
`Printed for: Implicit
`
`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
`391
`392
`393
`

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

` break;¬

` case TCP_CONNECT_FUNCTION_ID_TcpOnClose:¬

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

` break;¬

` default:¬
` SOS_ASSERT_ASSUMPTION(0, "Can't Happen");¬
` }¬

`}¬


`/*++¬
`Routine Name:¬

` TcpRecvThread¬

`Routine Description:¬

` This thread loops and reads data g_TcpRecvSize bytes at a time from a¬
` socket. The call to recv() blocks until there is data to fill into
`the¬
` buffer or the socket is closed. When the socket is closed, it calls¬
` the ClosedCallback that was registered for the socket, and when data¬
` is filled into the buffer, it calls the RecvCallback.¬

` This is an external thread.¬
`Parameters:¬

` void* Parameter - [in]¬
`
`Page 9 of 25
`
`Implicit Exhibit 2054
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/win32/tcp.c
`Page 10/25
`Saved: 8/9/01, 8:59:00 PM
`Printed for: Implicit
`
`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
`432
`433
`434
`435
`436
`437
`
` This is the SOS_ISOCKET_TCP that represents the connection.¬
` A reference is released when this routine exists, so it must¬
` have been referenced before the thread was created.¬

`Return Value:¬

` None¬

`--*/¬
`static¬
`void¬
`TcpRecvThread(¬
` void * Parameter¬
`)¬
`{¬
` SOS_ISOCKET_TCP* const socket = Parameter;¬

` CONNECTION_PARAM params;¬

` while (1) {¬

` char * buffer;¬
` int bytesReceived;¬

` buffer = malloc(g_TcpRecvSize);¬

` bytesReceived = recv(¬
` socket->NativeSocket,¬
` buffer,¬
` g_TcpRecvSize,¬
` 0);¬

` /* REVISIT: There is a condition that will cause this call¬
` to recv() to never return and the thread will never get
`killed,¬
` and the CloseCallback will never get called, which may have¬
` implications in the protocol calling this library. See the¬
` revisit comment in Socket_TcpClose() below for more info. */¬

` /* if the connection was closed or there was an error... */¬
` if (bytesReceived == 0 || bytesReceived == SOCKET_ERROR) {¬
` free(buffer);¬
` break;¬
` }¬

`
`Page 10 of 25
`
`Implicit Exhibit 2054
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/win32/tcp.c
`Page 11/25
`Saved: 8/9/01, 8:59:00 PM
`Printed for: Implicit
`
`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
`477
`478
`479
`480
`481
`482
`
` params.FunctionId = TCP_CONNECT_FUNCTION_ID_TcpOnReceive;¬
` params.Params.OnReceive.Socket = socket;¬
` params.Params.OnReceive.Buffer = buffer;¬
` params.Params.OnReceive.BufferLength = bytesReceived;¬
` params.Params.OnReceive.BufferFree = free;¬

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

` /* notify the caller that the connection is closed */¬
` params.FunctionId = TCP_CONNECT_FUNCTION_ID_TcpOnClose;¬
` params.Params.OnClose.Socket = socket;¬

` SOS_Internal_Call(TcpConnectionWorkerProc, &params);¬

` /* REVISIT: Race Condition */¬
` if (socket->WeHaveClosed) {¬
` closesocket(socket->NativeSocket);¬
` }¬
` socket->PeerHasClosed = SOS_True;¬

` TcpSocketRelease(socket);¬

`}¬



`/*++¬
`Routine Name:¬

` TcpListenThread¬

`Routine Description:¬

` This thread sets up a socket for a passive listen, and loops,¬
` blocking, waiting to accept a new incoming connection. When¬
` a new connection is accepted, it creates a new context for¬
` the new socket that is created, and then spawns a new receive¬
` thread for it. The call to accept() blocks until a new¬
` connection is accepted or the listen socket is shutdown.¬

` This must be called from an external thread context.¬

`Parameters:¬

`
`Page 11 of 25
`
`Implicit Exhibit 2054
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/win32/tcp.c
`Page 12/25
`Saved: 8/9/01, 8:59:00 PM
`Printed for: Implicit
`
`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
`521
`522
`523
`524
`525
`526
`527
`
` void* Parameter - [in]¬
` This in an SOS_ISOCKET_TCP_LISTEN that is listening.¬
` This routine releases a reference to this structure, so¬
` it must be referenced beforehand.¬

`Return Value:¬

` unsigned -¬
` 0, always¬

`--*/¬
`static¬
`unsigned¬
`__stdcall¬
`TcpListenThread(¬
` void * Parameter¬
`)¬
`{¬
` SOS_ISOCKET_TCP_LISTEN* const listenHandle = Parameter;¬

` struct sockaddr_in saddr_local;¬
` struct sockaddr_in saddr_remote;¬
` int size, ret;¬

` ret = listen(listenHandle->Socket.NativeSocket, 5);¬
` /* SOS_ASSERT_ASSUMPTION(ret != SOCKET_ERROR, "listen failed\n"); */¬

` while (1) {¬
` SOS_ISOCKET_TCP* newContext;¬

` CONNECTION_PARAM onConnectParam;¬

` /* create new socket context for newly accepted socket */¬
` /* CONSIDER for SPEED: a memcpy would be faster */¬
` newContext = TcpSocketCreate(¬
` listenHandle->Socket.NativeSocket,¬
` listenHandle->Socket.ConnectedCallback,¬
` listenHandle->Socket.RecvCallback,¬
` listenHandle->Socket.ClosedCallback,¬
` &listenHandle->Socket.SocketAddr,¬
` listenHandle->Socket.UserContext);¬

` /* Wait for a connection */¬
` size = sizeof(saddr_remote);¬
` newContext->NativeSocket = accept(¬
`
`Page 12 of 25
`
`Implicit Exhibit 2054
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/win32/tcp.c
`Page 13/25
`Saved: 8/9/01, 8:59:00 PM
`Printed for: Implicit
`
`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
`564
`565
`566
`567
`568
`569
`
` listenHandle->Socket.NativeSocket,¬
` (struct sockaddr*)&saddr_remote,¬
` &size);¬
` if (newContext->NativeSocket == INVALID_SOCKET) {¬
` newContext->PeerHasClosed = SOS_True;¬
` newContext->WeHaveClosed = SOS_True;¬
` TcpSocketRelease(newContext);¬
` break;¬
` }¬

` /* Get the local address */¬
` size = sizeof(saddr_local);¬
` ret = getsockname(¬
` newContext->NativeSocket,¬
` (struct sockaddr*)&saddr_local,¬
` &size);¬
` /* SOS_ASSERT_ASSUMPTION(ret != SOCKET_ERROR, "getsockname
`failed\n"); */¬

` /* fill in the new socket address */¬
` newContext->SocketAddr.LocalAddr =
`htonl(saddr_local.sin_addr.s_addr);¬
` newContext->SocketAddr.LocalPort = htons(saddr_local.sin_port);¬
` newContext->SocketAddr.RemoteAddr =
`htonl(saddr_remote.sin_addr.s_addr);¬
` newContext->SocketAddr.RemotePort = htons(saddr_remote.sin_port);¬


` /* add a second reference for a half-close */¬
` TcpSocketReference(newContext);¬



` /* CONSIDER:¬
` re-spec the interface so that client connections¬
` also receive an OnConnect callback. This would move¬
` the OnConnect call to the native thread, which is a¬
` more logical place for it.¬
` */¬
` /* Call the user-defined OnConnect callback*/¬
` onConnectParam.FunctionId = TCP_CONNECT_FUNCTION_ID_TcpOnConnect;¬
` onConnectParam.Params.OnConnect.Socket = newContext;¬

` SOS_Internal_Call(TcpConnectionWorkerProc, &onConnectParam);¬

`
`Page 13 of 25
`
`Implicit Exhibit 2054
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/win32/tcp.c
`Page 14/25
`Saved: 8/9/01, 8:59:00 PM
`Printed for: Implicit
`
`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
`608
`609
`610
`611
`
` newContext->UserContext =
`onConnectParam.Params.OnConnect.OutUserContext;¬



` /* Inform the client of the new connection. */¬

` /* Spawn a thread to recv for incoming messages */¬
` /* surrender our reference to the new thread */¬
` newContext->NativeConnectionThread = _beginthread(¬
` TcpRecvThread,¬
` 0, /* default stack size */¬
` newContext);¬
` }¬


` TcpSocketRelease((SOS_ISOCKET_TCP*)listenHandle);¬


` /* wait for outstanding recv threads to die */¬
` /* HACK Sleep instead of doing a real wait */¬
` Sleep(100);¬

` return 0;¬
`}¬


`/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`++++++¬
`SocketLib API -- TCP¬
`-------------------------------------------------------------------------
`----*/¬
`static¬
`void¬
`NativeSocketAddrInit(¬
` struct sockaddr_in * SocketAddress,¬
` unsigned short SocketInPort,¬
` u_long IpAddress¬
`)¬
`{¬
` SocketAddress->sin_family = PF_INET;¬
` SocketAddress->sin_port = htons(SocketInPort);¬
` SocketAddress->sin_addr.s_addr = htonl(IpAddress);¬
`}¬

`
`Page 14 of 25
`
`Implicit Exhibit 2054
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/win32/tcp.c
`Page 15/25
`Saved: 8/9/01, 8:59:00 PM
`Printed for: Implicit
`
`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
`652
`…
`653
`654
`655
`

`/* create a new "client" socket, and start a recieve thread¬
` for any incoming data on this socket */¬
`SOS_STATUS¬
`Socket_TcpCreate(¬
` SOS_ISOCKET* Interface,¬
` SOS_ISOCKET_ADDRESS* SocketAddr,¬
` void* UserContext,¬
` SOS_ISOCKET_TCP_RECEIVE RecvCallback,¬
` SOS_ISOCKET_CLOSED ClosedCallback,¬
` SOS_ISOCKET_TCP** Socket¬
`)¬
`{¬
` SOS_STATUS status = SOS_Error;¬

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

` /* fill in winsock address structs */¬

` NativeSocketAddrInit(¬
` &saddr_local,¬
` SocketAddr->LocalPort,¬
` INADDR_ANY);¬

` NativeSocketAddrInit(¬
` &saddr_remote,¬
` SocketAddr->RemotePort,¬
` SocketAddr->RemoteAddr);¬

` /* Create a TCP socket. For UDP use SOCK_DGRAM. */¬
` nativeSocket = socket(PF_INET, SOCK_STREAM, 0);¬
` if (nativeSocket == INVALID_SOCKET) {¬
` return ERROR_SOCKET_FAILED;¬
` }¬

` /* Bind the socket to the local address */¬
` ret = bind(nativeSocket, (struct sockaddr*)&saddr_local,
`sizeof(saddr_local));¬
` if (ret == SOCKET_ERROR) {¬
` return ERROR_BIND_FAILED;¬
` }¬
`
`Page 15 of 25
`
`Implicit Exhibit 2054
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/win32/tcp.c
`Page 16/25
`Saved: 8/9/01, 8:59:00 PM
`Printed for: Implicit
`
`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
`697
`698
`

` /* Connect the socket to the remote address */¬
` ret = connect(nativeSocket, (struct sockaddr*)&saddr_remote,
`sizeof(saddr_remote));¬
` if (ret == SOCKET_ERROR) {¬
` return ERROR_CONNECT_FAILED;¬
` }¬

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

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

` /* Spawn a thread to recv for incoming messages */¬
` TcpSocketReference(context);¬
` context->NativeConnectionThread = _beginthread(¬
` TcpRecvThread,¬
` 0, /* default stack size */¬
` context);¬

` if (context->NativeConnectionThread != -1) {¬
` status = SOS_Success;¬
` }¬
` else {¬
` Socket_TcpReset(Interface, context);¬
` }¬
` }¬

` /* "return" my context */¬
` *Socket = context;¬
`
`Page 16 of 25
`
`Implicit Exhibit 2054
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/win32/tcp.c
`Page 17/25
`Saved: 8/9/01, 8:59:00 PM
`Printed for: Implicit
`
`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
`742
`743
`

` return status;¬
`}¬



`/*++¬
`Routine Name:¬

` Socket_TcpListenCancelExternal¬

`Routine Description:¬

` This external worker proceedure closes the listen socket,¬
` which should cause any pending call to accept() in the¬
` TcpListenThread to return with an error code, and cause¬
` that thread to exit. This routine waits for that thread¬
` to exit.¬

` This must be called from an external thread context.¬

`Parameters:¬

` void* Parameter - [in]¬
` The SOS_ISOCKET_TCP_LISTEN* to cancel.¬

`Return Value:¬

` None¬

`--*/¬
`static¬
`void¬
`Socket_TcpListenCancelExternal(¬
` void * Parameter¬
`)¬
`{¬
` SOS_ISOCKET_TCP_LISTEN* const listenHandle = Parameter;¬

` BOOL val = TRUE;¬
` int ret;¬

` setsockopt(¬
` listenHandle->Socket.NativeSocket,¬
` SOL_SOCKET,¬
`
`Page 17 of 25
`
`Implicit Exhibit 2054
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/win32/tcp.c
`Page 18/25
`Saved: 8/9/01, 8:59:00 PM
`Printed for: Implicit
`
`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
`786
`787
`788
`
` SO_DONTLINGER,¬
` (const char FAR *)&val,¬
` sizeof(BOOL));¬

` listenHandle->Socket.PeerHasClosed = SOS_True;¬
` listenHandle->Socket.WeHaveClosed = SOS_True;¬

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

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

` CloseHandle((HANDLE) listenHandle->NativeListenThread);¬

` TcpSocketRelease((SOS_ISOCKET_TCP*) listenHandle);¬
`}¬


`/* internal thread context */¬
`SOS_STATUS¬
`Socket_TcpListenCancel(¬
` SOS_ISOCKET* Interface,¬
` SOS_ISOCKET_TCP_LISTEN* ListenHandle¬
`)¬
`{¬
` SOS_External_Call(Socket_TcpListenCancelExternal, ListenHandle);¬

` return SOS_Success;¬
`}¬



`/*++¬
`Routine Name:¬

` Socket_TcpListen¬

`Routine Description:¬

` Sets up a listen socket on the given address. This routine¬
` returns a "listen handle" to the caller that the caller can¬
` later use to cancel or shutdown the listen with a call to¬
` Socket_TcpListenCancel().¬
`
`Page 18 of 25
`
`Implicit Exhibit 2054
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/win32/tcp.c
`Page 19/25
`Saved: 8/9/01, 8:59:00 PM
`Printed for: Implicit
`
`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
`830
`831
`832
`

` This must be called from an internal thread context.¬

`Parameters:¬

` SOS_ISOCKET_TCP_LISTEN** ListenHandle - [out]¬
` This is an opaque pointer to a "listen handle" that can be¬
` passed into a SOS_ISOCKET_TCP_LISTEN_DESTROY to cancel this call.¬
` This value is set to NULL if the routine fails.¬

` const SOS_ISOCKET_ADDRESS * SocketAddr - [in]¬
` The address info to listen.¬
` Some implementations may not correctly handle non-zero LocalAddr,¬
` RemoteAddr, and RemotePort values.¬

` SOS_ISOCKET_TCP_CONNECT ConnectedCallback - [in]¬
` This will be called when a new connection is accepted, before any¬
` data is received on the socket.¬

` SOS_ISOCKET_TCP_RECEIVE RecvCallback - [in]¬
` This will be called whenever new data is received on the socket¬

` SOS_ISOCKET_CLOSED ClosedCallback - [in]¬
` This will be called for each connected socket when the other side
`has¬
` done their half-close.¬

`Return Value:¬

` SOS_STATUS -¬
` SOS_Success, on success.¬

` an error code, on failure.¬

`--*/¬
`SOS_STATUS¬
`Socket_TcpListen(¬
` SOS_ISOCKET* Interface,¬
` const SOS_ISOCKET_ADDRESS * SocketAddr,¬
` SOS_ISOCKET_TCP_CONNECT ConnectedCallback,¬
` SOS_ISOCKET_TCP_RECEIVE RecvCallback,¬
` SOS_ISOCKET_CLOSED ClosedCallback,¬
` SOS_ISOCKET_TCP_LISTEN** ListenHandle¬
`)¬
`{¬
`
`Page 19 of 25
`
`Implicit Exhibit 2054
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/win32/tcp.c
`Page 20/25
`Saved: 8/9/01, 8:59:00 PM
`Printed for: Implicit
`
`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
`873
`874
`875
`876
`877
`
` SOS_STATUS status = SOS_ErrorParameter;¬

` if (ListenHandle != NULL) {¬

` SOS_ISOCKET_TCP_LISTEN* listenHandle = NULL;¬

` SOCKET nativeSocket;¬
` struct sockaddr_in saddr_local;¬
` int ret;¬

` /* set addresses in winsock addr struct */¬
` NativeSocketAddrInit(¬
` &saddr_local,¬
` SocketAddr->LocalPort,¬
` INADDR_ANY);¬

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

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

` /* fill my context */¬
` listenHandle = (SOS_ISOCKET_TCP_LISTEN*) TcpSocketCreate(¬
` nativeSocket,¬
` ConnectedCallback,¬
` RecvCallback,¬
` ClosedCallback,¬
` SocketAddr,¬
` NULL);¬

` if (listenHandle != NULL) {¬

` unsigned externalWorkerThreadId;¬

` TcpSocketReference((SOS_ISOCKET_TCP*) listenHandle);¬

` /* Spawn a thread to accept connections */¬
` listenHandle->NativeListenThread = _beginthreadex(¬
` NULL, /* no security
`
`Page 20 of 25
`
`Implicit Exhibit 2054
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/win32/tcp.c
`Page 21/25
`Saved: 8/9/01, 8:59:00 PM
`Printed for: Implicit
`
`877…
`878
`…
`879
`880
`881
`…
`882
`…
`883
`884
`885
`886
`887
`888
`889
`890
`891
`892
`893
`…
`894
`…
`895
`896
`897
`898
`899
`900
`901
`902
`903
`904
`905
`906
`907
`908
`909
`910
`911
`912
`913
`914
`915
`916
`
`descriptor */¬
` 0, /* default stack size
`*/¬
` TcpListenThread,¬
` listenHandle,¬
` 0, /* no creation flags
`*/¬
` &externalWorkerThreadId /* thread ID out param
`*/¬
` );¬

` if (listenHandle->NativeListenThread != 0) {¬
` status = SOS_Success;¬
` }¬
` else {¬
` status = SOS_ErrorResourceAllocation;¬
` }¬

` if (SOS_FAILED(status)) {¬
` TcpSocketRelease((SOS_ISOCKET_TCP*)
`listenHandle);¬
` TcpSocketRelease((SOS_ISOCKET_TCP*)
`listenHandle);¬
` listenHandle = NULL;¬
` }¬
` }¬
` else {¬
`

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