void issueDelayReq(PtpClock *ptpClock) { TimeInternal internalTime; TimeRepresentation originTimestamp; ptpClock->sentDelayReq = TRUE; ptpClock->sentDelayReqSequenceId = ++ptpClock->last_sync_event_sequence_number; /* try to predict outgoing time stamp */ getTime(&internalTime, ptpClock); fromInternalTime(&internalTime, &originTimestamp, ptpClock->halfEpoch); msgPackDelayReq(ptpClock->msgObuf, FALSE, FALSE, &originTimestamp, ptpClock); if(!netSendEvent(ptpClock->msgObuf, DELAY_REQ_PACKET_LENGTH, ptpClock->delayedTiming ? &internalTime : NULL, ptpClock)) toState(PTP_FAULTY, ptpClock); else { DBGV("sent delay request message\n"); if(ptpClock->delayedTiming) { if (internalTime.seconds || internalTime.nanoseconds) { /* compensate with configurable latency, then store for later use */ addTime(&internalTime, &internalTime, &ptpClock->runTimeOpts.outboundLatency); ptpClock->delay_req_send_time = internalTime; } else { NOTIFY("WARNING: delay request message without hardware time stamp, will skip response\n"); ptpClock->sentDelayReq = FALSE; } } } }
/* pack and send various messages */ void issueSync(PtpClock *ptpClock) { TimeInternal internalTime; TimeRepresentation originTimestamp; ++ptpClock->last_sync_event_sequence_number; ptpClock->grandmaster_sequence_number = ptpClock->last_sync_event_sequence_number; /* try to predict outgoing time stamp */ getTime(&internalTime, ptpClock); fromInternalTime(&internalTime, &originTimestamp, ptpClock->halfEpoch); msgPackSync(ptpClock->msgObuf, FALSE, TRUE, &originTimestamp, ptpClock); if(!netSendEvent(ptpClock->msgObuf, SYNC_PACKET_LENGTH, ptpClock->delayedTiming ? &internalTime : NULL, ptpClock)) toState(PTP_FAULTY, ptpClock); else { DBGV("sent sync message\n"); if(ptpClock->delayedTiming) { if (internalTime.seconds || internalTime.nanoseconds) { /* compensate with configurable latency, then tell client real time stamp */ addTime(&internalTime, &internalTime, &ptpClock->runTimeOpts.outboundLatency); issueFollowup(&internalTime, ptpClock); } else { NOTIFY("WARNING: sync message without hardware time stamp, skipped followup\n"); } } } }
/*Pack and send on event multicast ip adress a PDelayReq message*/ static void issuePDelayReq(PtpClock *ptpClock) { Timestamp originTimestamp; TimeInternal internalTime; getTime(&internalTime); fromInternalTime(&internalTime, &originTimestamp); msgPackPDelayReq(ptpClock, ptpClock->msgObuf, &originTimestamp); if (!netSendPeerEvent(&ptpClock->netPath, ptpClock->msgObuf, PDELAY_REQ_LENGTH, &internalTime)) { ERROR("issuePDelayReq: can't sent\n"); toState(ptpClock, PTP_FAULTY); } else { DBGV("issuePDelayReq\n"); ptpClock->sentPDelayReqSequenceId++; /* Delay req TX timestamp is valid */ if (internalTime.seconds != 0) { addTime(&internalTime, &internalTime, &ptpClock->outboundLatency); ptpClock->pdelay_t1 = internalTime; } } }
/*Pack and send on event multicast ip adress a Sync message*/ static void issueSync(PtpClock *ptpClock) { Timestamp originTimestamp; TimeInternal internalTime; /* try to predict outgoing time stamp */ getTime(&internalTime); fromInternalTime(&internalTime, &originTimestamp); msgPackSync(ptpClock, ptpClock->msgObuf, &originTimestamp); if (!netSendEvent(&ptpClock->netPath, ptpClock->msgObuf, SYNC_LENGTH, &internalTime)) { ERROR("issueSync: can't sent\n"); toState(ptpClock, PTP_FAULTY); } else { DBGV("issueSync\n"); ptpClock->sentSyncSequenceId++; /* sync TX timestamp is valid */ if ((internalTime.seconds != 0) && (ptpClock->defaultDS.twoStepFlag)) { // waitingForLoopback = false; addTime(&internalTime, &internalTime, &ptpClock->outboundLatency); issueFollowup(ptpClock, &internalTime); } else { // waitingForLoopback = ptpClock->twoStepFlag; } } }
void issueDelayResp(TimeInternal *time, MsgHeader *header, PtpClock *ptpClock) { TimeRepresentation delayReceiptTimestamp; ++ptpClock->last_general_event_sequence_number; fromInternalTime(time, &delayReceiptTimestamp, ptpClock->halfEpoch); msgPackDelayResp(ptpClock->msgObuf, header, &delayReceiptTimestamp, ptpClock); if(!netSendGeneral(ptpClock->msgObuf, DELAY_RESP_PACKET_LENGTH, ptpClock)) toState(PTP_FAULTY, ptpClock); else DBGV("sent delay response message\n"); }
void issueFollowup(TimeInternal *time, PtpClock *ptpClock) { TimeRepresentation preciseOriginTimestamp; ++ptpClock->last_general_event_sequence_number; fromInternalTime(time, &preciseOriginTimestamp, ptpClock->halfEpoch); msgPackFollowUp(ptpClock->msgObuf, ptpClock->last_sync_event_sequence_number, &preciseOriginTimestamp, ptpClock); if(!netSendGeneral(ptpClock->msgObuf, FOLLOW_UP_PACKET_LENGTH, ptpClock)) toState(PTP_FAULTY, ptpClock); else DBGV("sent followup message\n"); }
/*Pack and send on event multicast ip adress a DelayResp message*/ static void issueDelayResp(PtpClock *ptpClock, const TimeInternal *time, const MsgHeader * delayReqHeader) { Timestamp requestReceiptTimestamp; fromInternalTime(time, &requestReceiptTimestamp); msgPackDelayResp(ptpClock, ptpClock->msgObuf, delayReqHeader, &requestReceiptTimestamp); if (!netSendGeneral(&ptpClock->netPath, ptpClock->msgObuf, PDELAY_RESP_LENGTH)) { ERROR("issueDelayResp: can't sent\n"); toState(ptpClock, PTP_FAULTY); } else { DBGV("issueDelayResp\n"); } }
/*Pack and send on general multicast ip adress a FollowUp message*/ void issueFollowup(TimeInternal *time,RunTimeOpts *rtOpts,PtpClock *ptpClock) { Timestamp preciseOriginTimestamp; fromInternalTime(time,&preciseOriginTimestamp); msgPackFollowUp(ptpClock->msgObuf,&preciseOriginTimestamp,ptpClock); if (!netSendGeneral(ptpClock->msgObuf,FOLLOW_UP_LENGTH, &ptpClock->netPath, 0)) { toState(PTP_FAULTY,rtOpts,ptpClock); DBGV("FollowUp message can't be sent -> FAULTY state \n"); } else { DBGV("FollowUp MSG sent ! \n"); } }
void issueDelayReq(RunTimeOpts *rtOpts, PtpClock *ptpClock) { TimeInternal internalTime; TimeRepresentation originTimestamp; ptpClock->sentDelayReq = TRUE; ptpClock->sentDelayReqSequenceId = ++ptpClock->last_sync_event_sequence_number; getTime(&internalTime); fromInternalTime(&internalTime, &originTimestamp, ptpClock->halfEpoch); msgPackDelayReq(ptpClock->msgObuf, FALSE, &originTimestamp, ptpClock); if(!netSendEvent(ptpClock->msgObuf, DELAY_REQ_PACKET_LENGTH, &ptpClock->netPath)) toState(PTP_FAULTY, rtOpts, ptpClock); else DBGV("sent delay request message\n"); }
/* pack and send various messages */ void issueSync(RunTimeOpts *rtOpts, PtpClock *ptpClock) { TimeInternal internalTime; TimeRepresentation originTimestamp; ++ptpClock->last_sync_event_sequence_number; ptpClock->grandmaster_sequence_number = ptpClock->last_sync_event_sequence_number; getTime(&internalTime); fromInternalTime(&internalTime, &originTimestamp, ptpClock->halfEpoch); msgPackSync(ptpClock->msgObuf, FALSE, &originTimestamp, ptpClock); if(!netSendEvent(ptpClock->msgObuf, SYNC_PACKET_LENGTH, &ptpClock->netPath)) toState(PTP_FAULTY, rtOpts, ptpClock); else DBGV("sent sync message\n"); }
static void issuePDelayRespFollowUp(PtpClock *ptpClock, const TimeInternal *time, const MsgHeader * pDelayReqHeader) { Timestamp responseOriginTimestamp; fromInternalTime(time, &responseOriginTimestamp); msgPackPDelayRespFollowUp(ptpClock->msgObuf, pDelayReqHeader, &responseOriginTimestamp); if (!netSendPeerGeneral(&ptpClock->netPath, ptpClock->msgObuf, PDELAY_RESP_FOLLOW_UP_LENGTH)) { ERROR("issuePDelayRespFollowUp: can't sent\n"); toState(ptpClock, PTP_FAULTY); } else { DBGV("issuePDelayRespFollowUp\n"); } }
/*Pack and send on general multicast ip adress a FollowUp message*/ static void issueFollowup(PtpClock *ptpClock, const TimeInternal *time) { Timestamp preciseOriginTimestamp; fromInternalTime(time, &preciseOriginTimestamp); msgPackFollowUp(ptpClock, ptpClock->msgObuf, &preciseOriginTimestamp); if (!netSendGeneral(&ptpClock->netPath, ptpClock->msgObuf, FOLLOW_UP_LENGTH)) { ERROR("issueFollowup: can't sent\n"); toState(ptpClock, PTP_FAULTY); } else { DBGV("issueFollowup\n"); } }
/*Pack and send on event multicast ip adress a PDelayResp message*/ void issuePDelayResp(TimeInternal *time,MsgHeader *header,RunTimeOpts *rtOpts, PtpClock *ptpClock) { Timestamp requestReceiptTimestamp; fromInternalTime(time,&requestReceiptTimestamp); msgPackPDelayResp(ptpClock->msgObuf,header, &requestReceiptTimestamp,ptpClock); if (!netSendPeerEvent(ptpClock->msgObuf,PDELAY_RESP_LENGTH, &ptpClock->netPath)) { toState(PTP_FAULTY,rtOpts,ptpClock); DBGV("PdelayResp message can't be sent -> FAULTY state \n"); } else { DBGV("PDelayResp MSG sent ! \n"); } }
/*Pack and send on event multicast ip adress a Sync message*/ void issueSync(RunTimeOpts *rtOpts,PtpClock *ptpClock) { Timestamp originTimestamp; TimeInternal internalTime; getTime(&internalTime); fromInternalTime(&internalTime,&originTimestamp); msgPackSync(ptpClock->msgObuf,&originTimestamp,ptpClock); if (!netSendEvent(ptpClock->msgObuf,SYNC_LENGTH,&ptpClock->netPath, 0)) { toState(PTP_FAULTY,rtOpts,ptpClock); DBGV("Sync message can't be sent -> FAULTY state \n"); } else { DBGV("Sync MSG sent ! \n"); ptpClock->sentSyncSequenceId++; } }
/*Pack and send on event multicast ip adress a PDelayReq message*/ void issuePDelayReq(RunTimeOpts *rtOpts,PtpClock *ptpClock) { Timestamp originTimestamp; TimeInternal internalTime; getTime(&internalTime); fromInternalTime(&internalTime,&originTimestamp); msgPackPDelayReq(ptpClock->msgObuf,&originTimestamp,ptpClock); if (!netSendPeerEvent(ptpClock->msgObuf,PDELAY_REQ_LENGTH, &ptpClock->netPath)) { toState(PTP_FAULTY,rtOpts,ptpClock); DBGV("PdelayReq message can't be sent -> FAULTY state \n"); } else { DBGV("PDelayReq MSG sent ! \n"); ptpClock->sentPDelayReqSequenceId++; } }
/*Pack and send on event multicast ip adress a PDelayResp message*/ static void issuePDelayResp(PtpClock *ptpClock, TimeInternal *time, const MsgHeader * pDelayReqHeader) { Timestamp requestReceiptTimestamp; fromInternalTime(time, &requestReceiptTimestamp); msgPackPDelayResp(ptpClock->msgObuf, pDelayReqHeader, &requestReceiptTimestamp); if (!netSendPeerEvent(&ptpClock->netPath, ptpClock->msgObuf, PDELAY_RESP_LENGTH, time)) { ERROR("issuePDelayResp: can't sent\n"); toState(ptpClock, PTP_FAULTY); } else { if (time->seconds != 0) { /*Add latency*/ addTime(time, time, &ptpClock->outboundLatency); } DBGV("issuePDelayResp\n"); } }
/*Pack and send on event multicast ip adress a DelayReq message*/ void issueDelayReq(RunTimeOpts *rtOpts,PtpClock *ptpClock) { Timestamp originTimestamp; TimeInternal internalTime; DBG("==> Issue DelayReq (%d)\n", ptpClock->sentDelayReqSequenceId ); /* call GTOD. This time is later replaced on handle_delayreq, to get the actual send timestamp from the OS */ getTime(&internalTime); fromInternalTime(&internalTime,&originTimestamp); // uses current sentDelayReqSequenceId msgPackDelayReq(ptpClock->msgObuf,&originTimestamp,ptpClock); Integer32 dst = 0; #ifdef PTP_EXPERIMENTAL if (rtOpts->do_hybrid_mode) { dst = ptpClock->MasterAddr; } #endif if (!netSendEvent(ptpClock->msgObuf,DELAY_REQ_LENGTH, &ptpClock->netPath, dst)) { toState(PTP_FAULTY,rtOpts,ptpClock); DBGV("delayReq message can't be sent -> FAULTY state \n"); } else { DBGV("DelayReq MSG sent ! \n"); ptpClock->sentDelayReqSequenceId++; /* From now on, we will only accept delayreq and delayresp of (sentDelayReqSequenceId - 1) */ /* Explicitelly re-arm timer for sending the next delayReq */ timerStart_random(DELAYREQ_INTERVAL_TIMER, pow(2,ptpClock->logMinDelayReqInterval), ptpClock->itimer); } }
/*Pack and send on event multicast ip adress a DelayResp message*/ void issueDelayResp(TimeInternal *time,MsgHeader *header,RunTimeOpts *rtOpts, PtpClock *ptpClock) { Timestamp requestReceiptTimestamp; fromInternalTime(time,&requestReceiptTimestamp); msgPackDelayResp(ptpClock->msgObuf,header,&requestReceiptTimestamp, ptpClock); Integer32 dst = 0; #ifdef PTP_EXPERIMENTAL if (rtOpts->do_hybrid_mode) { dst = ptpClock->LastSlaveAddr; } #endif if (!netSendGeneral(ptpClock->msgObuf,PDELAY_RESP_LENGTH, &ptpClock->netPath, dst)) { toState(PTP_FAULTY,rtOpts,ptpClock); DBGV("delayResp message can't be sent -> FAULTY state \n"); } else { DBGV("PDelayResp MSG sent ! \n"); } }
UInteger16 msgPackManagementResponse(void *buf, MsgHeader *header, MsgManagement *manage, PtpClock *ptpClock) { TimeInternal internalTime; TimeRepresentation externalTime; *(UInteger8*)((char*)buf + 20) = 2; /* messageType */ *(Integer32*)((char*)buf + 28) = shift16(flip16(ptpClock->port_id_field), 0) | shift16(flip16(ptpClock->last_general_event_sequence_number), 1); *(UInteger8*)((char*)buf + 32) = PTP_MANAGEMENT_MESSAGE; /* control */ clearFlag(((char*)buf + 34), PTP_SYNC_BURST); clearFlag(((char*)buf + 34), PARENT_STATS); *(Integer32*)((char*)buf + 40) = shift8(header->sourceCommunicationTechnology, 1); memcpy((char*)buf + 42, header->sourceUuid, 6); *(Integer32*)((char*)buf + 48) = shift16(flip16(header->sourcePortId), 0) | shift16(flip16(MM_STARTING_BOUNDARY_HOPS), 1); *(Integer32*)((char*)buf + 52) = shift16(flip16(manage->startingBoundaryHops - manage->boundaryHops + 1), 0); switch(manage->managementMessageKey) { case PTP_MM_OBTAIN_IDENTITY: *(UInteger8*)((char*)buf + 55) = PTP_MM_CLOCK_IDENTITY; *(Integer32*)((char*)buf + 56) = shift16(flip16(64), 1); *(Integer32*)((char*)buf + 60) = shift8(ptpClock->clock_communication_technology, 3); memcpy((char*)buf + 64, ptpClock->clock_uuid_field, 6); *(Integer32*)((char*)buf + 72) = shift16(flip16(ptpClock->clock_port_id_field), 1); memcpy(((char*)buf + 76), MANUFACTURER_ID, 48); return 124; case PTP_MM_GET_DEFAULT_DATA_SET: *(UInteger8*)((char*)buf + 55) = PTP_MM_DEFAULT_DATA_SET; *(Integer32*)((char*)buf + 56) = shift16(flip16(76), 1); *(Integer32*)((char*)buf + 60) = shift8(ptpClock->clock_communication_technology, 3); memcpy((char*)buf + 64, ptpClock->clock_uuid_field, 6); *(Integer32*)((char*)buf + 72) = shift16(flip16(ptpClock->clock_port_id_field), 1); *(Integer32*)((char*)buf + 76) = shift8(ptpClock->clock_stratum, 3); memcpy((char*)buf + 80, ptpClock->clock_identifier, 4); *(Integer32*)((char*)buf + 84) = shift16(flip16(ptpClock->clock_variance), 1); *(Integer32*)((char*)buf + 88) = shift8(ptpClock->clock_followup_capable, 3); *(Integer32*)((char*)buf + 92) = shift8(ptpClock->preferred, 3); *(Integer32*)((char*)buf + 96) = shift8(ptpClock->initializable, 3); *(Integer32*)((char*)buf + 100) = shift8(ptpClock->external_timing, 3); *(Integer32*)((char*)buf + 104) = shift8(ptpClock->is_boundary_clock, 3); *(Integer32*)((char*)buf + 108) = shift8(ptpClock->sync_interval, 3); memcpy((char*)buf + 112, ptpClock->subdomain_name, 16); *(Integer32*)((char*)buf + 128) = shift16(flip16(ptpClock->number_ports), 1); *(Integer32*)((char*)buf + 132) = shift16(flip16(ptpClock->number_foreign_records), 1); return 136; case PTP_MM_GET_CURRENT_DATA_SET: *(UInteger8*)((char*)buf + 55) = PTP_MM_CURRENT_DATA_SET; *(Integer32*)((char*)buf + 56) = shift16(flip16(20), 1); *(Integer32*)((char*)buf + 60) = shift16(flip16(ptpClock->steps_removed), 1); fromInternalTime(&ptpClock->offset_from_master, &externalTime, 0); *(Integer32*)((char*)buf + 64) = flip32(externalTime.seconds); *(Integer32*)((char*)buf + 68) = flip32(externalTime.nanoseconds); fromInternalTime(&ptpClock->one_way_delay, &externalTime, 0); *(Integer32*)((char*)buf + 72) = flip32(externalTime.seconds); *(Integer32*)((char*)buf + 76) = flip32(externalTime.nanoseconds); return 80; case PTP_MM_GET_PARENT_DATA_SET: *(UInteger8*)((char*)buf + 55) = PTP_MM_PARENT_DATA_SET; *(Integer32*)((char*)buf + 56) = shift16(flip16(90), 1); *(Integer32*)((char*)buf + 60) = shift8(ptpClock->parent_communication_technology, 3); memcpy((char*)buf + 64, ptpClock->parent_uuid, 6); *(Integer32*)((char*)buf + 72) = shift16(flip16(ptpClock->parent_port_id), 1); *(Integer32*)((char*)buf + 76) = shift16(flip16(ptpClock->parent_last_sync_sequence_number), 1); *(Integer32*)((char*)buf + 80) = shift8(ptpClock->parent_followup_capable, 1); *(Integer32*)((char*)buf + 84) = shift8(ptpClock->parent_external_timing, 3); *(Integer32*)((char*)buf + 88) = shift16(flip16(ptpClock->parent_variance), 1); *(Integer32*)((char*)buf + 92) = shift8(ptpClock->parent_stats, 3); *(Integer32*)((char*)buf + 96) = shift16(flip16(ptpClock->observed_variance), 1); *(Integer32*)((char*)buf + 100) = flip32(ptpClock->observed_drift); *(Integer32*)((char*)buf + 104) = shift8(ptpClock->utc_reasonable, 3); *(Integer32*)((char*)buf + 108) = shift8(ptpClock->grandmaster_communication_technology, 3); memcpy((char*)buf + 112, ptpClock->grandmaster_uuid_field, 6); *(Integer32*)((char*)buf + 120) = shift16(flip16(ptpClock->grandmaster_port_id_field), 1); *(Integer32*)((char*)buf + 124) = shift8(ptpClock->grandmaster_stratum, 3); memcpy((char*)buf + 128, ptpClock->grandmaster_identifier, 4); *(Integer32*)((char*)buf + 132) = shift16(flip16(ptpClock->grandmaster_variance), 1); *(Integer32*)((char*)buf + 136) = shift8(ptpClock->grandmaster_preferred, 3); *(Integer32*)((char*)buf + 140) = shift8(ptpClock->grandmaster_is_boundary_clock, 3); *(Integer32*)((char*)buf + 144) = shift16(flip16(ptpClock->grandmaster_sequence_number), 1); return 148; case PTP_MM_GET_PORT_DATA_SET: if(manage->targetPortId && manage->targetPortId != ptpClock->port_id_field) { *(UInteger8*)((char*)buf + 55) = PTP_MM_NULL; *(Integer32*)((char*)buf + 56) = shift16(flip16(0), 1); return 0; } *(UInteger8*)((char*)buf + 55) = PTP_MM_PORT_DATA_SET; *(Integer32*)((char*)buf + 56) = shift16(flip16(52), 1); *(Integer32*)((char*)buf + 60) = shift16(flip16(ptpClock->port_id_field), 1); *(Integer32*)((char*)buf + 64) = shift8(ptpClock->port_state, 3); *(Integer32*)((char*)buf + 68) = shift16(flip16(ptpClock->last_sync_event_sequence_number), 1); *(Integer32*)((char*)buf + 72) = shift16(flip16(ptpClock->last_general_event_sequence_number), 1); *(Integer32*)((char*)buf + 76) = shift8(ptpClock->port_communication_technology, 3); memcpy((char*)buf + 80, ptpClock->port_uuid_field, 6); *(Integer32*)((char*)buf + 88) = shift16(flip16(ptpClock->port_id_field), 1); *(Integer32*)((char*)buf + 92) = shift8(ptpClock->burst_enabled, 3); *(Integer32*)((char*)buf + 96) = shift8(4, 1) | shift8(2, 2) | shift8(2, 3); memcpy((char*)buf + 100, ptpClock->subdomain_address, 4); memcpy((char*)buf + 106, ptpClock->event_port_address, 2); memcpy((char*)buf + 110, ptpClock->general_port_address, 2); return 112; case PTP_MM_GET_GLOBAL_TIME_DATA_SET: *(UInteger8*)((char*)buf + 55) = PTP_MM_GLOBAL_TIME_DATA_SET; *(Integer32*)((char*)buf + 56) = shift16(flip16(24), 1); getTime(&internalTime); fromInternalTime(&internalTime, &externalTime, ptpClock->halfEpoch); *(Integer32*)((char*)buf + 60) = flip32(externalTime.seconds); *(Integer32*)((char*)buf + 64) = flip32(externalTime.nanoseconds); *(Integer32*)((char*)buf + 68) = shift16(flip16(ptpClock->current_utc_offset), 1); *(Integer32*)((char*)buf + 72) = shift8(ptpClock->leap_59, 3); *(Integer32*)((char*)buf + 76) = shift8(ptpClock->leap_61, 3); *(Integer32*)((char*)buf + 80) = shift16(flip16(ptpClock->epoch_number), 1); return 84; case PTP_MM_GET_FOREIGN_DATA_SET: if((manage->targetPortId && manage->targetPortId != ptpClock->port_id_field) || !manage->recordKey || manage->recordKey > ptpClock->number_foreign_records) { *(UInteger8*)((char*)buf + 55) = PTP_MM_NULL; *(Integer32*)((char*)buf + 56) = shift16(flip16(0), 1); return 0; } *(UInteger8*)((char*)buf + 55) = PTP_MM_FOREIGN_DATA_SET; *(Integer32*)((char*)buf + 56) = shift16(flip16(28), 1); *(Integer32*)((char*)buf + 60) = shift16(flip16(ptpClock->port_id_field), 1); *(Integer32*)((char*)buf + 64) = shift16(flip16(manage->recordKey - 1), 1); *(Integer32*)((char*)buf + 68) = shift8(ptpClock->foreign[manage->recordKey - 1].foreign_master_communication_technology, 3); memcpy((char*)buf + 72, ptpClock->foreign[manage->recordKey - 1].foreign_master_uuid, 6); *(Integer32*)((char*)buf + 80) = shift16(flip16(ptpClock->foreign[manage->recordKey - 1].foreign_master_port_id), 1); *(Integer32*)((char*)buf + 84) = shift16(flip16(ptpClock->foreign[manage->recordKey - 1].foreign_master_syncs), 1); return 88; default: return 0; } }