throbber
/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/main/timesync.c
`Page 1/27
`Saved: 10/23/01, 11:40:49 AM
`Printed for: Implicit
`
`/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`1
`++++++¬
`…
`¬2
`Copyright (c) 2001 BeComm Corporation¬
`3
`¬4
`Filename:¬
`5
`¬6
` timesync.c¬
`7
`¬8
`Group Name:¬
`9
`¬10
` todo¬
`11
`¬12
`Group Overview:¬
`13
`¬14
` Uses a broadcast protocol to determine the¬
`15
` clock offsets of all listening peers.¬
`16
`¬17
` Algorithm is based loosely on NTP.¬
`18
`¬19
` Also has edges which are used for passing¬
`20
` sample clocks across the network in a path.¬
`21
`¬22
`Owner:¬
`23
`¬24
` Guy Carpenter (guyc) 16-Aug-2001¬
`25
`¬26
`-------------------------------------------------------------------------
`27
`----*/¬
`…
`#define SOS_DEBUG_ZONE "/beads/timesync"¬
`28
`#include <sosstrings.h>¬
`29
`#include <sosmultimedia.h>¬
`30
`#include "timesync.h"¬
`31
`¬32
`SOS_SOURCE_VERSION("$Id: timesync.c,v 1.14 2001/10/23 16:40:49 guyc Exp
`33
`$");¬
`…
`¬34
`/*¬
`35
`* Broadcast sync packets every TIMER_INTERVAL milliseconds¬
`36
`*/¬
`37
`#define TIMER_INTERVAL 4000¬
`38
`#define TIMER_INITIAL_DELAY 200¬
`39
`#define MAX_AGE
`60000 /* expire after a minute */¬
`40
`¬41
`/*¬
`42
`
`Page 1 of 27
`
`Implicit Exhibit 2019
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/main/timesync.c
`Page 2/27
`Saved: 10/23/01, 11:40:49 AM
`Printed for: Implicit
`
` * Compute offset based on WINDOW_SIZE observations¬
`43
` */¬
`44
`#define WINDOW_SIZE 8¬
`45
`¬46
`/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`47
`++++++¬
`…
`Named Constants¬
`48
`-------------------------------------------------------------------------
`49
`----*/¬
`…
`¬50
`/*¬
`51
` * Name of bead¬
`52
` */¬
`53
`static¬
`54
`const char BEAD_NAME[] = "timesync";¬
`55
`¬56
`¬57
`¬58
`/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`59
`++++++¬
`…
`Globals¬
`60
`-------------------------------------------------------------------------
`61
`----*/¬
`…
`¬62
`/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`63
`++++++¬
`…
`Structs¬
`64
`-------------------------------------------------------------------------
`65
`----*/¬
`…
`¬66
`typedef struct {¬
`67
` SOS_UINT32 HostId;¬
`68
` SOS_CLOCK_TICK XmitTime;¬
`69
` SOS_CLOCK_TICK RecvTime;¬
`70
` SOS_INT32 Offset;¬
`71
` SOS_BOOLEAN OffsetValid;¬
`72
` SOS_INT32 Min[WINDOW_SIZE];¬
`73
` SOS_INT32 Max[WINDOW_SIZE];¬
`74
` SOS_UINT32 WindowFill;¬
`75
` SOS_UINT32 WindowPtr;¬
`76
`} HOSTINFO;¬
`77
`¬78
`typedef struct _UPDATE_HEADER {¬
`79
` SOS_UINT32 HostId;¬
`80
` SOS_CLOCK_TICK XmitTime;¬
`81
`
`Page 2 of 27
`
`Implicit Exhibit 2019
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/main/timesync.c
`Page 3/27
`Saved: 10/23/01, 11:40:49 AM
`Printed for: Implicit
`
`} UPDATE_HEADER;¬
`82
`¬83
`typedef struct {¬
`84
` SOS_UINT32 HostId;¬
`85
` SOS_CLOCK_TICK XmitTime;¬
`86
` SOS_CLOCK_TICK RecvTime;¬
`87
`} HOSTSYNC;¬
`88
`¬89
`typedef struct UPDATE_CONTEXT {¬
`90
` SOS_POINTERTABLE * HostTable;¬
`91
` SOS_LOCK * HostTableLock;¬
`92
` SOS_UINT32 HostId;¬
`93
` SOS_PATH * Path;¬
`94
` SOS_TIMER_ID TimerId;¬
`95
`} UPDATE_CONTEXT;¬
`96
`¬97
`#define LOCK() SOS_Lock_Acquire(g_Context->HostTableLock)¬
`98
`#define UNLOCK() SOS_Lock_Release(g_Context->HostTableLock)¬
`99

`100

`101
`/*¬
`102
` * Maintain a single global context, since this is a system-wide
`103
`protocol.¬
`…
` */¬
`104
`static¬
`105
`UPDATE_CONTEXT * g_Context;¬
`106

`107
`/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`108
`++++++¬
`…

`109
`-------------------------------------------------------------------------
`110
`----*/¬
`…

`111
`static¬
`112
`HOSTINFO *¬
`113
`TimeSync_HostInfoFind(¬
`114
` SOS_UINT32 HostId¬
`115
`)¬
`116
`{¬
`117
` HOSTINFO *host = NULL;¬
`118

`119
` SOS_PointerTable_ElementPeek(¬
`120
` g_Context->HostTable,¬
`121
` (void*)HostId,¬
`122
` (void**)&host¬
`123
`
`Page 3 of 27
`
`Implicit Exhibit 2019
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/main/timesync.c
`Page 4/27
`Saved: 10/23/01, 11:40:49 AM
`Printed for: Implicit
`
`124
`125
`126
`127
`128
`129
`130
`131
`132
`133
`134
`135
`136
`137
`138
`139
`140
`141
`142
`143
`144
`145
`146
`147
`148
`149
`150
`151
`152
`153
`154
`155
`156
`157
`158
`159
`160
`161
`162
`163
`164
`165
`166
`167
`168
`
` );¬

` return host;¬
`}¬
`static¬
`HOSTINFO *¬
`TimeSync_HostInfoFindOrAdd(¬
` SOS_UINT32 HostId¬
`)¬
`{¬
` HOSTINFO *host = NULL;¬

` host = TimeSync_HostInfoFind(HostId);¬

` if (!host) {¬
` SOS_DEBUGOUT_MAJOR_EVENT(¬
` "Adding host %x to table\n",¬
` HostId¬
` );¬
` host = SOS_Mem_Alloc(sizeof(*host));¬
` SOS_memset(host, 0, sizeof(*host));¬
` host->HostId = HostId;¬
` SOS_PointerTable_ElementPut(¬
` g_Context->HostTable,¬
` (void*)HostId,¬
` host¬
` );¬
` }¬

` return host;¬
`}¬

`static¬
`void¬
`TimeSync_Expire(¬
` UPDATE_CONTEXT * Context,¬
` SOS_UINT32 MaxAge¬
`)¬
`{¬

` SOS_POINTERTABLE_ITERATOR *iterator;¬
` HOSTINFO *hostInfo;¬
` SOS_CLOCK_TICK now = SOS_Clock_TickGet();¬
` ¬
` SOS_DEBUGOUT_FUNC_TRACE("TimeSync_Expire\n");¬
`
`Page 4 of 27
`
`Implicit Exhibit 2019
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/main/timesync.c
`Page 5/27
`Saved: 10/23/01, 11:40:49 AM
`Printed for: Implicit
`
`169
`170
`171
`172
`173
`174
`175
`176
`177
`178
`179
`180
`181
`182
`183
`184
`185
`186
`187
`188
`189
`190
`191
`192
`193
`194
`195
`196
`197
`198
`199
`200
`201
`202
`203
`204
`205
`206
`207
`208
`209
`210
`211
`212
`213
`

` LOCK();¬

` SOS_PointerTableIterator_Create(¬
` Context->HostTable,¬
` &iterator¬
` );¬

` while (SOS_Success==SOS_PointerTableIterator_Next(¬
` iterator,¬
` NULL,¬
` (void**)&hostInfo¬
` )) {¬
` SOS_CLOCK_TICK age = now - hostInfo->RecvTime;¬

` if (age>MaxAge) {¬

` SOS_DEBUGOUT_MAJOR_EVENT(¬
` "Removing host %x (age %lu) from table\n",¬
` hostInfo->HostId,¬
` age¬
` );¬
` ¬
` SOS_PointerTable_ElementRemove(¬
` Context->HostTable,¬
` (void*)hostInfo->HostId,¬
` NULL¬
` );¬

` {¬
` /*¬
` * This ugliness works around the fact¬
` * that the table API does not allow us¬
` * to destroy a member during iteration.¬
` * So each time we remove something we¬
` * start again.¬
` */¬
` SOS_PointerTableIterator_Destroy(¬
` iterator¬
` );¬
` SOS_PointerTableIterator_Create(¬
` Context->HostTable,¬
` &iterator¬
` );¬
` }¬
`
`Page 5 of 27
`
`Implicit Exhibit 2019
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/main/timesync.c
`Page 6/27
`Saved: 10/23/01, 11:40:49 AM
`Printed for: Implicit
`
`214
`215
`216
`217
`218
`219
`220
`221
`222
`223
`224
`225
`226
`227
`228
`229
`230
`231
`232
`233
`234
`235
`236
`237
`238
`239
`240
`241
`242
`243
`244
`245
`246
`247
`248
`249
`250
`251
`252
`253
`254
`255
`256
`257
`258
`
` }¬
` }¬

` SOS_PointerTableIterator_Destroy(¬
` iterator¬
` );¬

` UNLOCK();¬

`}¬

`static¬
`void¬
`TimeSync_HostUpdate(¬
` SOS_UINT32 HostId,¬
` SOS_CLOCK_TICK XmitTime,¬
` SOS_CLOCK_TICK RecvTime,¬
` HOSTSYNC * HostSync¬
`)¬
`{¬
` HOSTINFO *info;¬

` LOCK();¬

` info = TimeSync_HostInfoFindOrAdd(HostId);¬

` info->XmitTime = XmitTime;¬
` info->RecvTime = RecvTime;¬

` if (HostSync) {¬
` /*¬
` * Consider the offset td between host A and host B.¬
` * t0 the packet was sent by A¬
` * t1 the packet was received by B¬
` * t2 response sent by B¬
` * t3 response received by A¬
` * delayAB is the real time delay between event0 and event1¬
` * delayBA is the real time delay between event2 and event3¬
` * td is the clock offset such that (t0+td==t1)¬
` * ¬
` * t0+td+delayAB = t1¬
` * t2-td+delayBA = t3¬
` *¬
` * td = t1-t0-delayAB¬
` * td = t2-t3+delayBA¬
`
`Page 6 of 27
`
`Implicit Exhibit 2019
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/main/timesync.c
`Page 7/27
`Saved: 10/23/01, 11:40:49 AM
`Printed for: Implicit
`
`259
`260
`261
`262
`263
`264
`265
`266
`267
`268
`269
`270
`271
`272
`273
`274
`275
`276
`277
`278
`279
`280
`281
`282
`283
`284
`285
`286
`287
`288
`289
`290
`291
`292
`293
`294
`295
`296
`297
`298
`299
`300
`301
`302
`303
`
` *¬
` * Since delayAB and delayBA are always >= 0¬
` * td <= (t1-t0)¬
` * td >= (t2-t3)¬
` *¬
` * This gives us a way of computing bounds on td. We¬
` * expect delayAB and delayBA to vary rapidly, but td¬
` * to vary very slowly (only as the clocks drift relative¬
` * to each other).¬
` */¬
` SOS_UINT32 t0 = HostSync->XmitTime;¬
` SOS_UINT32 t1 = HostSync->RecvTime;¬
` SOS_UINT32 t2 = XmitTime;¬
` SOS_UINT32 t3 = RecvTime;¬
` SOS_INT32 tdmax = (SOS_INT32)(t1-t0);¬
` SOS_INT32 tdmin = (SOS_INT32)(t2-t3);¬

` /*¬
` * Instantanous offset value would be¬
` * info->Offset = ((SOS_INT32)((t1-t0)+(t2-t3)))/2;¬
` * but we will keep a running average of min and max to¬
` * smooth out asymmetric delivery delays.¬
` */¬
` if (0) {¬
` SOS_Debug_StringPrint(¬
` "%lu %lu %lu %lu\n",¬
` t0,¬
` t1,¬
` t2,¬
` t3¬
` );¬
` }¬
` ¬
` /*¬
` * Store values for running min/max¬
` */¬
` info->Min[info->WindowPtr] = tdmin;¬
` info->Max[info->WindowPtr] = tdmax;¬
` info->WindowPtr++;¬
` if (info->WindowFill<info->WindowPtr) {¬
` info->WindowFill = info->WindowPtr;¬
` }¬
` if (info->WindowPtr==WINDOW_SIZE) {¬
` info->WindowPtr=0;¬
` }¬
`
`Page 7 of 27
`
`Implicit Exhibit 2019
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/main/timesync.c
`Page 8/27
`Saved: 10/23/01, 11:40:49 AM
`Printed for: Implicit
`
`304
`305
`306
`307
`308
`309
`310
`311
`312
`313
`314
`315
`316
`317
`318
`319
`320
`321
`322
`323
`324
`325
`326
`327
`328
`329
`330
`331
`332
`333
`334
`335
`336
`337
`338
`339
`340
`341
`342
`343
`…
`344
`345
`346
`347
`

` /*¬
` * Now compute an estimate for offset¬
` */¬
` {¬
` SOS_INT32 min = tdmin;¬
` SOS_INT32 max = tdmax;¬
` SOS_UINT32 i;¬
` for (i=0;i<info->WindowFill;i++) {¬
` /*¬
` * note this is finding the highest min¬
` * and lowest max.¬
` */¬
` if (info->Min[i]>min) min=info->Min[i];¬
` if (info->Max[i]<max) max=info->Max[i];¬
` }¬
` /*¬
` * Use¬
` * M = A+(B-A)/2¬
` * instead of¬
` * M = (A+B)/2¬
` * to avoid overflow - A+B might exceed maxval.¬
` */¬
` info->Offset = min+(max-min)/2;¬
` info->OffsetValid = SOS_True;¬

` if (0) {¬
` for (i=0;i<info->WindowFill;i++) {¬
` SOS_Debug_StringPrint("%ld ",info->Min[i]);¬
` }¬
` SOS_Debug_StringPrint("\n");¬
` for (i=0;i<info->WindowFill;i++) {¬
` SOS_Debug_StringPrint("%ld ",info->Max[i]);¬
` }¬
` SOS_Debug_StringPrint("\n");¬
` }¬

` if (0) {¬
` SOS_Debug_StringPrint(¬
` "Offset for %x= now %ld/%ld/%ld smooth
`%ld/%ld/%ld\n",¬
` HostId,¬
` tdmin,¬
` tdmin+(tdmax-tdmin)/2,¬
` tdmax,¬
`
`Page 8 of 27
`
`Implicit Exhibit 2019
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/bea…/…/main/timesync.c
`Page 9/27
`Saved: 10/23/01, 11:40:49 AM
`Printed for: Implicit
`
`348
`349
`350
`351
`352
`353
`354
`355
`356
`357
`358
`359
`360
`361
`362
`363
`364
`365
`366
`367
`368
`369
`370
`371
`372
`373
`374
`375
`376
`377
`378
`379
`380
`381
`382
`383
`384
`385
`386
`387
`388
`389
`390
`391
`392
`
` min,¬
` min+(max-min)/2,¬
` max¬
` );¬
` }¬
` }¬

` }¬
` ¬
` UNLOCK();¬
`}¬
` ¬

`SOS_STATUS¬
`TimeSync_OffsetGet(¬
` SOS_UINT32 HostId,¬
` SOS_CLOCK_TICK * Offset¬
` ¬
`)¬
`{¬
` SOS_STATUS status = SOS_Success;¬
` HOSTINFO *hostInfo;¬
` SOS_UINT32 offset = 0;¬
` ¬
` LOCK();¬
` ¬
` hostInfo = TimeSync_HostInfoFind(HostId);¬
` ¬
` if (hostInfo && hostInfo->OffsetValid) {¬
` offset = hostInfo->Offset;¬
` } else {¬
` status = SOS_ErrorNotFound;¬
` }¬

` if (Offset) {¬
` *Offset = offset;¬
` }¬

` UNLOCK();¬
` return status;¬
`}¬

`SOS_STATUS¬
`TimeSync_HostIdGet(¬
` SOS_UINT32 * HostId¬
`
`Page 9 of 27
`
`Implicit Exhibit 2019
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/be…/…/main/timesync.c
`Page 10/27
`Saved: 10/23/01, 11:40:49 AM
`Printed for: Implicit
`
`393
`394
`395
`396
`397
`398
`399
`400
`401
`…
`402
`403
`…
`404
`405
`406
`407
`408
`409
`410
`411
`412
`…
`413
`414
`415
`416
`417
`418
`419
`420
`421
`422
`423
`424
`425
`426
`427
`428
`429
`430
`431
`432
`433
`434
`
`)¬
`{¬
` *HostId = g_Context->HostId;¬
` return SOS_Success;¬
`}¬



`/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`++++++¬
`Context create and destory¬
`-------------------------------------------------------------------------
`----*/¬

`/*++¬
`Routine Name:¬

` TimeSync_ContextCreate¬

`Routine Description:¬

` Attempt to allocate a TimeSync session and all the resources it
`requires.¬

`Parameters:¬

` None.¬

`Return Value:¬

` UPDATE_CONTEXT * - ¬
` A valid pointer to a session context on success.¬

` A NULL pointer if an error occured.¬

`--*/¬
`static¬
`UPDATE_CONTEXT *¬
`TimeSync_ContextCreate(¬
` void¬
`)¬
`{¬
` UPDATE_CONTEXT *context;¬

` SOS_DEBUGOUT_FUNC_TRACE("TimeSync_ContextCreate called\n");¬
`
`Page 10 of 27
`
`Implicit Exhibit 2019
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/be…/…/main/timesync.c
`Page 11/27
`Saved: 10/23/01, 11:40:49 AM
`Printed for: Implicit
`
`435
`436
`437
`438
`439
`440
`441
`442
`443
`444
`445
`446
`447
`448
`449
`450
`451
`452
`453
`454
`455
`456
`457
`458
`459
`460
`461
`462
`463
`464
`465
`466
`467
`468
`469
`470
`471
`472
`473
`474
`475
`476
`477
`478
`479
`

` /* allocate memory for TimeSync session context */¬
` context = SOS_Mem_Alloc(sizeof(*context));¬

` if (context) {¬
` context->HostTable = SOS_PointerTable_Create(¬
` NULL, /* generate hash from key pointer */¬
` NULL, /* use pointer equality for key compare */¬
` NULL, /* no key freeproc */¬
` SOS_Mem_Free /* element freeproc */¬
` );¬
` context->HostTableLock = SOS_Lock_Create();¬
` context->HostId = SOS_Clock_TickGet();¬
` }¬
` return context;¬
`}¬

`/*++¬
`Routine Name:¬

` TimeSync_ContextDestroy¬

`Routine Description:¬

` A helper function use to release all TimeSync context resources.¬

`Parameters:¬

` UPDATE_CONTEXT * Context - [consumed]¬
` An TimeSync context who's resources and memory are to be freed¬

`Return Value:¬

` None.¬

`--*/¬
`static¬
`void¬
`TimeSync_ContextDestroy(¬
` UPDATE_CONTEXT * Context¬
`)¬
`{¬
` SOS_DEBUGOUT_FUNC_TRACE("TimeSync_ContextDestroy called\n");¬
` ¬
` if (Context) {¬
`
`Page 11 of 27
`
`Implicit Exhibit 2019
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/be…/…/main/timesync.c
`Page 12/27
`Saved: 10/23/01, 11:40:49 AM
`Printed for: Implicit
`
`480
`481
`482
`483
`484
`485
`486
`487
`…
`488
`489
`…
`490
`491
`492
`493
`494
`495
`496
`497
`498
`499
`500
`501
`502
`503
`504
`505
`506
`507
`508
`509
`510
`511
`512
`513
`514
`515
`516
`517
`518
`519
`520
`521
`522
`
` SOS_Path_Destroy(Context->Path);¬
` SOS_PointerTable_Destroy(Context->HostTable);¬
` SOS_Lock_Destroy(Context->HostTableLock);¬
` SOS_Mem_Free(Context);¬
` }¬
`}¬

`/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`++++++¬
`Broadcast¬
`-------------------------------------------------------------------------
`----*/¬
`static¬
`SOS_STATUS¬
`TimeSync_PathCreate(¬
` UPDATE_CONTEXT * Context¬
`)¬
`{¬
` SOS_STATUS status;¬
`#define OUTPUT_CONTENT_TYPE "TimeSync/Output"¬
` SOS_REGOBJECT *contentType =¬
` SOS_String_CreateFromString(OUTPUT_CONTENT_TYPE);¬

` Context->Path = SOS_Path_Create(NULL /* no parent path */);¬
` if (Context->Path) {¬
` status = SOS_Path_AttributeSet(¬
` Context->Path,¬
` "Content-Type",¬
` contentType¬
` );¬
` } else {¬
` /* couldn't create path */¬
` status = SOS_Error;¬
` }¬

` SOS_RegObject_Release(contentType);¬

` return status;¬
`}¬


`static¬
`SOS_STATUS¬
`TimeSync_Send(¬
` UPDATE_CONTEXT * Context¬
`
`Page 12 of 27
`
`Implicit Exhibit 2019
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/be…/…/main/timesync.c
`Page 13/27
`Saved: 10/23/01, 11:40:49 AM
`Printed for: Implicit
`
`523
`524
`525
`526
`527
`528
`529
`530
`531
`532
`533
`534
`535
`536
`537
`538
`539
`540
`541
`542
`543
`544
`545
`546
`547
`548
`549
`550
`551
`552
`553
`554
`555
`556
`557
`558
`559
`560
`561
`562
`563
`564
`565
`566
`567
`
`)¬
`{¬
` SOS_STATUS status;¬
` SOS_MESSAGE *message = SOS_Message_Create();¬
` UPDATE_HEADER *header;¬
` HOSTSYNC *hostSync, *nextSync;¬
` HOSTINFO *hostInfo;¬
` SOS_CLOCK_TICK now = SOS_Clock_TickGet();¬
` SOS_UINT32 count, validCount;¬
` SOS_POINTERTABLE_ITERATOR *iterator;¬

` SOS_DEBUGOUT_FUNC_TRACE("TimeSync_Send\n");¬

` LOCK();¬

` count = SOS_PointerTable_LengthGet(¬
` Context->HostTable¬
` );¬
` validCount=0;¬

` hostSync = SOS_Mem_Alloc(sizeof(HOSTSYNC)*count);¬
` nextSync = hostSync;¬
` ¬
` SOS_PointerTableIterator_Create(¬
` Context->HostTable,¬
` &iterator¬
` );¬

` while (SOS_Success==SOS_PointerTableIterator_Next(¬
` iterator,¬
` NULL,¬
` (void**)&hostInfo¬
` )) {¬
` SOS_CLOCK_TICK age = now - hostInfo->RecvTime;¬

` SOS_Debug_StringPrint(¬
` "Host %x age %lu offset %ld\n",¬
` hostInfo->HostId,¬
` age,¬
` hostInfo->Offset¬
` );¬

` nextSync->HostId = hostInfo->HostId;¬
` nextSync->XmitTime = hostInfo->XmitTime;¬
` nextSync->RecvTime = hostInfo->RecvTime;¬
`
`Page 13 of 27
`
`Implicit Exhibit 2019
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/be…/…/main/timesync.c
`Page 14/27
`Saved: 10/23/01, 11:40:49 AM
`Printed for: Implicit
`
`568
`569
`570
`571
`572
`573
`574
`575
`576
`577
`578
`579
`580
`581
`582
`583
`584
`585
`586
`587
`588
`589
`590
`591
`592
`593
`594
`595
`596
`597
`598
`599
`600
`601
`602
`603
`604
`605
`606
`607
`608
`609
`610
`611
`612
`
` nextSync++;¬
` validCount++;¬
` }¬

` SOS_PointerTableIterator_Destroy(¬
` iterator¬
` );¬

` UNLOCK();¬

` SOS_Message_HeadDataPush(¬
` message,¬
` hostSync,¬
` sizeof(HOSTSYNC)*validCount,¬
` SOS_Mem_Free¬
` );¬

` header = SOS_Mem_Alloc(sizeof(*header));¬
` /* set this as late as possible */¬
` header->HostId = Context->HostId;¬
` header->XmitTime = SOS_Clock_TickGet();¬
` SOS_Message_HeadDataPush(¬
` message,¬
` header,¬
` sizeof(*header),¬
` SOS_Mem_Free¬
` );¬

` ¬
` status = SOS_Path_MessageSend(¬
` Context->Path,¬
` message¬
` );¬

` return status;¬
`}¬
`static¬
`void¬
`TimeSync_CallBack(¬
` void * Context¬
`);¬

`static¬
`SOS_STATUS¬
`TimeSync_TimerStart(¬
`
`Page 14 of 27
`
`Implicit Exhibit 2019
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/be…/…/main/timesync.c
`Page 15/27
`Saved: 10/23/01, 11:40:49 AM
`Printed for: Implicit
`
`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
`656
`657
`
` UPDATE_CONTEXT * Context¬
`)¬
`{¬
` SOS_STATUS status;¬
` SOS_DEBUGOUT_FUNC_TRACE("TimeSync_TimerStart\n");¬

` status = SOS_Timer_PeriodicSchedule(¬
` TIMER_INITIAL_DELAY,¬
` TIMER_INTERVAL,¬
` TimeSync_CallBack,¬
` Context,¬
` &Context->TimerId¬
` );¬

` return status;¬
`}¬

`static¬
`SOS_STATUS¬
`TimeSync_TimerStop(¬
` UPDATE_CONTEXT * Context¬
`)¬
`{¬
` SOS_STATUS status;¬
` SOS_DEBUGOUT_FUNC_TRACE("TimeSync_TimerStop\n");¬

` status = SOS_Timer_Cancel(¬
` Context->TimerId¬
` );¬

` return status;¬
`}¬

`static¬
`void¬
`TimeSync_CallBack(¬
` void * Context¬
`)¬
`{¬
` SOS_DEBUGOUT_FUNC_TRACE("TimeSync_TimerCallBack\n");¬
` TimeSync_Expire(Context, MAX_AGE);¬
` TimeSync_Send(Context);¬
`}¬


`
`Page 15 of 27
`
`Implicit Exhibit 2019
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/be…/…/main/timesync.c
`Page 16/27
`Saved: 10/23/01, 11:40:49 AM
`Printed for: Implicit
`
`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
`699
`700
`
`/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`++++++¬
`Edge Handlers¬
`-------------------------------------------------------------------------
`----*/¬

`/*++¬
`Routine Name:¬

` TimeSync_KeyCreate¬

`Routine Description:¬

` To ensure a single session, the key is constant.¬

`Parameters:¬

` SOS_PATH *Path - [in]¬
` The new Path to create a Key for¬

` SOS_MESSAGE *Message - [in]¬

`Return Value:¬

` SOS_STATUS - ¬
` SOS_PathBuild_Stop on success.¬

` SOS_Error if something goes wrong.¬
`--*/¬
`static¬
`SOS_STATUS¬
`TimeSync_KeyCreate(¬
` SOS_PATH *Path,¬
` SOS_MESSAGE *Message¬
`)¬
`{¬
`#define KEY_STRING "timesync key"¬
` SOS_REGOBJECT* key;¬
` SOS_STATUS status;¬

` SOS_DEBUGOUT_FUNC_TRACE("TimeSync_KeyCreate called\n");¬

` status = SOS_RegObject_CreateFromString(KEY_STRING, &key);¬

` if (SOS_SUCCEEDED(status)) {¬
`
`Page 16 of 27
`
`Implicit Exhibit 2019
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/be…/…/main/timesync.c
`Page 17/27
`Saved: 10/23/01, 11:40:49 AM
`Printed for: Implicit
`
`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
`744
`745
`
` status = SOS_Path_SessionKeySet(Path, key);¬
` }¬

` SOS_RegObject_Release(key);¬

` return SOS_SUCCEEDED(status) ? SOS_PathBuild_Stop : status;¬
`}¬


`/*++¬
`Routine Name:¬

` TimeSync_UpdateHandler¬

`Routine Description:¬

` Insert Description Here¬

`Parameters:¬

` SOS_PATH *Path - [in]¬
` The Path that this message is arriving on. It is used to get¬
` the TimeSync session context.¬

` SOS_MESSAGE *Message - [consumed]¬
` Message containing timesync data to be decoded.¬

`Return Value:¬

` SOS_STATUS - ¬
` SOS_Success¬
` if the data was successfuly decoded.¬

` SOS_Error otherwise.¬

`--*/¬
`static¬
`SOS_STATUS¬
`TimeSync_UpdateHandler(¬
` SOS_PATH *Path,¬
` SOS_MESSAGE *Message¬
`)¬
`{¬
` SOS_STATUS status = SOS_Success;¬
` SOS_CLOCK_TICK recvTime = SOS_Clock_TickGet();¬
`
`Page 17 of 27
`
`Implicit Exhibit 2019
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/be…/…/main/timesync.c
`Page 18/27
`Saved: 10/23/01, 11:40:49 AM
`Printed for: Implicit
`
`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
`789
`790
`
` UPDATE_CONTEXT * context;¬
` HOSTSYNC hostSync;¬
` UPDATE_HEADER header;¬
` SOS_BOOLEAN found = SOS_False;¬

` status = SOS_Path_SessionContextPeek(Path, (void**)&context);¬

` SOS_Message_HeadDataPop(¬
` Message,¬
` sizeof(UPDATE_HEADER),¬
` &header,¬
` NULL¬
` );¬


` if (0) {¬
` SOS_Debug_StringPrint(¬
` "Received TimeSync from %x@%lu\n",¬
` header.HostId,¬
` header.XmitTime¬
` );¬
` }¬

`// SOS_ASSERT_ASSUMPTION(0,"break");¬

`// if (header.HostId!=context->HostId) {¬
` if (1) {¬
` while (!found &&¬
` SOS_Message_LengthGet(Message)>=sizeof(HOSTSYNC)) {¬
` SOS_Message_HeadDataPop(¬
` Message,¬
` sizeof(HOSTSYNC),¬
` &hostSync,¬
` NULL¬
` );¬

` if (0) {¬
` SOS_Debug_StringPrint(¬
` "TimeSync from %x@%lu contains %x@%lu/%lu\n",¬
` header.HostId,¬
` header.XmitTime,¬
` hostSync.HostId,¬
` hostSync.XmitTime,¬
` hostSync.RecvTime¬
` );¬
`
`Page 18 of 27
`
`Implicit Exhibit 2019
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/be…/…/main/timesync.c
`Page 19/27
`Saved: 10/23/01, 11:40:49 AM
`Printed for: Implicit
`
`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
`833
`834
`835
`
` }¬
` ¬
` if (hostSync.HostId==context->HostId) {¬
` found = SOS_True;¬
` }¬
` }¬

` TimeSync_HostUpdate(¬
` header.HostId,¬
` header.XmitTime,¬
` recvTime,¬
` found ? &hostSync : NULL¬
` );¬
` }¬

` SOS_Message_Destroy(Message);¬
` ¬
` SOS_DEBUGOUT_FUNC_TRACE("TimeSync_UpdateHandler\n");¬

`// SOS_ASSERT_ASSUMPTION(0,"break");¬

` if (0) {¬
` SOS_REGOBJECT *localAddress;¬
` SOS_REGOBJECT *remoteAddress;¬
` char *localString;¬
` char *remoteString;¬

` SOS_Path_AttributeGet(¬
` Path,¬
` "Network-Address-Local",¬
` &localAddress¬
` );¬
` SOS_Path_AttributeGet(¬
` Path,¬
` "Network-Address-Remote",¬
` &remoteAddress¬
` );¬

` SOS_RegObject_ToQualifiedString(¬
` localAddress,¬
` &localString¬
` );¬

` SOS_RegObject_ToQualifiedString(¬
` localAddress,¬
`
`Page 19 of 27
`
`Implicit Exhibit 2019
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/be…/…/main/timesync.c
`Page 20/27
`Saved: 10/23/01, 11:40:49 AM
`Printed for: Implicit
`
`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
`878
`
` &remoteString¬
` );¬

` SOS_Debug_StringPrint(¬
` "LocalAddress=%s RemoteAddress=%s\n",¬
` localString,¬
` remoteString¬
` );¬

`// SOS_ASSERT_ASSUMPTION(0,"break");¬

` SOS_Mem_Free(localString);¬
` SOS_Mem_Free(remoteString);¬
` }¬

`// SOS_Debug_StringPrint("TimeSync update handler hit\n");¬

` return status;¬
`}¬



`/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`++++++¬
`Session init and uninit¬
`+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`++++*/¬

`/*++¬
`Routine Name:¬

` TimeSync_SessionInit¬

`Routine Description:¬

` Called by Strings when TimeSync_KeyCreate returns that a new¬
` TimeSync session should be created. It allocates a session¬
` context and assocates it with the Path that is passed in.¬

`Parameters:¬

` SOS_PATH *Path - [in]¬
` The path assocated with the mp3decoder to be created.¬

`Return Value:¬
`
`Page 20 of 27
`
`Implicit Exhibit 2019
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/be…/…/main/timesync.c
`Page 21/27
`Saved: 10/23/01, 11:40:49 AM
`Printed for: Implicit
`
`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
`917
`918
`919
`920
`921
`922
`923
`

` SOS_STATUS - ¬
` SOS_Success if a context was created and succesfully assocated¬
` with a path.¬

` SOS_Error otherwise.¬

`--*/¬
`static¬
`SOS_STATUS¬
`TimeSync_SessionInit(¬
` SOS_PATH *Path¬
`)¬
`{¬
` SOS_STATUS status = SOS_Success;¬
` UPDATE_CONTEXT *context = g_Context;¬

` SOS_DEBUGOUT_FUNC_TRACE("TimeSync_SessionInit called\n");¬
` ¬
` if (context) {¬
` /* assocate the new context with a path */¬
` status = SOS_Path_SessionContextPut(Path, context);¬
` } else {¬
` status = SOS_ErrorResourceAllocation;¬
` }¬

` return status;¬
`}¬

`/*++¬
`Routine Name:¬

` TimeSync_SessionUninit¬

`Routine Description:¬

` Called by Strings to free all memory assocated with this session¬
` of mp3decoder.¬

`Parameters:¬

` SOS_PATH *Path - [in]¬
` The path assocated with the mp3decoder to be destroyed.¬

`Return Value:¬
`
`Page 21 of 27
`
`Implicit Exhibit 2019
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/be…/…/main/timesync.c
`Page 22/27
`Saved: 10/23/01, 11:40:49 AM
`Printed for: Implicit
`
`924
`925
`926
`927
`928
`929
`930
`931
`932
`933
`934
`935
`936
`937
`938
`939
`940
`941
`942
`943
`944
`945
`946
`947
`948
`949
`950
`951
`952
`953
`954
`955
`956
`…
`957
`958
`…
`959
`960
`961
`962
`963
`964
`965
`966
`

` SOS_STATUS - ¬
` SOS_Success¬
` on successful uninit.¬

` SOS_Error¬
` if the context could not be retrieved.¬

`--*/¬
`static¬
`SOS_STATUS¬
`TimeSync_SessionUninit(¬
` SOS_PATH *Path¬
`)¬
`{¬
` SOS_STATUS status;¬
` UPDATE_CONTEXT *context;¬

` SOS_DEBUGOUT_FUNC_TRACE("TimeSync_SessionUninit called\n");¬

` /* find the session context assocated with this path */¬
` status = SOS_Path_SessionContextPeek(Path, (void**)&context);¬

` /* make sure we found a valid context */¬
` if (SOS_SUCCEEDED(status) && context) {¬
` // don't destroy it, it's global.¬
`// TimeSync_ContextDestroy(context);¬
` }¬

` return status;¬
`}¬

`/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`++++++¬
`Bead init and uninit¬
`+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`++++*/¬

`/*++¬
`Routine Name:¬

` TimeSync_BeadInit¬

`Routine Description:¬

`
`Page 22 of 27
`
`Implicit Exhibit 2019
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/be…/…/main/timesync.c
`Page 23/27
`Saved: 10/23/01, 11:40:49 AM
`Printed for: Implicit
`
`967
`968
`969
`970
`971
`972
`973
`974
`975
`976
`977
`978
`979
`980
`981
`982
`983
`984
`985
`986
`987
`988
`989
`990
`991
`992
`993
`994
`995
`996
`997
`998
`999
`1000
`1001
`1002
`1003
`1004
`1005
`1006
`1007
`1008
`1009
`1010
`1011
`
`Parameters:¬

` SOS_BEAD *Bead - [in]¬
` A reference to the timesync bead. We use this parameter to¬
` register edges assocated with the bead.¬

` SOS_REGOBJECT *InitContext - [in]¬
` Set to the value passed into the bead register function (NULL).¬

`Return Value:¬

` SOS_STATUS - ¬
` The return value of our call to SOS_Edge_Register.¬

`--*/¬
`static¬
`SOS_STATUS¬
`TimeSync_BeadInit(¬
` SOS_BEAD *Bead,¬
` SOS_REGOBJECT *InitContext¬
`)¬
`{¬
` SOS_STATUS status;¬

` SOS_DEBUGOUT_FUNC_TRACE("BeadInit called\n");¬
` /* register Sync Edge */¬
` status = SOS_Edge_Register(¬
` Bead,¬
` "Update",¬
` NULL,¬
` NULL,¬
` NULL,¬
` TimeSync_KeyCreate,¬
` TimeSync_UpdateHandler,¬
` NULL,¬
` NULL,¬
` NULL,¬
` NULL);¬

` if (SOS_FAILED(status)) {¬
` SOS_DEBUGOUT_MAJOR_EVENT( "Could not register Decode edge");¬
` }¬

` g_Context = TimeSync_ContextCreate();¬
` ¬
`
`Page 23 of 27
`
`Implicit Exhibit 2019
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/be…/…/main/timesync.c
`Page 24/27
`Saved: 10/23/01, 11:40:49 AM
`Printed for: Implicit
`
`1012
`1013
`1014
`1015
`1016
`1017
`1018
`1019
`1020
`1021
`1022
`1023
`1024
`1025
`1026
`1027
`1028
`1029
`1030
`1031
`1032
`1033
`1034
`1035
`1036
`1037
`1038
`1039
`1040
`1041
`1042
`1

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