throbber
/Users/implicit/Desktop/Source Code/2001.11.01/beads/s…/…/posix/tcp.c
`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,¬
` &params->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, &params);¬
` }¬
` }¬

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

` SOS_Internal_Call(TcpConnectionWorkerProc, &params);¬


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

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