/* add or update an entry in the foreign master data set */ MsgSync * addForeign(Octet *buf, MsgHeader *header, PtpClock *ptpClock) { int i, j; Boolean found = FALSE; DBGV("updateForeign\n"); j = ptpClock->foreign_record_best; for(i = 0; i < ptpClock->number_foreign_records; ++i) { if(header->sourceCommunicationTechnology == ptpClock->foreign[j].foreign_master_communication_technology && header->sourcePortId == ptpClock->foreign[j].foreign_master_port_id && !memcmp(header->sourceUuid, ptpClock->foreign[j].foreign_master_uuid, PTP_UUID_LENGTH)) { ++ptpClock->foreign[j].foreign_master_syncs; found = TRUE; DBGV("updateForeign: update record %d\n", j); break; } j = (j + 1)%ptpClock->number_foreign_records; } if(!found) { if(ptpClock->number_foreign_records < ptpClock->max_foreign_records) ++ptpClock->number_foreign_records; j = ptpClock->foreign_record_i; ptpClock->foreign[j].foreign_master_communication_technology = header->sourceCommunicationTechnology; ptpClock->foreign[j].foreign_master_port_id = header->sourcePortId; memcpy(ptpClock->foreign[j].foreign_master_uuid, header->sourceUuid, PTP_UUID_LENGTH); DBG("updateForeign: new record (%d,%d) %d %d %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx\n", ptpClock->foreign_record_i, ptpClock->number_foreign_records, ptpClock->foreign[j].foreign_master_communication_technology, ptpClock->foreign[j].foreign_master_port_id, ptpClock->foreign[j].foreign_master_uuid[0], ptpClock->foreign[j].foreign_master_uuid[1], ptpClock->foreign[j].foreign_master_uuid[2], ptpClock->foreign[j].foreign_master_uuid[3], ptpClock->foreign[j].foreign_master_uuid[4], ptpClock->foreign[j].foreign_master_uuid[5]); ptpClock->foreign_record_i = (ptpClock->foreign_record_i + 1)%ptpClock->max_foreign_records; } msgUnpackHeader(buf, &ptpClock->foreign[j].header); msgUnpackSync(buf, &ptpClock->foreign[j].sync); return &ptpClock->foreign[j].sync; }
static void handleSync(PtpClock *ptpClock, TimeInternal *time, Boolean isFromSelf) { TimeInternal originTimestamp; TimeInternal correctionField; Boolean isFromCurrentParent = FALSE; DBGV("handleSync: received\n"); if (ptpClock->msgIbufLength < SYNC_LENGTH) { ERROR("handleSync: short message\n"); toState(ptpClock, PTP_FAULTY); return; } switch (ptpClock->portDS.portState) { case PTP_INITIALIZING: case PTP_FAULTY: case PTP_DISABLED: DBGV("handleSync: disreguard\n"); break; case PTP_UNCALIBRATED: case PTP_SLAVE: if (isFromSelf) { DBGV("handleSync: ignore from self\n"); break; } isFromCurrentParent = isSamePortIdentity( &ptpClock->parentDS.parentPortIdentity, &ptpClock->msgTmpHeader.sourcePortIdentity); if (!isFromCurrentParent) { DBGV("handleSync: ignore from another master\n"); break; } ptpClock->timestamp_syncRecieve = *time; scaledNanosecondsToInternalTime(&ptpClock->msgTmpHeader.correctionfield, &correctionField); if (getFlag(ptpClock->msgTmpHeader.flagField[0], FLAG0_TWO_STEP)) { ptpClock->waitingForFollowUp = TRUE; ptpClock->recvSyncSequenceId = ptpClock->msgTmpHeader.sequenceId; /* Save correctionField of Sync message for future use */ ptpClock->correctionField_sync = correctionField; } else { msgUnpackSync(ptpClock->msgIbuf, &ptpClock->msgTmp.sync); ptpClock->waitingForFollowUp = FALSE; /* Synchronize local clock */ toInternalTime(&originTimestamp, &ptpClock->msgTmp.sync.originTimestamp); /* use correctionField of Sync message for future use */ updateOffset(ptpClock, &ptpClock->timestamp_syncRecieve, &originTimestamp, &correctionField); updateClock(ptpClock); issueDelayReqTimerExpired(ptpClock); } break; case PTP_MASTER: if (!isFromSelf) { DBGV("handleSync: from another master\n"); break; } else { DBGV("handleSync: ignore from self\n"); break; } // if waitingForLoopback && TWO_STEP_FLAG // { // /*Add latency*/ // addTime(time, time, &rtOpts->outboundLatency); // // issueFollowup(ptpClock, time); // break; // } case PTP_PASSIVE: issueDelayReqTimerExpired(ptpClock); DBGV("handleSync: disreguard\n"); break; default: DBGV("handleSync: disreguard\n"); break; } }
void handleSync(MsgHeader *header, Octet *msgIbuf, ssize_t length, TimeInternal *time, Boolean isFromSelf, RunTimeOpts *rtOpts, PtpClock *ptpClock) { TimeInternal OriginTimestamp; TimeInternal correctionField; Boolean isFromCurrentParent = FALSE; DBGV("Sync message received : \n"); if (length < SYNC_LENGTH) { ERROR("short Sync message\n"); toState(PTP_FAULTY, rtOpts, ptpClock); return; } switch (ptpClock->portState) { case PTP_INITIALIZING: case PTP_FAULTY: case PTP_DISABLED: DBGV("HandleSync : disregard\n"); return; case PTP_UNCALIBRATED: case PTP_SLAVE: if (isFromSelf) { DBGV("HandleSync: Ignore message from self \n"); return; } isFromCurrentParent = !memcmp(ptpClock->parentPortIdentity.clockIdentity, header->sourcePortIdentity.clockIdentity, CLOCK_IDENTITY_LENGTH) && (ptpClock->parentPortIdentity.portNumber == header->sourcePortIdentity.portNumber); if (isFromCurrentParent) { /* We only start our own delayReq timer after receiving the first sync */ if (ptpClock->waiting_for_first_sync) { ptpClock->waiting_for_first_sync = FALSE; NOTICE("Received first Sync from Master\n"); NOTICE(" going to arm DelayReq timer for the first time, with initial rate: %d\n", ptpClock->logMinDelayReqInterval ); if (ptpClock->delayMechanism == E2E) timerStart(DELAYREQ_INTERVAL_TIMER, pow(2,ptpClock->logMinDelayReqInterval), ptpClock->itimer); else if (ptpClock->delayMechanism == P2P) timerStart(PDELAYREQ_INTERVAL_TIMER, pow(2,ptpClock->logMinPdelayReqInterval), ptpClock->itimer); } ptpClock->sync_receive_time.seconds = time->seconds; ptpClock->sync_receive_time.nanoseconds = time->nanoseconds; recordSync(rtOpts, header->sequenceId, time); if ((header->flagField[0] & PTP_TWO_STEP) == PTP_TWO_STEP) { DBG2("HandleSync: waiting for follow-up \n"); ptpClock->waitingForFollow = TRUE; ptpClock->recvSyncSequenceId = header->sequenceId; /*Save correctionField of Sync message*/ integer64_to_internalTime( header->correctionfield, &correctionField); ptpClock->lastSyncCorrectionField.seconds = correctionField.seconds; ptpClock->lastSyncCorrectionField.nanoseconds = correctionField.nanoseconds; break; } else { msgUnpackSync(ptpClock->msgIbuf, &ptpClock->msgTmp.sync); integer64_to_internalTime( ptpClock->msgTmpHeader.correctionfield, &correctionField); timeInternal_display(&correctionField); ptpClock->waitingForFollow = FALSE; toInternalTime(&OriginTimestamp, &ptpClock->msgTmp.sync.originTimestamp); updateOffset(&OriginTimestamp, &ptpClock->sync_receive_time, &ptpClock->ofm_filt,rtOpts, ptpClock,&correctionField); updateClock(rtOpts,ptpClock); break; } } else { DBG("HandleSync: Sync message received from " "another Master not our own \n"); } break; case PTP_MASTER: default : if (!isFromSelf) { DBGV("HandleSync: Sync message received from " "another Master \n"); break; } if (ptpClock->twoStepFlag) { DBGV("HandleSync: going to send followup message\n "); /*Add latency*/ addTime(time,time,&rtOpts->outboundLatency); issueFollowup(time,rtOpts,ptpClock); break; } else { DBGV("HandleSync: Sync message received from self\n "); } } }