`Page 1/25
`Saved: 8/9/01, 8:59:33 PM
`Printed for: Implicit
`
`/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`1
`++++++¬
`…
`¬2
`$Id: tcp.c,v 1.10 2001/08/10 01:59:33 davidc Exp $¬
`3
`¬4
`Copyright (c) 2001 BeComm Corporation¬
`5
`¬6
`Filename:¬
`7
`¬8
` tcp.c¬
`9
`¬10
`Abstract:¬
`11
`¬12
` The posix implementation of the TCP portion of the SocketLib API.¬
`13
`¬14
`Owner:¬
`15
`¬16
` David Costanzo (davidc)¬
`17
`¬18
`-------------------------------------------------------------------------
`19
`----*/¬
`…
`#include <stdlib.h>¬
`20
`#include <stdio.h>¬
`21
`#include <pthread.h>¬
`22
`#include <assert.h>¬
`23
`#include <errno.h>¬
`24
`¬25
`#include <sys/time.h>¬
`26
`#include <unistd.h>¬
`27
`¬28
`#include <netdb.h>¬
`29
`#include <sys/socket.h>¬
`30
`#include <sys/types.h>¬
`31
`#include <netinet/in.h>¬
`32
`¬33
`#define SOS_DEBUG_ZONE "/classes/socket/tcp"¬
`34
`#include <sosstrings.h>¬
`35
`#include <sosisocket.h>¬
`36
`#include "socket.h"¬
`37
`#include "tcp.h"¬
`38
`¬39
`SOS_SOURCE_VERSION("$Id: tcp.c,v 1.10 2001/08/10 01:59:33 davidc Exp $");¬
`40
`¬41
`/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`42
`++++++¬
`…
`
`Page 1 of 25
`
`Implicit Exhibit 2052
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/beads/s…/…/posix/tcp.c
`Page 2/25
`Saved: 8/9/01, 8:59:33 PM
`Printed for: Implicit
`
`Constants¬
`43
`-------------------------------------------------------------------------
`44
`----*/¬
`…
`¬45
`#define ERROR_BIND_FAILED SOS_Error¬
`46
`#define ERROR_SOCKET_FAILED SOS_Error¬
`47
`#define ERROR_BIND_FAILED SOS_Error¬
`48
`#define ERROR_CONNECT_FAILED SOS_Error¬
`49
`#define ERROR_GETSOCKNAME_FAILED SOS_Error¬
`50
`¬51
`¬52
`/* size of buffer to allocate for each read */¬
`53
`static const size_t g_TcpRecvSize = 1500;¬
`54
`¬55
`/* largest amount to call send() with */¬
`56
`static const size_t g_MaxSendSize = 2048;¬
`57
`¬58
`/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`59
`++++++¬
`…
`Data Types¬
`60
`-------------------------------------------------------------------------
`61
`----*/¬
`…
`¬62
`/* TCP socket context to be passed back and¬
`63
` forth with caller of this library */¬
`64
`struct _SOS_ISOCKET_TCP {¬
`65
` int NativeSocket;¬
`66
`¬67
` pthread_mutex_t Mutex; /* non-recursive */¬
`68
` int RefCount;¬
`69
`¬70
` SOS_ISOCKET_TCP_CONNECT ConnectedCallback;¬
`71
` SOS_ISOCKET_TCP_RECEIVE RecvCallback;¬
`72
` SOS_ISOCKET_CLOSED ClosedCallback;¬
`73
` SOS_ISOCKET_ADDRESS SocketAddr;¬
`74
` void* UserContext;¬
`75
`¬76
` SOS_BOOLEAN PeerHasClosed;¬
`77
` SOS_BOOLEAN WeHaveClosed;¬
`78
`¬79
` pthread_t NativeConnectionThread;¬
`80
`};¬
`81
`¬82
`¬83
`struct _SOS_ISOCKET_TCP_LISTEN {¬
`84
`
`Page 2 of 25
`
`Implicit Exhibit 2052
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/beads/s…/…/posix/tcp.c
`Page 3/25
`Saved: 8/9/01, 8:59:33 PM
`Printed for: Implicit
`
` SOS_ISOCKET_TCP Socket;¬
`85
`¬86
` pthread_t NativeListenThread;¬
`87
`};¬
`88
`¬89
`¬90
`/* TcpConnectionWorkerProc types */¬
`91
`¬92
`typedef struct _CONNECTION_PARAM CONNECTION_PARAM;¬
`93
`¬94
`typedef enum _TCP_CONNECT_FUNCTION_ID {¬
`95
` TCP_CONNECT_FUNCTION_ID_TcpOnConnect,¬
`96
` TCP_CONNECT_FUNCTION_ID_TcpOnReceive,¬
`97
` TCP_CONNECT_FUNCTION_ID_TcpOnClose,¬
`98
`} TCP_CONNECT_FUNCTION_ID;¬
`99
`¬
`100
`struct _CONNECTION_PARAM {¬
`101
`¬
`102
` TCP_CONNECT_FUNCTION_ID FunctionId;¬
`103
`¬
`104
` union _CONNECTION_PARAMS {¬
`105
`¬
`106
` struct _CONNECTION_PARAM_ON_CONNECT {¬
`107
` SOS_ISOCKET_TCP * Socket;¬
`108
` void * OutUserContext;¬
`109
` } OnConnect;¬
`110
`¬
`111
`¬
`112
` struct _CONNECTION_PARAM_ON_RECEIVE {¬
`113
` SOS_ISOCKET_TCP * Socket;¬
`114
` void* Buffer;¬
`115
` size_t BufferLength;¬
`116
` SOS_FREEPROC BufferFree;¬
`117
` } OnReceive;¬
`118
`¬
`119
`¬
`120
` struct _CONNECTION_PARAM_ON_CLOSE {¬
`121
` SOS_ISOCKET_TCP * Socket;¬
`122
` } OnClose;¬
`123
`¬
`124
` } Params;¬
`125
`};¬
`126
`¬
`127
`¬
`128
`/* TcpSendWorkerProc types */¬
`129
`
`Page 3 of 25
`
`Implicit Exhibit 2052
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/beads/s…/…/posix/tcp.c
`Page 4/25
`Saved: 8/9/01, 8:59:33 PM
`Printed for: Implicit
`
`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
`171
`172
`
`¬
`typedef struct _TCP_SEND_WORKER_PROC TCP_SEND_WORKER_PROC;¬
`¬
`struct _TCP_SEND_WORKER_PROC {¬
` int NativeSocket;¬
` void * Buffer;¬
` size_t BufferLength;¬
` 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]¬
`
`Page 4 of 25
`
`Implicit Exhibit 2052
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/beads/s…/…/posix/tcp.c
`Page 5/25
`Saved: 8/9/01, 8:59:33 PM
`Printed for: Implicit
`
`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
`216
`217
`
` 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_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(¬
` int 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) {¬
`¬
` int initStatus;¬
`¬
` initStatus = pthread_mutex_init(&tcpSocket->Mutex, NULL);¬
` if (initStatus == 0) {¬
`¬
` tcpSocket->NativeSocket = NativeSocket;¬
` tcpSocket->ConnectedCallback = ConnectedCallback;¬
` tcpSocket->ClosedCallback = ClosedCallback;¬
` tcpSocket->RecvCallback = RecvCallback;¬
` tcpSocket->SocketAddr = *SocketAddr;¬
` tcpSocket->UserContext = UserContext;¬
`
`Page 5 of 25
`
`Implicit Exhibit 2052
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/beads/s…/…/posix/tcp.c
`Page 6/25
`Saved: 8/9/01, 8:59:33 PM
`Printed for: Implicit
`
`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
`261
`262
`
`¬
`¬
` tcpSocket->PeerHasClosed = SOS_False;¬
` tcpSocket->WeHaveClosed = SOS_False;¬
`¬
` tcpSocket->RefCount = 1;¬
` }¬
` else {¬
` free(tcpSocket);¬
` tcpSocket = NULL;¬
` }¬
` }¬
`¬
` return tcpSocket;¬
`}¬
`¬
`/*++¬
`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);¬
`
`Page 6 of 25
`
`Implicit Exhibit 2052
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/beads/s…/…/posix/tcp.c
`Page 7/25
`Saved: 8/9/01, 8:59:33 PM
`Printed for: Implicit
`
`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
`305
`306
`307
`
` assert(TcpSocket->PeerHasClosed);¬
` assert(TcpSocket->WeHaveClosed);¬
` pthread_mutex_destroy(&TcpSocket->Mutex);¬
` free(TcpSocket);¬
` }¬
`}¬
`¬
`¬
`/*++¬
`Routine Name:¬
`¬
` TcpSocketReference¬
`¬
`Routine Description:¬
`¬
` This routine adds a reference to a UDP socket struct.¬
`¬
`Parameters:¬
`¬
` 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);¬
`¬
` pthread_mutex_lock(&TcpSocket->Mutex);¬
` TcpSocket->RefCount++;¬
` pthread_mutex_unlock(&TcpSocket->Mutex);¬
` }¬
`¬
` return TcpSocket;¬
`}¬
`¬
`
`Page 7 of 25
`
`Implicit Exhibit 2052
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/beads/s…/…/posix/tcp.c
`Page 8/25
`Saved: 8/9/01, 8:59:33 PM
`Printed for: Implicit
`
`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
`350
`351
`
`/*++¬
`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¬
`¬
`--*/¬
`static¬
`void¬
`TcpSocketRelease(¬
` SOS_ISOCKET_TCP* TcpSocket¬
`)¬
`{¬
` if (TcpSocket) {¬
`¬
` int newValue;¬
`¬
` assert(0 < TcpSocket->RefCount);¬
`¬
` pthread_mutex_lock(&TcpSocket->Mutex);¬
` newValue = --TcpSocket->RefCount;¬
` pthread_mutex_unlock(&TcpSocket->Mutex);¬
`¬
` if (newValue == 0) {¬
` TcpSocketDestroy(TcpSocket);¬
` }¬
` }¬
`}¬
`¬
`¬
`¬
`
`Page 8 of 25
`
`Implicit Exhibit 2052
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/beads/s…/…/posix/tcp.c
`Page 9/25
`Saved: 8/9/01, 8:59:33 PM
`Printed for: Implicit
`
`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
`394
`395
`396
`
`/*¬
` 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,¬
` ¶ms->Params.OnReceive.Socket->SocketAddr¬
` );¬
`¬
` break;¬
`¬
` case TCP_CONNECT_FUNCTION_ID_TcpOnReceive:¬
`¬
` 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:¬
`
`Page 9 of 25
`
`Implicit Exhibit 2052
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/posix/tcp.c
`Page 10/25
`Saved: 8/9/01, 8:59:33 PM
`Printed for: Implicit
`
`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
`438
`439
`440
`
` 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]¬
` 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 tcpSocket = Parameter;¬
`¬
` CONNECTION_PARAM params;¬
`¬
` while (1) {¬
`¬
`
`Page 10 of 25
`
`Implicit Exhibit 2052
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/posix/tcp.c
`Page 11/25
`Saved: 8/9/01, 8:59:33 PM
`Printed for: Implicit
`
`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
`483
`484
`485
`
` char * buffer;¬
` int bytesReceived;¬
`¬
` buffer = malloc(g_TcpRecvSize);¬
`¬
` bytesReceived = read(¬
` tcpSocket->NativeSocket,¬
` buffer,¬
` g_TcpRecvSize);¬
`¬
` /* if the connection was closed or there was an error... */¬
` if (bytesReceived <= 0 && errno != -EINTR) {¬
` free(buffer);¬
` break;¬
` }¬
`¬
` if (0 < bytesReceived) {¬
` params.FunctionId = TCP_CONNECT_FUNCTION_ID_TcpOnReceive;¬
` params.Params.OnReceive.Socket = tcpSocket;¬
` params.Params.OnReceive.Buffer = buffer;¬
` params.Params.OnReceive.BufferLength = bytesReceived;¬
` params.Params.OnReceive.BufferFree = free;¬
`¬
` SOS_Internal_Call(TcpConnectionWorkerProc, ¶ms);¬
` }¬
` }¬
`¬
` /* notify the caller that the connection is closed */¬
` params.FunctionId = TCP_CONNECT_FUNCTION_ID_TcpOnClose;¬
` params.Params.OnClose.Socket = tcpSocket;¬
`¬
` SOS_Internal_Call(TcpConnectionWorkerProc, ¶ms);¬
`¬
`¬
` /* REVISIT: Race Condition */¬
` if (tcpSocket->WeHaveClosed) {¬
` close(tcpSocket->NativeSocket);¬
` }¬
` tcpSocket->PeerHasClosed = SOS_True;¬
`¬
` TcpSocketRelease(tcpSocket);¬
`¬
` return NULL;¬
`}¬
`¬
`
`Page 11 of 25
`
`Implicit Exhibit 2052
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/posix/tcp.c
`Page 12/25
`Saved: 8/9/01, 8:59:33 PM
`Printed for: Implicit
`
`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
`528
`529
`530
`
`¬
`¬
`/*++¬
`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:¬
`¬
` 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¬
`void *¬
`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"); */¬
`
`Page 12 of 25
`
`Implicit Exhibit 2052
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/posix/tcp.c
`Page 13/25
`Saved: 8/9/01, 8:59:33 PM
`Printed for: Implicit
`
`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
`…
`570
`571
`…
`572
`
`¬
` 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(¬
` listenHandle->Socket.NativeSocket,¬
` (struct sockaddr*)&saddr_remote,¬
` &size);¬
` if (newContext->NativeSocket < 0) {¬
` 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);¬
`
`Page 13 of 25
`
`Implicit Exhibit 2052
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/posix/tcp.c
`Page 14/25
`Saved: 8/9/01, 8:59:33 PM
`Printed for: Implicit
`
`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
`612
`613
`614
`615
`616
`
`¬
`¬
` /* 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);¬
`¬
` 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 */¬
` pthread_create(¬
` &newContext->NativeConnectionThread,¬
` NULL,¬
` TcpRecvThread,¬
` newContext);¬
` pthread_detach(newContext->NativeConnectionThread);¬
` }¬
`¬
` TcpSocketRelease((SOS_ISOCKET_TCP*)listenHandle);¬
`¬
` /* wait until the recv threads die */¬
` /* HACK: sleep instead of doing a real wait */¬
` {¬
` struct timespec sleepTime;¬
`¬
` sleepTime.tv_sec = 0;¬
` sleepTime.tv_nsec = 100000; /* 100 ms */¬
` nanosleep(&sleepTime, NULL);¬
`
`Page 14 of 25
`
`Implicit Exhibit 2052
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/posix/tcp.c
`Page 15/25
`Saved: 8/9/01, 8:59:33 PM
`Printed for: Implicit
`
`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
`656
`657
`658
`659
`
` }¬
`¬
` return NULL;¬
`}¬
`¬
`¬
`/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`++++++¬
`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);¬
`}¬
`¬
`¬
`/* 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;¬
`¬
` int nativeSocket;¬
` struct sockaddr_in saddr_local;¬
` struct sockaddr_in saddr_remote;¬
` int ret, size;¬
` SOS_ISOCKET_TCP* context;¬
` struct protoent *protocol;¬
`
`Page 15 of 25
`
`Implicit Exhibit 2052
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/posix/tcp.c
`Page 16/25
`Saved: 8/9/01, 8:59:33 PM
`Printed for: Implicit
`
`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
`699
`700
`701
`
`¬
` /* fill in winsock address structs */¬
`¬
` NativeSocketAddrInit(¬
` &saddr_local,¬
` SocketAddr->LocalPort,¬
` INADDR_ANY);¬
`¬
` NativeSocketAddrInit(¬
` &saddr_remote,¬
` SocketAddr->RemotePort,¬
` SocketAddr->RemoteAddr);¬
`¬
` protocol = getprotobyname("tcp");¬
`¬
` /* Create a TCP socket. For UDP use SOCK_DGRAM. */¬
` nativeSocket = socket(PF_INET, SOCK_STREAM, protocol->p_proto);¬
` if (nativeSocket < 0) {¬
` return ERROR_SOCKET_FAILED;¬
` }¬
`¬
` /* Bind the socket to the local address */¬
` ret = bind(nativeSocket, (struct sockaddr*)&saddr_local,
`sizeof(saddr_local));¬
` if (ret < 0) {¬
` return ERROR_BIND_FAILED;¬
` }¬
`¬
` /* Connect the socket to the remote address */¬
` ret = connect(nativeSocket, (struct sockaddr*)&saddr_remote,
`sizeof(saddr_remote));¬
` if (ret < 0) {¬
` return ERROR_CONNECT_FAILED;¬
` }¬
`¬
` /* Find out the local IP used */¬
` size = sizeof(saddr_local);¬
` ret = getsockname(nativeSocket, (struct sockaddr*)&saddr_local,
`&size);¬
` if (ret < 0) {¬
` return ERROR_GETSOCKNAME_FAILED;¬
` }¬
` SocketAddr->LocalAddr = ntohl(saddr_local.sin_addr.s_addr);¬
` SocketAddr->LocalPort = ntohs(saddr_local.sin_port);¬
`¬
`
`Page 16 of 25
`
`Implicit Exhibit 2052
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/posix/tcp.c
`Page 17/25
`Saved: 8/9/01, 8:59:33 PM
`Printed for: Implicit
`
`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
`744
`745
`746
`
` /* fill my context */¬
` context = TcpSocketCreate(¬
` nativeSocket,¬
` NULL,¬
` RecvCallback,¬
` ClosedCallback,¬
` SocketAddr,¬
` UserContext);¬
` if (context != NULL) {¬
`¬
` /* Spawn a thread to recv for incoming messages */¬
` TcpSocketReference(context);¬
` pthread_create(¬
` &context->NativeConnectionThread,¬
` NULL,¬
` TcpRecvThread,¬
` context);¬
`¬
` if (context->NativeConnectionThread != -1) {¬
` pthread_detach(context->NativeConnectionThread);¬
` status = SOS_Success;¬
` }¬
` else {¬
` Socket_TcpReset(&g_ISocket, context);¬
` }¬
` }¬
`¬
` /* "return" my context */¬
` *Socket = context;¬
`¬
` 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¬
`
`Page 17 of 25
`
`Implicit Exhibit 2052
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/posix/tcp.c
`Page 18/25
`Saved: 8/9/01, 8:59:33 PM
`Printed for: Implicit
`
`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
`789
`790
`791
`
` 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;¬
`¬
` int ret;¬
` struct linger olinger;¬
`¬
` olinger.l_onoff = 1;¬
` olinger.l_linger = 0;¬
`¬
` setsockopt(¬
` listenHandle->Socket.NativeSocket,¬
` SOL_SOCKET,¬
` SO_LINGER,¬
` (char *)&olinger,¬
` sizeof(olinger));¬
`¬
` ret = shutdown(listenHandle->Socket.NativeSocket, 2);¬
`¬
` listenHandle->Socket.PeerHasClosed = SOS_True;¬
` listenHandle->Socket.WeHaveClosed = SOS_True;¬
`¬
` /* make sure that TcpListenThread exits */¬
` pthread_join(¬
` listenHandle->NativeListenThread,¬
` NULL);¬
`
`Page 18 of 25
`
`Implicit Exhibit 2052
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/posix/tcp.c
`Page 19/25
`Saved: 8/9/01, 8:59:33 PM
`Printed for: Implicit
`
`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
`833
`834
`835
`836
`
`¬
` TcpSocketRelease((SOS_ISOCKET_TCP*) listenHandle);¬
`}¬
`¬
`¬
`/* internal thread context */¬
`SOS_STATUS¬
`Socket_TcpListenCancel(¬
` SOS_ISOCKET* Interface,¬
` SOS_ISOCKET_TCP_LISTEN* ListenHandle¬
`)¬
`{¬
` SOS_DEBUGOUT_FUNC_TRACE(¬
` "Destroying TCP listen on ports <%u,%u>\n",¬
` ListenHandle->Socket.SocketAddr.LocalPort,¬
` ListenHandle->Socket.SocketAddr.RemotePort);¬
`¬
` SOS_External_Call(Socket_TcpListenCancelExternal, ListenHandle);¬
`¬
` SOS_DEBUGOUT_FUNC_TRACE("Done destroying TCP listen on ports\n");¬
`¬
` 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().¬
`¬
` 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.¬
`
`Page 19 of 25
`
`Implicit Exhibit 2052
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/posix/tcp.c
`Page 20/25
`Saved: 8/9/01, 8:59:33 PM
`Printed for: Implicit
`
`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
`878
`879
`880
`
` 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¬
`)¬
`{¬
` SOS_STATUS status = SOS_ErrorParameter;¬
`¬
` if (ListenHandle != NULL) {¬
`¬
` SOS_ISOCKET_TCP_LISTEN* listenHandle = NULL;¬
`¬
` int nativeSocket;¬
` struct sockaddr_in saddr_local;¬
`
`Page 20 of 25
`
`Implicit Exhibit 2052
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/…/posix/tcp.c
`Page 21/25
`Saved: 8/9/01, 8:59:33 PM
`Printed for: Implicit
`
`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
`917
`918
`919
`920
`921
`922
`923
`…
`924
`
` int ret;¬
` struct protoent *protocol;¬
`¬
` SOS_DEBUGOUT_FUNC_TRACE(¬
` "Creating a TCP listen on local port %u\n",¬
` SocketAddr->LocalPort);¬
`¬
` /* set addresses in winsock addr struct */¬
` NativeSocketAddrInit(¬
` &saddr_local,¬
` SocketAddr->LocalPort,¬
` INADDR_ANY);¬
`¬
` protocol = getprotobyname("tcp");¬
`¬
` /* Create a TCP socket. For UDP use SOCK_DGRAM. */¬
` nativeSocket = socket(PF_INET, SOCK_STREAM, protocol->p_proto);¬
` if (0 <= nativeSocket) {¬
`¬
` /* Bind the socket to the local address */¬
` ret = bind(¬
` nativeSocket,¬
` (struct sockaddr*)&saddr_local,¬
` sizeof(saddr_local));¬
` if (0 <= ret) {¬
`¬
` /* fill my context */¬
` listenHandle = (SOS_ISOCKET_TCP_LISTEN*) TcpSocketCreate(¬
` nativeSocket,¬
` ConnectedCallback,¬
` RecvCallback,¬
` ClosedCallback,¬
` SocketAddr,¬
` NULL);¬
`¬
` if (listenHandle != NULL) {¬
`¬
` TcpSocketReference((SOS_ISOCKET_TCP*) listenHandle);¬
`¬
` /* Spawn a thread to accept connections */¬
` pthread_create(¬
` &listenHandle->NativeListenThread,¬
`