flexPTP 1.0
An IEEE 1588 PTP implementation designed for microcontrollers
Loading...
Searching...
No Matches
cli_cmds.c
Go to the documentation of this file.
1#include "cli_cmds.h"
2
3#include <stdlib.h>
4#include <string.h>
5#include <inttypes.h>
6
7#include "clock_utils.h"
8#include "logging.h"
9#include "profiles.h"
10#include "ptp_core.h"
11#include "ptp_profile_presets.h"
12#include "ptp_types.h"
13#include "settings_interface.h"
14
15#include "minmax.h"
16
17// #define S (gPtpCoreState)
18
19// ---- COMPILE ONLY IF CLI_REG_CMD is provided ----
20
21#ifdef CLI_REG_CMD
22
23#ifndef CMD_FUNCTION
24#error "No CMD_FUNCTION macro has been defined, cannot register CLI functions!"
25#endif
26
27static CMD_FUNCTION(CB_reset) {
28 ptp_reset();
29 MSG("> PTP reset!\n");
30 return 0;
31}
32
33static CMD_FUNCTION(CB_offset) {
34 if (argc > 0) {
35 ptp_set_clock_offset(atoi(ppArgs[0]));
36 }
37
38 MSG("> PTP clock offset: %d ns\n", ptp_get_clock_offset());
39 return 0;
40}
41
42static CMD_FUNCTION(CB_log) {
43 bool logEn = false;
44
45 if (argc > 1) {
46 if (!strcmp(ppArgs[1], "on")) {
47 logEn = true;
48 } else if (!strcmp(ppArgs[1], "off")) {
49 logEn = false;
50 } else {
51 return -1;
52 }
53
54 if (!strcmp(ppArgs[0], "def")) {
56 } else if (!strcmp(ppArgs[0], "corr")) {
58 } else if (!strcmp(ppArgs[0], "ts")) {
60 } else if (!strcmp(ppArgs[0], "info")) {
62 } else if (!strcmp(ppArgs[0], "locked")) {
64 } else if (!strcmp(ppArgs[0], "bmca")) {
66 } else if (!strcmp(ppArgs[0], "logid")) {
68 } else {
69 return -1;
70 }
71
72 } else {
73 return -1;
74 }
75
76 return 0;
77}
78
79static CMD_FUNCTION(CB_time) {
80 char datetime[24];
81 TimestampU t;
82 ptp_time(&t);
83
84 if (argc > 0 && !strcmp(ppArgs[0], "ns")) {
85 MSG("%" __PRI64_PREFIX "u %u\n", t.sec, t.nanosec);
86 } else {
87 tsPrint(datetime, (const TimestampI *)&t);
88 MSG("%s\n", datetime);
89 }
90
91 return 0;
92}
93
94static CMD_FUNCTION(CB_master) {
95 if (argc > 0) {
96 if (!strcmp(ppArgs[0], "prefer")) {
98 if (argc > 1) {
99 idM = hextoclkid(ppArgs[1]);
100 }
102 } else if (!strcmp(ppArgs[0], "unprefer")) {
104 }
105 }
106
107 MSG("Master clock ID: ");
109 MSG("\n");
110 return 0;
111}
112
113static CMD_FUNCTION(CB_ptpinfo) {
114 MSG("Own clock ID: ");
116 MSG("\nMaster clock ID: ");
118 MSG("\n");
119 return 0;
120}
121
122static CMD_FUNCTION(CB_ptpdomain) {
123 if (argc > 0) {
124 ptp_set_domain(atoi(ppArgs[0]));
125 }
126 MSG("PTP domain: %d\n", (int)ptp_get_domain());
127 return 0;
128}
129
130#ifdef PTP_ADDEND_INTERFACE
131static CMD_FUNCTION(CB_addend) {
132 if (argc > 0) {
133 ptp_set_addend((uint32_t)atoll(ppArgs[0]));
134 }
135 MSG("Addend: %u\n", ptp_get_addend());
136 return 0;
137}
138#elif defined(PTP_HLT_INTERFACE)
139static CMD_FUNCTION(CB_tuning) {
140 if (argc > 0) {
141 ptp_set_tuning((uint32_t)atof(ppArgs[0]));
142 }
143 MSG("Tuning: %.4f\n", ptp_get_tuning());
144 return 0;
145}
146#endif
147
148static CMD_FUNCTION(CB_transportType) {
149 if (argc > 0) {
150 if (!strcmp(ppArgs[0], "ipv4")) {
152 } else if (!strcmp(ppArgs[0], "802.3")) {
154 }
155 }
156
157 MSG("Transport layer: %s\n", PTP_TRANSPORT_TYPE_HINT[ptp_get_transport_type()]);
158 return 0;
159}
160
161static CMD_FUNCTION(CB_delayMechanism) {
162 if (argc > 0) { // If changing delay mechanism, PTP will be inherently reset!
163 if (!strcmp(ppArgs[0], "e2e")) {
165 } else if (!strcmp(ppArgs[0], "p2p")) {
167 }
168 }
169
170 MSG("Delay mechanism: %s\n", PTP_DELMECH_HINT[(int)ptp_get_delay_mechanism()]);
171 return 0;
172}
173
174static CMD_FUNCTION(CB_transpec) {
175 if (argc > 0) { // ...inherent reset!
176 if (!strcmp(ppArgs[0], "def") || !strcmp(ppArgs[0], "unknown")) {
178 } else if (!strcmp(ppArgs[0], "gPTP")) {
180 }
181 }
182
183 MSG("PTP transport specific: %s\n", PTP_TRANSPEC_HINT[(int)ptp_get_transport_specific()]);
184 return 0;
185}
186
187static CMD_FUNCTION(CB_profile) {
188 bool printProfileSummary = true;
189 if (argc > 0 && !strcmp(ppArgs[0], "preset")) {
190 if (argc > 1) {
191 const PtpProfile *pProf = ptp_profile_preset_get(ppArgs[1]);
192 if (pProf) {
193 MSG("Loading preset '%s'...\n\n", ppArgs[1]);
194 ptp_load_profile(pProf); // ...inherent reset!
195 } else {
196 MSG("Profile preset '%s' is unknown, settings untouched!\n", ppArgs[1]);
197 }
198 } else {
199 MSG("PTP profile presets: ");
200 size_t N = ptp_profile_preset_cnt();
201 size_t i;
202 for (i = 0; i < N; i++) {
203 MSG("%s", ptp_profile_preset_get_name(i));
204 if ((i + 1) != N) {
205 MSG(", ");
206 }
207 }
208 MSG("\n");
209 printProfileSummary = false;
210 }
211 }
212
213 if (printProfileSummary) {
215 }
216 return 0;
217}
218
219static CMD_FUNCTION(CB_tlv) {
220 bool printLoadedTlvPresetChain = true;
221 if (argc > 0) {
222 if (!strcmp(ppArgs[0], "preset")) {
223 if (argc > 1) {
224 const PtpProfileTlvElement *pTlv = ptp_tlv_chain_preset_get(ppArgs[1]);
225 if (pTlv) {
226 MSG("Loading TLV-chain '%s'...\n\n", ppArgs[1]);
227 ptp_set_tlv_chain_by_name(ppArgs[1]); // ...inherent reset!
228 } else {
229 MSG("TLV-chain preset '%s' is unknown, settings are not tampered with!\n", ppArgs[1]);
230 }
231 printLoadedTlvPresetChain = false;
232
233 } else {
234 MSG("TLV-chain presets: ");
235 size_t N = ptp_tlv_chain_preset_cnt();
236 size_t i;
237 for (i = 0; i < N; i++) {
238 MSG("%s", ptp_tlv_chain_preset_get_name(i));
239 if ((i + 1) != N) {
240 MSG(", ");
241 }
242 }
243 MSG("\n");
244
245 printLoadedTlvPresetChain = false;
246 }
247 } else if (!strcmp(ppArgs[0], "unload")) {
248 MSG("Unloading any TLV-chain...\n\n");
250 printLoadedTlvPresetChain = false;
251 }
252 }
253
254 if (printLoadedTlvPresetChain) {
255 MSG("Loaded TLV-chain: ");
256 const char *tlvSet = ptp_get_loaded_tlv_chain();
257 if (!strcmp(tlvSet, "")) {
258 MSG("none\n\n");
259 } else {
260 MSG("'%s'\n\n", tlvSet);
261 }
262 }
263
264 return 0;
265}
266
267static CMD_FUNCTION(CB_profile_flags) {
268 if (argc > 0) { // set profile flags
269 uint8_t pf = atoi(ppArgs[0]);
271 }
272
273 MSG("Profile flags: %X\n", ptp_get_profile_flags());
274
275 return 0;
276}
277
278static CMD_FUNCTION(CB_logPeriod) {
279 if (argc > 1) {
280 if (!strcmp(ppArgs[0], "delreq")) {
281 if (!strcmp(ppArgs[1], "match")) {
283 } else {
284 int8_t lp = atoi(ppArgs[1]);
287 }
288 } else if (!strcmp(ppArgs[0], "sync")) {
289 int8_t lp = atoi(ppArgs[1]);
292 } else if (!strcmp(ppArgs[0], "ann")) {
293 int8_t lp = atoi(ppArgs[1]);
296 }
297 }
298
299 MSG("(P)Delay_Req log. period: ");
300 int8_t drlp = ptp_get_delay_req_log_period();
301 if (drlp != PTP_LOGPER_SYNCMATCHED) {
302 MSG("%d\n", drlp);
303 } else {
304 MSG("MATCHED\n");
305 }
306
307 MSG("Sync log. period: %d\n", ptp_get_sync_log_period());
308 MSG("Announce log. period: %d\n", ptp_get_announce_log_period());
309
310 return 0;
311}
312
313static CMD_FUNCTION(CB_coarseThreshold) {
314 if (argc > 0) {
315 ptp_set_coarse_threshold(atoi(ppArgs[0]));
316 }
317
318 MSG("PTP coarse correction threshold: %" __PRI64_PREFIX "u ns\n", ptp_get_coarse_threshold());
319 return 0;
320}
321
322static CMD_FUNCTION(CB_priority) {
323 if (argc >= 2) {
324 ptp_set_priority1(atoi(ppArgs[0]));
325 ptp_set_priority2(atoi(ppArgs[1]));
326 }
327
328 MSG("PTP priorities: priority1: %u, priority2: %u\n", ptp_get_priority1(), ptp_get_priority2());
329 return 0;
330}
331
332// command assignments
333enum PTP_CMD_IDS {
334 CMD_RESET,
335 CMD_OFFSET,
336 CMD_LOG,
337 CMD_TIME,
338 CMD_MASTER,
339 CMD_PTPINFO,
340 CMD_PTPDOMAIN,
341 CMD_ADDEND_TUNING,
342 CMD_TRANSPORTTYPE,
343 CMD_DELAYMECH,
344 CMD_TRANSPEC,
345 CMD_PROFILE,
346 CMD_TLV,
347 CMD_PROFILE_FLAGS,
348 CMD_LOGPERIOD,
349 CMD_COARSE_THRESHOLD,
350 CMD_PRIORITY,
351 CMD_N
352};
353
354// command descriptors
355static int sCmds[CMD_N + 1];
356
357#endif // CLI_REG_CMD
358
359// register cli commands
361#ifdef CLI_REG_CMD
362 sCmds[CMD_RESET] = CLI_REG_CMD("ptp reset \t\t\tReset PTP subsystem", 2, 0, CB_reset);
363 sCmds[CMD_OFFSET] = CLI_REG_CMD("ptp servo offset [offset_ns] \t\t\tSet or query clock offset", 3, 0, CB_offset);
364 sCmds[CMD_LOG] = CLI_REG_CMD("ptp log {def|corr|ts|info|locked|bmca|logid} {on|off} \t\t\tTurn on or off logging", 2, 2, CB_log);
365 sCmds[CMD_TIME] = CLI_REG_CMD("time [ns] \t\t\tPrint time", 1, 0, CB_time);
366 sCmds[CMD_MASTER] = CLI_REG_CMD("ptp master [[un]prefer] [clockid] \t\t\tMaster clock settings", 2, 0, CB_master);
367 sCmds[CMD_PTPINFO] = CLI_REG_CMD("ptp info \t\t\tPrint PTP info", 2, 0, CB_ptpinfo);
368 sCmds[CMD_PTPDOMAIN] = CLI_REG_CMD("ptp domain [domain]\t\t\tPrint or set PTP domain", 2, 0, CB_ptpdomain);
369#ifdef PTP_ADDEND_INTERFACE
370 sCmds[CMD_ADDEND_TUNING] = CLI_REG_CMD("ptp addend [addend]\t\t\tPrint or set addend", 2, 0, CB_addend);
371#elif defined(PTP_HLT_INTERFACE)
372 sCmds[CMD_ADDEND_TUNING] = CLI_REG_CMD("ptp tuning [tuning]\t\t\tPrint or set tuning", 2, 0, CB_tuning);
373#endif
374 sCmds[CMD_TRANSPORTTYPE] = CLI_REG_CMD("ptp transport [{ipv4|802.3}]\t\t\tSet or get PTP transport layer", 2, 0, CB_transportType);
375 sCmds[CMD_DELAYMECH] = CLI_REG_CMD("ptp delmech [{e2e|p2p}]\t\t\tSet or get PTP delay mechanism", 2, 0, CB_delayMechanism);
376 sCmds[CMD_TRANSPEC] = CLI_REG_CMD("ptp transpec [{def|gPTP}]\t\t\tSet or get PTP transportSpecific field (majorSdoId)", 2, 0, CB_transpec);
377 sCmds[CMD_PROFILE] = CLI_REG_CMD("ptp profile [preset [<name>]]\t\t\tPrint or set PTP profile, or list available presets", 2, 0, CB_profile);
378 sCmds[CMD_TLV] = CLI_REG_CMD("ptp tlv [preset [name]|unload]\t\t\tPrint or set TLV-chain, or list available TLV presets", 2, 0, CB_tlv);
379 sCmds[CMD_PROFILE_FLAGS] = CLI_REG_CMD("ptp pflags [<flags>]\t\t\tPrint or set profile flags", 2, 0, CB_profile_flags);
380 sCmds[CMD_LOGPERIOD] = CLI_REG_CMD("ptp period <delreq|sync|ann> [<lp>|matched]\t\t\tPrint or set log. periods", 2, 0, CB_logPeriod);
381 sCmds[CMD_COARSE_THRESHOLD] = CLI_REG_CMD("ptp coarse [threshold]\t\t\tPrint or set coarse correction threshold", 2, 0, CB_coarseThreshold);
382 sCmds[CMD_PRIORITY] = CLI_REG_CMD("ptp priority [<p1> <p2>]\t\t\tPrint or set clock priority fields", 2, 0, CB_priority);
383 sCmds[CMD_N] = -1;
384#endif // CLI_REG_CMD
385}
386
388#ifdef CLI_REMOVE_CMD
389 for (uint8_t i = 0; i < CMD_N; i++) {
390 CLI_REMOVE_CMD(i);
391 }
392#endif // CLI_REMOVE_CMD
393}
void ptp_register_cli_commands()
Definition: cli_cmds.c:360
void ptp_remove_cli_commands()
Definition: cli_cmds.c:387
This module handles and registers CLI commands. Commands:
void ptp_print_clock_identity(uint64_t clockID)
Definition: clock_utils.c:16
uint64_t hextoclkid(const char *str)
Definition: clock_utils.c:40
This module defines clock identity related operations.
#define CLI_REG_CMD(cmd_hintline, n_cmd, n_min_arg, cb)
void ptp_log_enable(int logId, bool en)
Definition: logging.c:52
This module handles various logging capabilities.
@ PTP_LOG_BMCA
Notifies the user about BMCA state changes.
Definition: logging.h:27
@ PTP_LOG_INFO
If enabled, the user will be notified of unexpected events occurred and exceptions.
Definition: logging.h:25
@ PTP_LOG_CORR_FIELD
The PTP engine will print the correction fields of particular PTP messages.
Definition: logging.h:23
@ PTP_LOG_LOCKED_STATE
Signals the user if the PTP engine considers the clock have gotten locked.
Definition: logging.h:26
@ PTP_LOG_LOGID
Prints formatted identifier before each log line.
Definition: logging.h:29
@ PTP_LOG_TIMESTAMPS
The PTP engine will print the T1-T4/T6 timestamps (in E2E/P2P modes).
Definition: logging.h:24
@ PTP_LOG_DEF
Default PTP log, prints sync-cycle related data (e.g. time error, tuning, code word etc....
Definition: logging.h:22
#define MIN(a, b)
Definition: minmax.h:8
#define MAX(a, b)
Definition: minmax.h:14
void ptp_print_profile()
Definition: profiles.c:13
char * PTP_TRANSPORT_TYPE_HINT[]
Hint on transport types.
Definition: profiles.c:9
char * PTP_TRANSPEC_HINT[]
Hint on transport specific field.
Definition: profiles.c:8
char * PTP_DELMECH_HINT[]
Hint on delay mechanism.
Definition: profiles.c:10
This module implements defines a single method that prints a verbose summary of the operating PTP pro...
void ptp_reset()
Definition: ptp_core.c:242
Core of the PTP implementation. Defines functions for message processing, clock tuning,...
const PtpProfileTlvElement * ptp_tlv_chain_preset_get(const char *pName)
const char * ptp_tlv_chain_preset_get_name(size_t i)
const PtpProfile * ptp_profile_preset_get(const char *pName)
size_t ptp_tlv_chain_preset_cnt()
const char * ptp_profile_preset_get_name(size_t i)
size_t ptp_profile_preset_cnt()
This module manages predefined profile presets. It allows their fetching by name or ID.
This module defines the fundamental PTP message and state machine type, flags, bitfields and the PTP ...
@ PTP_TP_IPv4
IPv4 Transport Type.
Definition: ptp_types.h:137
@ PTP_TP_802_3
Ethernet Transport Type.
Definition: ptp_types.h:138
@ PTP_LOGPER_MAX
Maximal logarithmic messaging period.
Definition: ptp_types.h:306
@ PTP_LOGPER_MIN
Minimal logarithmic messaging period.
Definition: ptp_types.h:305
@ PTP_LOGPER_SYNCMATCHED
Messaging occurs whenever a Sync arrives.
Definition: ptp_types.h:307
@ PTP_DM_E2E
End-to-End Delay Mechanism.
Definition: ptp_types.h:145
@ PTP_DM_P2P
Peer-to-Peer Delay Mechanism.
Definition: ptp_types.h:146
@ PTP_TSPEC_GPTP_8021AS
802.1AS Transport Specific Flag
Definition: ptp_types.h:154
@ PTP_TSPEC_UNKNOWN_DEF
Unkown Transport Specific Flag (default)
Definition: ptp_types.h:153
void ptp_time(TimestampU *pT)
void ptp_set_delay_mechanism(PtpDelayMechanism dm)
uint64_t ptp_get_coarse_threshold()
void ptp_set_announce_log_period(int8_t alp)
PtpDelayMechanism ptp_get_delay_mechanism()
void ptp_set_delay_req_log_period(int8_t drlp)
int8_t ptp_get_announce_log_period()
void ptp_set_transport_type(PtpTransportType tp)
void ptp_set_clock_offset(int32_t offset)
PtpTransportType ptp_get_transport_type()
uint8_t ptp_get_priority2()
uint8_t ptp_get_profile_flags()
uint64_t ptp_get_current_master_clock_identity()
int8_t ptp_get_sync_log_period()
uint8_t ptp_get_priority1()
int8_t ptp_get_delay_req_log_period()
int32_t ptp_get_clock_offset()
uint8_t ptp_get_domain()
void ptp_set_domain(uint8_t domain)
void ptp_set_priority2(uint8_t p2)
void ptp_set_addend(uint32_t addend)
PtpTransportSpecific ptp_get_transport_specific()
void ptp_set_sync_log_period(int8_t slp)
void ptp_set_transport_specific(PtpTransportSpecific tspec)
void ptp_unprefer_master_clock()
void ptp_prefer_master_clock(uint64_t clockId)
uint64_t ptp_get_own_clock_identity()
void ptp_set_tlv_chain_by_name(const char *tlvSet)
void ptp_set_priority1(uint8_t p1)
void ptp_set_profile_flags(uint8_t flags)
const char * ptp_get_loaded_tlv_chain()
uint32_t ptp_get_addend()
void ptp_load_profile(const PtpProfile *pProfile)
void ptp_set_coarse_threshold(uint64_t ns)
This module features functions to tweak around the PTP engine's almost every property.
float ptp_get_tuning()
void ptp_set_tuning(float tuning_ppb)
PTP profile structure.
Definition: ptp_types.h:357
PTP profile additional data list element.
Definition: ptp_types.h:337
Timestamp (signed)
Definition: timeutils.h:33
Timestamp (unsigned)
Definition: timeutils.h:24
uint32_t nanosec
nanoseconds
Definition: timeutils.h:26
uint64_t sec
seconds
Definition: timeutils.h:25
void tsPrint(char *str, const TimestampI *ts)
Definition: timeutils.c:81