`Page 1/25
`Saved: 10/23/01, 12:11:25 PM
`Printed for: Implicit
`
`/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`1
`++++++¬
`…
`¬2
`Copyright (c) 2001 BeComm Corporation¬
`3
`¬4
`Filename:¬
`5
`¬6
` clocksync.c¬
`7
`¬8
`Group Name:¬
`9
`¬10
` todo¬
`11
`¬12
`Group Overview:¬
`13
`¬14
` Used in conjunction with timesync.¬
`15
`¬16
` Used to propogate a master/render clock pair over¬
`17
` a network link.¬
`18
`¬19
` Passes the following elements:¬
`20
`- epoch from the master clock.¬
`21
`- frequency/divisor from the render clock. (NO LONGER REQUIRED,
`22
`REMOVED)¬
`…
`¬23
` This is enough to manage timed delivery of video.¬
`24
`¬25
` NOTE: Transports only in forward direction (currently) - updates to
`26
`the¬
`…
` render clock are not propogated backwards.¬
`27
`¬28
`Owner:¬
`29
`¬30
` Guy Carpenter (guyc) 16-Aug-2001¬
`31
`¬32
`-------------------------------------------------------------------------
`33
`----*/¬
`…
`#define SOS_DEBUG_ZONE "/beads/clocksync"¬
`34
`#include <sosstrings.h>¬
`35
`#include <sosmultimedia.h>¬
`36
`#include "timesync.h"¬
`37
`¬38
`SOS_SOURCE_VERSION("$Id: clocksync.c,v 1.11 2001/10/23 17:11:25 guyc Exp
`39
`$");¬
`…
`¬40
`
`Page 1 of 25
`
`Implicit Exhibit 2020
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/be…/…/main/clocksync.c
`Page 2/25
`Saved: 10/23/01, 12:11:25 PM
`Printed for: Implicit
`
`/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`41
`++++++¬
`…
`Named Constants¬
`42
`-------------------------------------------------------------------------
`43
`----*/¬
`…
`¬44
`/*¬
`45
` * Name of bead¬
`46
` */¬
`47
`static¬
`48
`const char BEAD_NAME[] = "clocksync";¬
`49
`const char LOOPBACK_CONTENTTYPE[] = "clocksync/loopback";¬
`50
`¬51
`#define TIMER_INTERVAL 4000¬
`52
`#define TIMER_INITIAL_DELAY 200¬
`53
`¬54
`/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`55
`++++++¬
`…
`Masks¬
`56
`-------------------------------------------------------------------------
`57
`----*/¬
`…
`¬58
`/*¬
`59
` * Order here is important: we use the bit¬
`60
` * positions to efficiently compute the length.¬
`61
` */¬
`62
`#define FLAG_MASTERSHIFT 16¬
`63
`#define FLAG_RENDERSHIFT 18¬
`64
`#define MASK_SIZE 3¬
`65
`#define MASK_LENGTH 0xFFFF¬
`66
`#define FLAG_MASTEREPOCH 1<<(FLAG_MASTERSHIFT)¬
`67
`#define FLAG_MASTERFREQ 1<<(FLAG_MASTERSHIFT+1)¬
`68
`#define FLAG_RENDEREPOCH 1<<(FLAG_RENDERSHIFT)¬
`69
`#define FLAG_RENDERFREQ 1<<(FLAG_RENDERSHIFT+1)¬
`70
`#define FLAG_LOOPBACKREQ 1<<20¬
`71
`#define FLAG_DONTFORWARD 1<<21¬
`72
`#define FLAG_UNCONDITIONAL_MASK (FLAG_LOOPBACKREQ | FLAG_DONTFORWARD)¬
`73
`#define CONSTANT_LENGTH 2 /* hostid and length+flags in 2x32 bits */¬
`74
`#define MAX_VARIABLE_LENGTH 6 /* up to 6 other 32-bit values */¬
`75
`¬76
`/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`77
`++++++¬
`…
`Structs¬
`78
`-------------------------------------------------------------------------
`79
`----*/¬
`…
`
`Page 2 of 25
`
`Implicit Exhibit 2020
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/be…/…/main/clocksync.c
`Page 3/25
`Saved: 10/23/01, 12:11:25 PM
`Printed for: Implicit
`
`¬80
`typedef struct STREAM_CONTEXT {¬
`81
` SOS_UINT32 HostId;¬
`82
` SOS_CLOCK_TICK StartTime;¬
`83
` SOS_ISAMPLECLOCK * IMasterClock;¬
`84
` SOS_ISAMPLECLOCK * IRenderClock;¬
`85
` SOS_TIMER_ID TimerId;¬
`86
` SOS_BOOLEAN RenderUpdate;¬
`87
` SOS_PATH * ReturnPath;¬
`88
`} STREAM_CONTEXT;¬
`89
`¬90
`/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`91
`++++++¬
`…
`Context create and destory¬
`92
`-------------------------------------------------------------------------
`93
`----*/¬
`…
`¬94
`/*++¬
`95
`Routine Name:¬
`96
`¬97
` ClockSync_ContextCreate¬
`98
`¬99
`Routine Description:¬
`100
`¬
`101
` Attempt to allocate a ClockSync session and all the resources it
`102
`requires.¬
`…
`¬
`103
`Parameters:¬
`104
`¬
`105
` None.¬
`106
`¬
`107
`Return Value:¬
`108
`¬
`109
` UPDATE_CONTEXT * - ¬
`110
` A valid pointer to a session context on success.¬
`111
`¬
`112
` A NULL pointer if an error occured.¬
`113
`¬
`114
`--*/¬
`115
`static¬
`116
`STREAM_CONTEXT *¬
`117
`ClockSync_ContextCreate(¬
`118
` void¬
`119
`)¬
`120
`{¬
`121
`
`Page 3 of 25
`
`Implicit Exhibit 2020
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/be…/…/main/clocksync.c
`Page 4/25
`Saved: 10/23/01, 12:11:25 PM
`Printed for: Implicit
`
`122
`123
`124
`125
`126
`127
`128
`129
`130
`131
`…
`132
`133
`134
`135
`136
`137
`138
`139
`140
`141
`142
`143
`144
`145
`146
`147
`148
`149
`150
`151
`…
`152
`153
`…
`154
`155
`156
`157
`158
`159
`160
`161
`162
`163
`
` STREAM_CONTEXT *context;¬
`¬
` SOS_DEBUGOUT_FUNC_TRACE("ClockSync_ContextCreate called\n");¬
`¬
` context = SOS_Mem_Alloc(sizeof(*context));¬
` if (context) {¬
` SOS_memset(context, 0, sizeof(*context));¬
` TimeSync_HostIdGet(&context->HostId);¬
` context->StartTime = SOS_Clock_TickGet();¬
`// context->RenderUpdate = SOS_True; // REVISIT - set via
`configuration¬
` ¬
` }¬
`¬
` return context;¬
`}¬
`¬
`void¬
`ClockSync_ContextDestroy(¬
` STREAM_CONTEXT * Context¬
`)¬
`{¬
` if (Context) {¬
` SOS_Interface_Release(Context->IMasterClock);¬
` SOS_Interface_Release(Context->IRenderClock);¬
` ¬
` SOS_Mem_Free(Context);¬
` }¬
`}¬
`¬
`/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`++++++¬
`Edge Handlers¬
`-------------------------------------------------------------------------
`----*/¬
`¬
`/*++¬
`Routine Name:¬
`¬
` ClockSync_KeyCreate¬
`¬
`Routine Description:¬
`¬
` Creates a new key for each session.¬
`¬
`
`Page 4 of 25
`
`Implicit Exhibit 2020
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/be…/…/main/clocksync.c
`Page 5/25
`Saved: 10/23/01, 12:11:25 PM
`Printed for: Implicit
`
`164
`165
`166
`167
`168
`169
`170
`171
`172
`173
`174
`175
`176
`177
`178
`179
`180
`181
`182
`183
`184
`185
`186
`187
`188
`189
`190
`191
`192
`193
`194
`195
`196
`197
`198
`199
`200
`201
`202
`203
`204
`205
`206
`207
`208
`
`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¬
`ClockSync_KeyCreate(¬
` SOS_PATH *Path,¬
` SOS_MESSAGE *Message¬
`)¬
`{¬
` static SOS_UINT32 s_UniqueId = 0;¬
` SOS_REGOBJECT* uniqueSessionKey;¬
` ¬
` uniqueSessionKey = SOS_UInt32_Create(s_UniqueId++);¬
` SOS_Path_SessionKeySet(Path, uniqueSessionKey);¬
` SOS_RegObject_Release(uniqueSessionKey);¬
`¬
` return SOS_PathBuild_Stop;¬
`}¬
`¬
`static¬
`SOS_ISAMPLECLOCK *¬
`FindClock(¬
` SOS_PATH * Path,¬
` const char * Name¬
`)¬
`{¬
` SOS_REGOBJECT *clock;¬
` SOS_ISAMPLECLOCK *iSampleClock = NULL;¬
` ¬
` if (SOS_SUCCEEDED(¬
` SOS_Path_AttributeGet(¬
` Path,¬
` Name,¬
`
`Page 5 of 25
`
`Implicit Exhibit 2020
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/be…/…/main/clocksync.c
`Page 6/25
`Saved: 10/23/01, 12:11:25 PM
`Printed for: Implicit
`
`209
`210
`211
`212
`213
`214
`215
`216
`217
`218
`219
`220
`221
`222
`223
`224
`225
`226
`227
`228
`229
`230
`231
`232
`233
`234
`235
`236
`237
`238
`239
`240
`241
`242
`243
`244
`245
`246
`247
`248
`249
`250
`251
`252
`253
`
` &clock))) {¬
` SOS_RegObject_InterfaceGet(¬
` clock,¬
` SOS_ISAMPLECLOCK_ID,¬
` (void**)&iSampleClock¬
` );¬
` SOS_RegObject_Release(clock);¬
` }¬
` return iSampleClock;¬
`}¬
`¬
`¬
`static¬
`SOS_UINT32¬
`ClockSync_LengthCompute(¬
` SOS_UINT32 Flags¬
`)¬
`{¬
` /*¬
` * We always send a hostid and length+flags¬
` */¬
` SOS_UINT32 length = 2;¬
` /*¬
` * Flags are structured such that the 64-bit¬
` * entries are in bit positions 0x0010 and 1000¬
` * and the 32-bit entries are in positions 0001 and 0100.¬
` * This means that we can compute the length by adding¬
` * 0011 + 1100>>2.¬
` */¬
` length += (Flags>>FLAG_MASTERSHIFT & MASK_SIZE) +¬
` (Flags>>FLAG_RENDERSHIFT & MASK_SIZE);¬
` return length;¬
`}¬
`¬
`¬
`static¬
`SOS_STATUS¬
`ClockSync_Encode(¬
` STREAM_CONTEXT * Context,¬
` SOS_MESSAGE * Message,¬
` SOS_UINT32 Flags¬
`)¬
`{¬
` SOS_STATUS status;¬
` SOS_UINT32 length = ClockSync_LengthCompute(Flags);¬
`
`Page 6 of 25
`
`Implicit Exhibit 2020
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/be…/…/main/clocksync.c
`Page 7/25
`Saved: 10/23/01, 12:11:25 PM
`Printed for: Implicit
`
`254
`255
`256
`257
`258
`259
`260
`261
`262
`263
`264
`265
`266
`267
`268
`269
`270
`271
`272
`273
`274
`275
`276
`277
`278
`279
`280
`281
`282
`283
`284
`285
`286
`287
`288
`289
`290
`291
`292
`293
`294
`295
`296
`297
`298
`
` SOS_UINT32 *header = SOS_Mem_Alloc(sizeof(SOS_UINT32)*length);¬
` SOS_UINT32 *ptr = header;¬
` SOS_UINT32 actualFlags = Flags & FLAG_UNCONDITIONAL_MASK;¬
` SOS_UINT32 actualLength = 0;¬
`¬
` if (header) {¬
` ptr++; /* later set to (SOS_HTOLEL((length-2) | Flags) */¬
` *ptr++ = SOS_HTOLEL(Context->HostId);¬
` ¬
` if (Flags & FLAG_MASTERFREQ) {¬
` SOS_UINT32 frequency, divisor;¬
`¬
` SOS_DEBUGOUT_DETAIL("Encoding master frequency\n");¬
`¬
` status = Context->IMasterClock->FrequencyGet(¬
` Context->IMasterClock,¬
` &frequency,¬
` &divisor¬
` );¬
` if (SOS_SUCCEEDED(status)) {¬
` *ptr++ = SOS_HTOLEL(frequency);¬
` *ptr++ = SOS_HTOLEL(divisor);¬
` actualFlags |= FLAG_MASTERFREQ;¬
` }¬
` }¬
`¬
` if (Flags & FLAG_MASTEREPOCH) {¬
` SOS_UINT32 epoch;¬
`¬
` SOS_DEBUGOUT_DETAIL("Encoding master epoch\n");¬
` ¬
` status = Context->IMasterClock->EpochGet(¬
` Context->IMasterClock,¬
` &epoch¬
` );¬
` if (SOS_SUCCEEDED(status)) {¬
` *ptr++ = SOS_HTOLEL(epoch);¬
` actualFlags |= FLAG_MASTEREPOCH;¬
` }¬
` ¬
` }¬
` ¬
` if (Flags & FLAG_RENDERFREQ) {¬
` SOS_UINT32 frequency, divisor;¬
`¬
`
`Page 7 of 25
`
`Implicit Exhibit 2020
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/be…/…/main/clocksync.c
`Page 8/25
`Saved: 10/23/01, 12:11:25 PM
`Printed for: Implicit
`
`299
`300
`301
`302
`303
`304
`305
`306
`307
`308
`309
`310
`311
`312
`313
`314
`315
`316
`317
`318
`319
`320
`321
`322
`323
`324
`325
`326
`327
`328
`329
`330
`331
`332
`333
`334
`335
`336
`337
`338
`339
`340
`341
`342
`343
`
` SOS_DEBUGOUT_DETAIL("Encoding render frequency\n");¬
` ¬
` status = Context->IRenderClock->FrequencyGet(¬
` Context->IRenderClock,¬
` &frequency,¬
` &divisor¬
` );¬
` if (SOS_SUCCEEDED(status)) {¬
` *ptr++ = SOS_HTOLEL(frequency);¬
` *ptr++ = SOS_HTOLEL(divisor);¬
` actualFlags |= FLAG_RENDERFREQ;¬
` }¬
` }¬
`¬
` if (Flags & FLAG_RENDEREPOCH) {¬
` SOS_UINT32 epoch;¬
`¬
` SOS_DEBUGOUT_DETAIL("Encoding render epoch\n");¬
`¬
` status = Context->IRenderClock->EpochGet(¬
` Context->IRenderClock,¬
` &epoch¬
` );¬
` if (SOS_SUCCEEDED(status)) {¬
` *ptr++ = SOS_HTOLEL(epoch);¬
` actualFlags |= FLAG_RENDEREPOCH;¬
` }¬
` }¬
`¬
` actualLength = ptr-header;¬
`¬
` SOS_ASSERT(¬
` (SOS_UINT32)actualLength<=length,¬
` "Error in header length computation"¬
` );¬
`¬
` header[0] = (SOS_HTOLEL(actualLength-2)) | actualFlags;¬
`¬
` status = SOS_Message_HeadDataPush(¬
` Message,¬
` header,¬
` actualLength * sizeof(SOS_UINT32),¬
` SOS_Mem_Free¬
` );¬
` } else {¬
`
`Page 8 of 25
`
`Implicit Exhibit 2020
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/be…/…/main/clocksync.c
`Page 9/25
`Saved: 10/23/01, 12:11:25 PM
`Printed for: Implicit
`
`344
`345
`346
`347
`348
`349
`350
`351
`352
`353
`354
`355
`356
`357
`358
`359
`360
`361
`362
`363
`364
`365
`366
`367
`368
`369
`370
`371
`372
`373
`374
`375
`376
`377
`378
`379
`380
`381
`382
`383
`384
`385
`386
`387
`388
`
` status = SOS_ErrorResourceAllocation;¬
` }¬
`¬
` return status;¬
`}¬
`¬
`¬
`static¬
`void¬
`ClockSync_LoopBack(¬
` void * Context¬
`)¬
`{¬
` SOS_MESSAGE *message;¬
` STREAM_CONTEXT *context = Context;¬
` SOS_DEBUGOUT_FUNC_TRACE("ClockSync_LoopBack\n");¬
`¬
` message = SOS_Message_Create();¬
`¬
` ClockSync_Encode(¬
` context,¬
` message,¬
` FLAG_RENDEREPOCH | FLAG_DONTFORWARD¬
` );¬
`¬
` SOS_DEBUGOUT_DETAIL("Sending loopback path data\n");¬
` SOS_Path_MessageSend(context->ReturnPath, message);¬
`}¬
`¬
`static¬
`SOS_STATUS¬
`ClockSync_Decode(¬
` STREAM_CONTEXT * Context,¬
` SOS_MESSAGE * Message,¬
` SOS_PATH * Path¬
`)¬
`{¬
` SOS_STATUS status = SOS_Success;¬
` SOS_UINT32 header1[CONSTANT_LENGTH];¬
` SOS_UINT32 header2[MAX_VARIABLE_LENGTH];¬
` SOS_UINT32 *ptr = header2;¬
` size_t bytesRemoved;¬
` SOS_UINT32 length;¬
` SOS_UINT32 flags;¬
` SOS_UINT32 hostId;¬
`
`Page 9 of 25
`
`Implicit Exhibit 2020
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/b…/…/main/clocksync.c
`Page 10/25
`Saved: 10/23/01, 12:11:25 PM
`Printed for: Implicit
`
`389
`390
`391
`392
`393
`394
`395
`396
`397
`398
`399
`400
`401
`402
`403
`404
`405
`406
`407
`408
`409
`410
`411
`412
`413
`414
`415
`416
`417
`418
`419
`420
`421
`422
`423
`424
`425
`426
`427
`428
`429
`430
`431
`432
`433
`
` SOS_UINT32 offset;¬
` SOS_BOOLEAN haveOffset = SOS_False;¬
`¬
` /* extract constant part of header */¬
`¬
` status = SOS_Message_HeadDataPop(¬
` Message,¬
` CONSTANT_LENGTH * sizeof(SOS_UINT32),¬
` header1,¬
` &bytesRemoved);¬
`¬
` SOS_ASSERT_SOFT_ERROR(¬
` bytesRemoved==CONSTANT_LENGTH*sizeof(SOS_UINT32),¬
` "Message does not contain enough data"¬
` );¬
`¬
` flags = SOS_LETOHL(header1[0]);¬
` hostId = SOS_LETOHL(header1[1]);¬
` length = flags & MASK_LENGTH;¬
`¬
` if (SOS_SUCCEEDED(TimeSync_OffsetGet(hostId, &offset))) {¬
` haveOffset = SOS_True;¬
` }¬
`¬
` SOS_ASSERT_SOFT_ERROR(¬
` length<=MAX_VARIABLE_LENGTH,¬
` "Length exceeded expected maximum"¬
` );¬
`¬
` /* recover constant part of header */¬
`¬
` SOS_Message_HeadDataPop(¬
` Message,¬
` length * sizeof(SOS_UINT32),¬
` header2,¬
` &bytesRemoved);¬
`¬
` SOS_ASSERT_SOFT_ERROR(¬
` bytesRemoved==length*sizeof(SOS_UINT32),¬
` "Message does not contain enough data"¬
` );¬
`¬
` /*¬
` * Extract those elements found in mask¬
` */¬
`
`Page 10 of 25
`
`Implicit Exhibit 2020
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/b…/…/main/clocksync.c
`Page 11/25
`Saved: 10/23/01, 12:11:25 PM
`Printed for: Implicit
`
`434
`435
`436
`437
`438
`439
`440
`441
`442
`443
`444
`445
`446
`447
`448
`449
`450
`451
`452
`453
`454
`455
`456
`457
`458
`459
`460
`461
`462
`463
`464
`…
`465
`466
`467
`468
`469
`470
`471
`472
`473
`474
`475
`476
`477
`
`¬
` /* master clock frequency */¬
`¬
` if (flags & FLAG_MASTERFREQ) {¬
` SOS_UINT32 frequency = SOS_LETOHL(*ptr++);¬
` SOS_UINT32 divisor = SOS_LETOHL(*ptr++);¬
`¬
` SOS_DEBUGOUT_DETAIL("ClockSync decoding master freq\n");¬
`¬
` status = Context->IMasterClock->FrequencySet(¬
` Context->IMasterClock,¬
` frequency,¬
` divisor¬
` );¬
`¬
` SOS_ASSERT_SOFT_ERROR(¬
` SOS_SUCCEEDED(status),¬
` "Error updating master clock frequency"¬
` );¬
` }¬
`¬
` /* master clock epoch */¬
`¬
` if (flags & FLAG_MASTEREPOCH) {¬
` SOS_UINT32 epoch = SOS_LETOHL(*ptr++);¬
`¬
` SOS_DEBUGOUT_DETAIL("ClockSync decoding master epoch\n");¬
` ¬
` if (haveOffset) {¬
` SOS_DEBUGOUT_DETAIL(¬
` "Remote master epoch=%lu corrected by offset of %ld to
`local master epoch=%lu\n",¬
` epoch,¬
` offset,¬
` epoch - offset);¬
` epoch -= offset;¬
` } else {¬
` SOS_DEBUGOUT_DETAIL(¬
` "No offset available - using session time as epoch\n"¬
` );¬
` epoch = Context->StartTime;¬
` }¬
`¬
` status = Context->IMasterClock->Update(¬
` Context->IMasterClock,¬
`
`Page 11 of 25
`
`Implicit Exhibit 2020
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/b…/…/main/clocksync.c
`Page 12/25
`Saved: 10/23/01, 12:11:25 PM
`Printed for: Implicit
`
`478
`479
`480
`481
`482
`483
`484
`485
`486
`487
`488
`489
`490
`491
`492
`493
`494
`…
`495
`496
`497
`498
`499
`500
`501
`502
`503
`504
`505
`506
`507
`508
`509
`510
`511
`512
`513
`514
`…
`515
`516
`517
`518
`519
`520
`
` epoch,¬
` 0¬
` );¬
`¬
` SOS_ASSERT_SOFT_ERROR(¬
` SOS_SUCCEEDED(status),¬
` "Error updating master clock"¬
` );¬
` }¬
`¬
` /* render clock frequency */¬
`¬
` if (flags & FLAG_RENDERFREQ) {¬
` SOS_UINT32 frequency = SOS_LETOHL(*ptr++);¬
` SOS_UINT32 divisor = SOS_LETOHL(*ptr++);¬
`¬
` SOS_DEBUGOUT_DETAIL("ClockSync decoding render frequency to clock
`%p\n",¬
` Context->IRenderClock->Interface.Object);¬
`¬
` status = Context->IRenderClock->FrequencySet(¬
` Context->IRenderClock,¬
` frequency,¬
` divisor¬
` );¬
`¬
` SOS_ASSERT_SOFT_ERROR(¬
` SOS_SUCCEEDED(status),¬
` "Error updating render clock frequency"¬
` );¬
` }¬
`¬
` /* render clock epoch */¬
`¬
` if (flags & FLAG_RENDEREPOCH) {¬
` SOS_UINT32 epoch = SOS_LETOHL(*ptr++);¬
`¬
` SOS_DEBUGOUT_DETAIL("ClockSync decoding render epoch remote %lu
`local %lu to clock %p\n",¬
` epoch,¬
` haveOffset ? (epoch - offset) : 0,¬
` Context->IRenderClock->Interface.Object);¬
` ¬
` if (haveOffset) {¬
` epoch -= offset;¬
`
`Page 12 of 25
`
`Implicit Exhibit 2020
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/b…/…/main/clocksync.c
`Page 13/25
`Saved: 10/23/01, 12:11:25 PM
`Printed for: Implicit
`
`521
`522
`523
`524
`525
`526
`527
`528
`529
`530
`531
`532
`533
`534
`535
`536
`537
`538
`539
`540
`541
`542
`543
`544
`545
`546
`547
`548
`549
`550
`551
`552
`553
`554
`555
`556
`557
`558
`559
`560
`561
`562
`563
`564
`565
`
` } else {¬
` epoch = Context->StartTime;¬
` }¬
`¬
` status = Context->IRenderClock->Update(¬
` Context->IRenderClock,¬
` epoch,¬
` 0¬
` );¬
` ¬
`¬
` SOS_ASSERT_SOFT_ERROR(¬
` SOS_SUCCEEDED(status),¬
` "Error updating render clock"¬
` );¬
` }¬
`¬
` if (flags & FLAG_LOOPBACKREQ) {¬
` ¬
` SOS_DEBUGOUT_DETAIL("ClockSync received loopback request\n");¬
`¬
` if (!Context->ReturnPath) {¬
` SOS_REGOBJECT *contentType =¬
` SOS_String_CreateFromString(LOOPBACK_CONTENTTYPE);¬
` Context->ReturnPath = SOS_Path_Create(Path);¬
` SOS_Path_AttributeSet(¬
` Context->ReturnPath,¬
` "Content-Type",¬
` contentType¬
` );¬
` SOS_RegObject_Release(contentType);¬
` }¬
` ClockSync_LoopBack(Context);¬
` }¬
`¬
` if (flags & FLAG_DONTFORWARD) {¬
` SOS_DEBUGOUT_DETAIL("ClockSync received dontforward request\n");¬
` /*¬
` * We return SOS_True to indicate the message should not¬
` * be forwarded.¬
` */¬
` status = SOS_True;¬
` }¬
`¬
`¬
`
`Page 13 of 25
`
`Implicit Exhibit 2020
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/b…/…/main/clocksync.c
`Page 14/25
`Saved: 10/23/01, 12:11:25 PM
`Printed for: Implicit
`
`566
`567
`568
`569
`570
`571
`572
`573
`574
`575
`576
`577
`578
`579
`580
`581
`582
`583
`584
`585
`586
`587
`588
`589
`590
`591
`592
`593
`594
`595
`596
`597
`598
`599
`600
`601
`602
`603
`604
`605
`606
`607
`608
`609
`610
`
` return status;¬
`}¬
`¬
`¬
`static¬
`SOS_STATUS¬
`ClockSync_EncodeHandler(¬
` SOS_PATH *Path,¬
` SOS_MESSAGE *Message¬
`)¬
`{¬
` SOS_STATUS status = SOS_Success;¬
` STREAM_CONTEXT * context;¬
`¬
` status = SOS_Path_SessionContextPeek(Path, (void**)&context);¬
`¬
` SOS_DEBUGOUT_FUNC_TRACE("ClockSync_EncodeHandler\n");¬
`¬
` status = ClockSync_Encode(¬
` context,¬
` Message,¬
` (context->IMasterClock ? FLAG_MASTEREPOCH : 0)¬
` );¬
` ¬
` ¬
` if (SOS_SUCCEEDED(status)) {¬
` status = SOS_Path_MessageSend(¬
` Path,¬
` Message¬
` );¬
` } else {¬
` /* some sort of error prevented message from being sent */¬
` SOS_Message_Destroy(Message);¬
` }¬
` ¬
` return status;¬
`}¬
`¬
`static¬
`SOS_STATUS¬
`ClockSync_DecodeHandler(¬
` SOS_PATH *Path,¬
` SOS_MESSAGE *Message¬
`)¬
`{¬
`
`Page 14 of 25
`
`Implicit Exhibit 2020
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/b…/…/main/clocksync.c
`Page 15/25
`Saved: 10/23/01, 12:11:25 PM
`Printed for: Implicit
`
`611
`612
`613
`614
`615
`616
`617
`618
`619
`620
`621
`622
`623
`624
`625
`626
`627
`628
`629
`630
`631
`632
`633
`634
`635
`636
`637
`638
`639
`640
`641
`642
`643
`644
`645
`646
`647
`648
`649
`650
`651
`652
`653
`654
`655
`
` SOS_STATUS status = SOS_Success;¬
` STREAM_CONTEXT * context;¬
`¬
` status = SOS_Path_SessionContextPeek(Path, (void**)&context);¬
`¬
` SOS_DEBUGOUT_FUNC_TRACE("ClockSync_DecodeHandler\n");¬
`¬
` status = ClockSync_Decode(¬
` context,¬
` Message,¬
` Path¬
` );¬
` ¬
` if (status == SOS_Success) {¬
` status = SOS_Path_MessageSend(Path, Message);¬
` } else if (status == SOS_True) {¬
` /* we aren't forwarding the message, but everything is good */¬
` SOS_Message_Destroy(Message);¬
` status = SOS_Success;¬
` } else {¬
` SOS_Message_Destroy(Message);¬
` }¬
` ¬
` return status;¬
`}¬
`¬
`static¬
`SOS_STATUS¬
`ClockSync_MasterEncodeHandler(¬
` SOS_PATH *Path,¬
` SOS_MESSAGE *Message¬
`)¬
`{¬
` SOS_STATUS status = SOS_Success;¬
` STREAM_CONTEXT * context;¬
`¬
` status = SOS_Path_SessionContextPeek(Path, (void**)&context);¬
`¬
` SOS_DEBUGOUT_FUNC_TRACE("ClockSync_MasterEncodeHandler\n");¬
`¬
` if (!context->IMasterClock) {¬
` context->IMasterClock = FindClock(¬
` Path,¬
` SOS_MASTERCLOCK_NAME);¬
` }¬
`
`Page 15 of 25
`
`Implicit Exhibit 2020
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/b…/…/main/clocksync.c
`Page 16/25
`Saved: 10/23/01, 12:11:25 PM
`Printed for: Implicit
`
`656
`657
`658
`659
`660
`661
`662
`663
`664
`665
`666
`667
`668
`669
`670
`671
`672
`673
`674
`675
`676
`677
`678
`679
`680
`681
`682
`683
`…
`684
`685
`…
`686
`687
`688
`689
`690
`691
`692
`693
`694
`695
`696
`697
`698
`
`¬
` if (!context->IRenderClock) {¬
` context->IRenderClock = FindClock(¬
` Path,¬
` SOS_RENDERCLOCK_NAME);¬
` }¬
`¬
` status = ClockSync_Encode(¬
` context,¬
` Message,¬
` FLAG_LOOPBACKREQ | (context->IMasterClock ? FLAG_MASTEREPOCH : 0)¬
` );¬
` ¬
` ¬
` if (SOS_SUCCEEDED(status)) {¬
` status = SOS_Path_MessageSend(¬
` Path,¬
` Message¬
` );¬
` } else {¬
` /* some sort of error prevented message from being sent */¬
` SOS_Message_Destroy(Message);¬
` }¬
` ¬
` return status;¬
`}¬
`¬
`/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`++++++¬
`Timer¬
`+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`++++*/¬
`¬
`#if 0¬
`¬
`static¬
`SOS_STATUS¬
`ClockSync_TimerStart(¬
` STREAM_CONTEXT * Context¬
`)¬
`{¬
` SOS_STATUS status;¬
`¬
` status = SOS_Timer_PeriodicSchedule(¬
` TIMER_INITIAL_DELAY,¬
`
`Page 16 of 25
`
`Implicit Exhibit 2020
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/b…/…/main/clocksync.c
`Page 17/25
`Saved: 10/23/01, 12:11:25 PM
`Printed for: Implicit
`
`699
`700
`701
`702
`703
`704
`705
`706
`707
`708
`709
`710
`711
`712
`713
`714
`715
`716
`717
`718
`719
`720
`721
`722
`723
`…
`724
`725
`…
`726
`727
`728
`729
`730
`731
`732
`733
`734
`735
`736
`737
`738
`739
`740
`741
`
` TIMER_INTERVAL,¬
` ClockSync_LoopBack,¬
` Context,¬
` &Context->TimerId¬
` );¬
`¬
` return status;¬
`}¬
`¬
`static¬
`SOS_STATUS¬
`ClockSync_TimerStop(¬
` STREAM_CONTEXT * Context¬
`)¬
`{¬
` SOS_STATUS status;¬
`¬
` status = SOS_Timer_Cancel(Context->TimerId);¬
`¬
` return status;¬
`}¬
`¬
`#endif¬
`¬
`/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`++++++¬
`Session init and uninit¬
`+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`++++*/¬
`¬
`/*++¬
`Routine Name:¬
`¬
` ClockSync_SessionInit¬
`¬
`Routine Description:¬
`¬
` Called by Strings when ClockSync_KeyCreate returns that a new¬
` ClockSync 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 bead to be created.¬
`
`Page 17 of 25
`
`Implicit Exhibit 2020
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/b…/…/main/clocksync.c
`Page 18/25
`Saved: 10/23/01, 12:11:25 PM
`Printed for: Implicit
`
`742
`743
`744
`745
`746
`747
`748
`749
`750
`751
`752
`753
`754
`755
`756
`757
`758
`759
`760
`761
`762
`763
`764
`765
`766
`767
`768
`769
`770
`771
`772
`773
`774
`775
`776
`777
`778
`779
`780
`781
`782
`783
`784
`785
`786
`
`¬
`Return Value:¬
`¬
` SOS_STATUS - ¬
` SOS_Success if a context was created and succesfully assocated¬
` with a path.¬
`¬
` SOS_Error otherwise.¬
`¬
`--*/¬
`static¬
`SOS_STATUS¬
`ClockSync_SessionInit(¬
` SOS_PATH *Path¬
`)¬
`{¬
` SOS_STATUS status = SOS_Success;¬
` STREAM_CONTEXT *context = ClockSync_ContextCreate();¬
`¬
` SOS_DEBUGOUT_FUNC_TRACE("ClockSync_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:¬
`¬
` ClockSync_SessionUninit¬
`¬
`Routine Description:¬
`¬
` Called by Strings to free all memory assocated with this session.¬
`¬
`Parameters:¬
`¬
` SOS_PATH *Path - [in]¬
` The path assocated with the session to be destroyed.¬
`¬
`Return Value:¬
`
`Page 18 of 25
`
`Implicit Exhibit 2020
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/b…/…/main/clocksync.c
`Page 19/25
`Saved: 10/23/01, 12:11:25 PM
`Printed for: Implicit
`
`787
`788
`789
`790
`791
`792
`793
`794
`795
`796
`797
`798
`799
`800
`801
`802
`803
`804
`805
`806
`807
`808
`809
`810
`811
`812
`813
`814
`815
`816
`817
`818
`819
`820
`821
`822
`823
`824
`825
`826
`827
`828
`829
`830
`831
`
`¬
` SOS_STATUS - ¬
` SOS_Success¬
` on successful uninit.¬
`¬
` SOS_Error¬
` if the context could not be retrieved.¬
`¬
`--*/¬
`static¬
`SOS_STATUS¬
`ClockSync_SessionUninit(¬
` SOS_PATH *Path¬
`)¬
`{¬
` SOS_STATUS status;¬
` STREAM_CONTEXT *context;¬
`¬
` SOS_DEBUGOUT_FUNC_TRACE("ClockSync_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) {¬
` ClockSync_ContextDestroy(context);¬
` }¬
`¬
` return status;¬
`}¬
`¬
`static¬
`SOS_STATUS¬
`ClockSync_PathInit(¬
` SOS_PATH * Path¬
`)¬
`{¬
` SOS_STATUS status = SOS_Success;¬
` STREAM_CONTEXT *context;¬
`¬
` status = SOS_Path_SessionContextPeek(Path, (void**)&context);¬
`¬
` /* PathInit is called after the context is created in SessionInit */¬
` ¬
` if (context) {¬
`
`Page 19 of 25
`
`Implicit Exhibit 2020
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/b…/…/main/clocksync.c
`Page 20/25
`Saved: 10/23/01, 12:11:25 PM
`Printed for: Implicit
`
`832
`833
`834
`835
`836
`837
`838
`839
`840
`841
`842
`843
`844
`845
`846
`847
`848
`849
`850
`851
`…
`852
`853
`…
`854
`855
`856
`857
`858
`859
`860
`861
`862
`863
`864
`865
`866
`867
`868
`869
`870
`871
`872
`873
`874
`
`¬
` if (!context->IMasterClock || !context->IRenderClock) {¬
` context->IMasterClock = FindClock(¬
` Path,¬
` SOS_MASTERCLOCK_NAME);¬
` ¬
` context->IRenderClock = FindClock(¬
` Path,¬
` SOS_RENDERCLOCK_NAME);¬
`¬
` if (!context->IMasterClock || !context->IRenderClock) {¬
` status = SOS_Error;¬
` }¬
` }¬
` }¬
`¬
` return status;¬
`}¬
`¬
`/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`++++++¬
`Bead init and uninit¬
`+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`++++*/¬
`¬
`/*++¬
`Routine Name:¬
`¬
` ClockSync_BeadInit¬
`¬
`Routine Description:¬
`¬
`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.¬
`
`Page 20 of 25
`
`Implicit Exhibit 2020
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/b…/…/main/clocksync.c
`Page 21/25
`Saved: 10/23/01, 12:11:25 PM
`Printed for: Implicit
`
`875
`876
`877
`878
`879
`880
`881
`882
`883
`884
`885
`886
`887
`888
`889
`890
`891
`892
`893
`894
`895
`896
`897
`898
`899
`900
`901
`902
`903
`904
`905
`906
`907
`908
`909
`910
`911
`912
`913
`914
`915
`916
`917
`918
`919
`
`¬
`--*/¬
`static¬
`SOS_STATUS¬
`ClockSync_BeadInit(¬
` SOS_BEAD *Bead,¬
` SOS_REGOBJECT *InitContext¬
`)¬
`{¬
` SOS_STATUS status;¬
`¬
` SOS_DEBUGOUT_FUNC_TRACE("BeadInit called\n");¬
`¬
` status = SOS_Edge_Register(¬
` Bead,¬
` "Encode",¬
` NULL,¬
` NULL,¬
` NULL,¬
` ClockSync_KeyCreate,¬
` ClockSync_EncodeHandler,¬
` NULL,¬
` NULL,¬
` ClockSync_PathInit,¬
` NULL);¬
`¬
` if (SOS_FAILED(status)) {¬
` SOS_DEBUGOUT_MAJOR_EVENT( "Could not register edge");¬
` }¬
`¬
` status = SOS_Edge_Register(¬
` Bead,¬
` "Decode",¬
` NULL,¬
` NULL,¬
` NULL,¬
` ClockSync_KeyCreate,¬
` ClockSync_DecodeHandler,¬
` NULL,¬
` NULL,¬
` ClockSync_PathInit,¬
` NULL);¬
`¬
` if (SOS_FAILED(status)) {¬
` SOS_DEBUGOUT_MAJOR_EVENT( "Could not register edge");¬
`
`Page 21 of 25
`
`Implicit Exhibit 2020
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/b…/…/main/clocksync.c
`Page 22/25
`Saved: 10/23/01, 12:11:25 PM
`Printed for: Implicit
`
`920
`921
`922
`923
`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
`
` }¬
`¬
` status = SOS_Edge_Register(¬
` Bead,¬
` "MasterEncode",¬
` NULL,¬
` NULL,¬
` NULL,¬
` ClockSync_KeyCreate,¬
` ClockSync_MasterEncodeHandler,¬
` NULL,¬
` NULL,¬
` NULL,¬
` NULL);¬
`¬
` if (SOS_FAILED(status)) {¬
` SOS_DEBUGOUT_MAJOR_EVENT( "Could not register edge");¬
` }¬
`¬
` status = SOS_Bead_SchemaSet(Bead, "clocksync");¬
`¬
` if (SOS_FAILED(status)) {¬
` SOS_DEBUGOUT_MAJOR_EVENT( "Could not set bead schema");¬
` }¬
` ¬
` return status;¬
`}¬
`¬
`/*++¬
`Routine Name:¬
`¬
` ClockSync_BeadUninit¬
`¬
`Routine Description:¬
`¬
` Called when Strings attempts to unload the Bead.¬
`¬
`Parameters:¬
`¬
` void *BeadContext - [in]¬
` NULL because SOS_Bead_ContextPut is never called by this bead.¬
`¬
`Return Value:¬
`¬
` SOS_STATUS - ¬
`
`Page 22 of 25
`
`Implicit Exhibit 2020
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/b…/…/main/clocksync.c
`Page 23/25
`Saved: 10/23/01, 12:11:25 PM
`Printed for: Implicit
`
`965
`966
`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
`
` Always SOS_Success¬
`¬
`--*/¬
`static¬
`SOS_STATUS¬
`ClockSync_BeadUninit(¬
` void *BeadContext¬
`)¬
`{¬
` SOS_DEBUGOUT_FUNC_TRACE("BeadUninit called\n");¬
` ¬
` return SOS_Success;¬
`}¬
`¬
`/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`++++++¬
`Module init and uninit¬
`+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`++++*/¬
`¬
`/*+¬
`Routine Name:¬
`¬
` SOS_ModuleInit¬
`¬
`Routine Description:¬
`¬
` Called by Strings when this object file is loade