summaryrefslogtreecommitdiff
path: root/third_party/ptpd-1.1.0/src/probe.c
blob: 8fdadcf39557f7c25194d75cc646fae13d8f8bfb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
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
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
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
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
/**
 * @file   probe.c
 * @date   Tue Jul 20 16:13:30 2010
 * 
 * @brief  Management packet handling
 * 
 * 
 */

#include "ptpd.h"

#define KEY_ARRAY_LEN 6
UInteger8 management_key_array[KEY_ARRAY_LEN] =
{PTP_MM_OBTAIN_IDENTITY, PTP_MM_GET_DEFAULT_DATA_SET, PTP_MM_GET_CURRENT_DATA_SET,
PTP_MM_GET_PARENT_DATA_SET, PTP_MM_GET_PORT_DATA_SET, PTP_MM_GET_GLOBAL_TIME_DATA_SET};

void	displayHeader(MsgHeader *);
void	displayManagement(MsgHeader *, MsgManagement *);

void 
probe(RunTimeOpts * rtOpts, PtpClock * ptpClock)
{
	UInteger16 i;
	UInteger16 length;
	TimeInternal interval, now, finish, timestamp;

	/* check */
	if (rtOpts->probe_management_key == PTP_MM_UPDATE_DEFAULT_DATA_SET
	    || rtOpts->probe_management_key == PTP_MM_UPDATE_GLOBAL_TIME_PROPERTIES
	    || rtOpts->probe_management_key == PTP_MM_SET_SYNC_INTERVAL) {
		ERROR("send not supported for that management message\n");
		return;
	}
	/* init */
	if (!netInit(&ptpClock->netPath, rtOpts, ptpClock)) {
		ERROR("failed to initialize network\n");
		return;
	}
	initData(rtOpts, ptpClock);
	msgPackHeader(ptpClock->msgObuf, ptpClock);

	memset(&ptpClock->msgTmp.manage, 0, sizeof(MsgManagement));
	ptpClock->msgTmp.manage.targetCommunicationTechnology = PTP_DEFAULT;

	/* send */
	for (i = 0; i < KEY_ARRAY_LEN; ++i) {
		if (rtOpts->probe_management_key > 0) {
			ptpClock->msgTmp.manage.managementMessageKey = rtOpts->probe_management_key;
			ptpClock->msgTmp.manage.recordKey = rtOpts->probe_record_key;
		} else
			ptpClock->msgTmp.manage.managementMessageKey = management_key_array[i];

		if (!(length = msgPackManagement(ptpClock->msgObuf, &ptpClock->msgTmp.manage, ptpClock))) {
			ERROR("failed to pack management message\n");
			return;
		}
		printf("\n(sending managementMessageKey %hhu)\n", ptpClock->msgTmp.manage.managementMessageKey);

		if (!netSendGeneral(ptpClock->msgObuf, length, &ptpClock->netPath)) {
			ERROR("failed to send message\n");
			return;
		}
		if (rtOpts->probe_management_key > 0)
			break;
	}

	getTime(&finish);
	finish.seconds += PTP_SYNC_INTERVAL_TIMEOUT(ptpClock->sync_interval);
	for (;;) {
		interval.seconds = PTP_SYNC_INTERVAL_TIMEOUT(ptpClock->sync_interval);
		interval.nanoseconds = 0;
		netSelect(&interval, &ptpClock->netPath);

		netRecvEvent(ptpClock->msgIbuf, &timestamp, &ptpClock->netPath);

		if (netRecvGeneral(ptpClock->msgIbuf, &ptpClock->netPath)) {
			msgUnpackHeader(ptpClock->msgIbuf, &ptpClock->msgTmpHeader);

			if (ptpClock->msgTmpHeader.control == PTP_MANAGEMENT_MESSAGE) {
				msgUnpackManagement(ptpClock->msgIbuf, &ptpClock->msgTmp.manage);
				msgUnpackManagementPayload(ptpClock->msgIbuf, &ptpClock->msgTmp.manage);

				displayManagement(&ptpClock->msgTmpHeader, &ptpClock->msgTmp.manage);
			}
			fflush(stdout);
		}
		getTime(&now);
		if (now.seconds > finish.seconds || (now.seconds == finish.seconds
		    && now.nanoseconds > finish.nanoseconds))
			break;
	}

	/* done */
	printf("\n");
	ptpdShutdown();

	exit(0);
}

void 
displayHeader(MsgHeader * header)
{
	printf(
	    "  sourceCommunicationTechnology %hhu\n"
	    "  sourceUuid %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx\n"
	    "  sourcePortId %hu\n",
	    header->sourceCommunicationTechnology,
	    header->sourceUuid[0], header->sourceUuid[1], header->sourceUuid[2],
	    header->sourceUuid[3], header->sourceUuid[4], header->sourceUuid[5],
	    header->sourcePortId);
}

void 
displayManagement(MsgHeader * header, MsgManagement * manage)
{
	Integer16 i;

	switch (manage->managementMessageKey) {
	case PTP_MM_CLOCK_IDENTITY:
		printf("\n");
		displayHeader(header);
		printf("  managementMessageKey %hhu (PTP_MM_CLOCK_IDENTITY)\n", manage->managementMessageKey);
		printf("  clockCommunicationTechnology %hhu\n", manage->payload.clockIdentity.clockCommunicationTechnology);
		printf("  clockUuidField %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx\n",
		    manage->payload.clockIdentity.clockUuidField[0], manage->payload.clockIdentity.clockUuidField[1],
		    manage->payload.clockIdentity.clockUuidField[2], manage->payload.clockIdentity.clockUuidField[3],
		    manage->payload.clockIdentity.clockUuidField[4], manage->payload.clockIdentity.clockUuidField[5]);
		printf("  clockPortField %hu\n", manage->payload.clockIdentity.clockPortField);
		printf("  manufacturerIdentity ");
		for (i = 0; i < MANUFACTURER_ID_LENGTH && manage->payload.clockIdentity.manufacturerIdentity[i]; ++i)
			putchar(manage->payload.clockIdentity.manufacturerIdentity[i]);
		putchar('\n');
		break;

	case PTP_MM_DEFAULT_DATA_SET:
		printf("\n");
		displayHeader(header);
		printf("  managementMessageKey %hhu (PTP_MM_DEFAULT_DATA_SET)\n", manage->managementMessageKey);
		printf("  clockCommunicationTechnology %hhu\n", manage->payload.defaultData.clockCommunicationTechnology);
		printf("  clockUuidField %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx\n",
		    manage->payload.defaultData.clockUuidField[0], manage->payload.defaultData.clockUuidField[1],
		    manage->payload.defaultData.clockUuidField[2], manage->payload.defaultData.clockUuidField[3],
		    manage->payload.defaultData.clockUuidField[4], manage->payload.defaultData.clockUuidField[5]);
		printf("  clockPortField %hu\n", manage->payload.defaultData.clockPortField);
		printf("  clockStratum %hhu\n", manage->payload.defaultData.clockStratum);
		printf("  clockIdentifier ");
		for (i = 0; i < PTP_CODE_STRING_LENGTH && manage->payload.defaultData.clockIdentifier[i]; ++i)
			putchar(manage->payload.defaultData.clockIdentifier[i]);
		putchar('\n');
		printf("  clockVariance %hd\n", manage->payload.defaultData.clockVariance);
		printf("  clockFollowupCapable %hhu\n", manage->payload.defaultData.clockFollowupCapable);
		printf("  preferred %hhu\n", manage->payload.defaultData.preferred);
		printf("  initializable %hhu\n", manage->payload.defaultData.initializable);
		printf("  externalTiming %hhu\n", manage->payload.defaultData.externalTiming);
		printf("  isBoundaryClock %hhu\n", manage->payload.defaultData.isBoundaryClock);
		printf("  syncInterval %hhd\n", manage->payload.defaultData.syncInterval);
		printf("  subdomainName ");
		for (i = 0; i < PTP_SUBDOMAIN_NAME_LENGTH && manage->payload.defaultData.subdomainName[i]; ++i)
			putchar(manage->payload.defaultData.subdomainName[i]);
		putchar('\n');
		printf("  numberPorts %hu\n", manage->payload.defaultData.numberPorts);
		printf("  numberForeignRecords %hu\n", manage->payload.defaultData.numberForeignRecords);
		break;

	case PTP_MM_CURRENT_DATA_SET:
		printf("\n");
		displayHeader(header);
		printf("  managementMessageKey %hhu (PTP_MM_CURRENT_DATA_SET)\n", manage->managementMessageKey);
		printf("  stepsRemoved %hu\n", manage->payload.current.stepsRemoved);
		printf("  offsetFromMaster %s%u.%09d\n",
		    manage->payload.current.offsetFromMaster.nanoseconds & 0x80000000 ? "-" : "",
		    manage->payload.current.offsetFromMaster.seconds,
		    manage->payload.current.offsetFromMaster.nanoseconds & ~0x80000000);
		printf("  oneWayDelay %s%u.%09d\n",
		    manage->payload.current.oneWayDelay.nanoseconds & 0x80000000 ? "-" : "",
		    manage->payload.current.oneWayDelay.seconds,
		    manage->payload.current.oneWayDelay.nanoseconds & ~0x80000000);
		break;

	case PTP_MM_PARENT_DATA_SET:
		printf("\n");
		displayHeader(header);
		printf("  managementMessageKey %hhu (PTP_MM_PARENT_DATA_SET)\n", manage->managementMessageKey);
		printf("  parentCommunicationTechnology %hhu\n", manage->payload.parent.parentCommunicationTechnology);
		printf("  parentUuid %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx\n",
		    manage->payload.parent.parentUuid[0], manage->payload.parent.parentUuid[1],
		    manage->payload.parent.parentUuid[2], manage->payload.parent.parentUuid[3],
		    manage->payload.parent.parentUuid[4], manage->payload.parent.parentUuid[5]);
		printf("  parentPortId %hu\n", manage->payload.parent.parentPortId);
		printf("  parentLastSyncSequenceNumber %hu\n", manage->payload.parent.parentLastSyncSequenceNumber);
		printf("  parentFollowupCapable %hhu\n", manage->payload.parent.parentFollowupCapable);
		printf("  parentExternalTiming %hhu\n", manage->payload.parent.parentExternalTiming);
		printf("  parentVariance %hd\n", manage->payload.parent.parentVariance);
		printf("  parentStats %hhu\n", manage->payload.parent.parentStats);
		printf("  observedVariance %hd\n", manage->payload.parent.observedVariance);
		printf("  observedDrift %d\n", manage->payload.parent.observedDrift);
		printf("  utcReasonable %hhu\n", manage->payload.parent.utcReasonable);
		printf("  grandmasterCommunicationTechnology %hhu\n", manage->payload.parent.grandmasterCommunicationTechnology);
		printf("  grandmasterUuidField %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx\n",
		    manage->payload.parent.grandmasterUuidField[0], manage->payload.parent.grandmasterUuidField[1],
		    manage->payload.parent.grandmasterUuidField[2], manage->payload.parent.grandmasterUuidField[3],
		    manage->payload.parent.grandmasterUuidField[4], manage->payload.parent.grandmasterUuidField[5]);
		printf("  grandmasterPortIdField %hu\n", manage->payload.parent.grandmasterPortIdField);
		printf("  grandmasterStratum %hhu\n", manage->payload.parent.grandmasterStratum);
		printf("  grandmasterIdentifier ");
		for (i = 0; i < PTP_CODE_STRING_LENGTH && manage->payload.parent.grandmasterIdentifier[i]; ++i)
			putchar(manage->payload.parent.grandmasterIdentifier[i]);
		putchar('\n');
		printf("  grandmasterVariance %hd\n", manage->payload.parent.grandmasterVariance);
		printf("  grandmasterPreferred %hhu\n", manage->payload.parent.grandmasterPreferred);
		printf("  grandmasterIsBoundaryClock %hhu\n", manage->payload.parent.grandmasterIsBoundaryClock);
		printf("  grandmasterSequenceNumber %hu\n", manage->payload.parent.grandmasterSequenceNumber);
		break;

	case PTP_MM_PORT_DATA_SET:
		printf("\n");
		displayHeader(header);
		printf("  managementMessageKey %hhu (PTP_MM_PORT_DATA_SET)\n", manage->managementMessageKey);
		printf("  returnedPortNumber %hu\n", manage->payload.port.returnedPortNumber);
		printf("  portState %hhu\n", manage->payload.port.portState);
		printf("  lastSyncEventSequenceNumber %hu\n", manage->payload.port.lastSyncEventSequenceNumber);
		printf("  lastGeneralEventSequenceNumber %hu\n", manage->payload.port.lastGeneralEventSequenceNumber);
		printf("  portCommunicationTechnology %hhu\n", manage->payload.port.portCommunicationTechnology);
		printf("  portUuidField %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx\n",
		    manage->payload.port.portUuidField[0], manage->payload.port.portUuidField[1],
		    manage->payload.port.portUuidField[2], manage->payload.port.portUuidField[3],
		    manage->payload.port.portUuidField[4], manage->payload.port.portUuidField[5]);
		printf("  portIdField %hu\n", manage->payload.port.portIdField);
		printf("  burstEnabled %hhu\n", manage->payload.port.burstEnabled);
		printf("  subdomainAddressOctets %hhu\n", manage->payload.port.subdomainAddressOctets);
		printf("  eventPortAddressOctets %hhu\n", manage->payload.port.eventPortAddressOctets);
		printf("  generalPortAddressOctets %hhu\n", manage->payload.port.generalPortAddressOctets);
		printf("  subdomainAddress ");
		printf("%hhu", manage->payload.port.subdomainAddress[0]);
		for (i = 1; i < SUBDOMAIN_ADDRESS_LENGTH; ++i)
			printf(".%hhu", manage->payload.port.subdomainAddress[i]);
		putchar('\n');
		printf("  eventPortAddress %hu\n", *(UInteger16 *) manage->payload.port.eventPortAddress);
		printf("  generalPortAddress %hu\n", *(UInteger16 *) manage->payload.port.generalPortAddress);
		break;

	case PTP_MM_GLOBAL_TIME_DATA_SET:
		printf("\n");
		displayHeader(header);
		printf("  managementMessageKey %hhu (PTP_MM_GLOBAL_TIME_DATA_SET)\n", manage->managementMessageKey);
		printf("  localTime %s%u.%09d\n",
		    manage->payload.globalTime.localTime.nanoseconds & 0x80000000 ? "-" : "",
		    manage->payload.globalTime.localTime.seconds,
		    manage->payload.globalTime.localTime.nanoseconds & ~0x80000000);
		printf("  currentUtcOffset %hd\n", manage->payload.globalTime.currentUtcOffset);
		printf("  leap59 %hhu\n", manage->payload.globalTime.leap59);
		printf("  leap61 %hhu\n", manage->payload.globalTime.leap61);
		printf("  epochNumber %hu\n", manage->payload.globalTime.epochNumber);
		break;


	case PTP_MM_FOREIGN_DATA_SET:
		printf("\n");
		displayHeader(header);
		printf("  managementMessageKey %hhu (PTP_MM_FOREIGN_DATA_SET)\n", manage->managementMessageKey);
		printf("  returnedPortNumber %hu\n", manage->payload.foreign.returnedPortNumber);
		printf("  returnedRecordNumber %hu\n", manage->payload.foreign.returnedRecordNumber);
		printf("  foreignMasterCommunicationTechnology %hu\n", manage->payload.foreign.foreignMasterCommunicationTechnology);
		printf("  foreignMasterUuid %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx\n",
		    manage->payload.foreign.foreignMasterUuid[0], manage->payload.foreign.foreignMasterUuid[1],
		    manage->payload.foreign.foreignMasterUuid[2], manage->payload.foreign.foreignMasterUuid[3],
		    manage->payload.foreign.foreignMasterUuid[4], manage->payload.foreign.foreignMasterUuid[5]);

		printf("  foreignMasterPortId %hu\n", manage->payload.foreign.foreignMasterPortId);
		printf("  foreignMasterSyncs %hu\n", manage->payload.foreign.foreignMasterSyncs);
		break;

	case PTP_MM_NULL:
		printf("\n");
		displayHeader(header);
		printf("  managementMessageKey %hhu (NULL)\n", manage->managementMessageKey);
		break;

	default:
		break;
	}

	return;
}