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 {
67 return -1;
68 }
69
70 } else {
71 return -1;
72 }
73
74 return 0;
75}
76
77static CMD_FUNCTION(CB_time) {
78 char datetime[24];
79 TimestampU t;
80 ptp_time(&t);
81
82 if (argc > 0 && !strcmp(ppArgs[0], "ns")) {
83 MSG("%" __PRI64_PREFIX "u %u\n", t.sec, t.nanosec);
84 } else {
85 tsPrint(datetime, (const TimestampI *)&t);
86 MSG("%s\n", datetime);
87 }
88
89 return 0;
90}
91
92static CMD_FUNCTION(CB_master) {
93 if (argc > 0) {
94 if (!strcmp(ppArgs[0], "prefer")) {
96 if (argc > 1) {
97 idM = hextoclkid(ppArgs[1]);
98 }
100 } else if (!strcmp(ppArgs[0], "unprefer")) {
102 }
103 }
104
105 MSG("Master clock ID: ");
107 MSG("\n");
108 return 0;
109}
110
111static CMD_FUNCTION(CB_ptpinfo) {
112 MSG("Own clock ID: ");
114 MSG("\nMaster clock ID: ");
116 MSG("\n");
117 return 0;
118}
119
120static CMD_FUNCTION(CB_ptpdomain) {
121 if (argc > 0) {
122 ptp_set_domain(atoi(ppArgs[0]));
123 }
124 MSG("PTP domain: %d\n", (int)ptp_get_domain());
125 return 0;
126}
127
128#ifdef PTP_ADDEND_INTERFACE
129static CMD_FUNCTION(CB_addend) {
130 if (argc > 0) {
131 ptp_set_addend((uint32_t)atoll(ppArgs[0]));
132 }
133 MSG("Addend: %u\n", ptp_get_addend());
134 return 0;
135}
136#elif defined(PTP_HLT_INTERFACE)
137static CMD_FUNCTION(CB_tuning) {
138 if (argc > 0) {
139 ptp_set_tuning((uint32_t)atof(ppArgs[0]));
140 }
141 MSG("Tuning: %.4f\n", ptp_get_tuning());
142 return 0;
143}
144#endif
145
146static CMD_FUNCTION(CB_transportType) {
147 if (argc > 0) {
148 if (!strcmp(ppArgs[0], "ipv4")) {
150 } else if (!strcmp(ppArgs[0], "802.3")) {
152 }
153 }
154
155 MSG("Transport layer: %s\n", PTP_TRANSPORT_TYPE_HINT[ptp_get_transport_type()]);
156 return 0;
157}
158
159static CMD_FUNCTION(CB_delayMechanism) {
160 if (argc > 0) { // If changing delay mechanism, PTP will be inherently reset!
161 if (!strcmp(ppArgs[0], "e2e")) {
163 } else if (!strcmp(ppArgs[0], "p2p")) {
165 }
166 }
167
168 MSG("Delay mechanism: %s\n", PTP_DELMECH_HINT[(int)ptp_get_delay_mechanism()]);
169 return 0;
170}
171
172static CMD_FUNCTION(CB_transpec) {
173 if (argc > 0) { // ...inherent reset!
174 if (!strcmp(ppArgs[0], "def") || !strcmp(ppArgs[0], "unknown")) {
176 } else if (!strcmp(ppArgs[0], "gPTP")) {
178 }
179 }
180
181 MSG("PTP transport specific: %s\n", PTP_TRANSPEC_HINT[(int)ptp_get_transport_specific()]);
182 return 0;
183}
184
185static CMD_FUNCTION(CB_profile) {
186 bool printProfileSummary = true;
187 if (argc > 0 && !strcmp(ppArgs[0], "preset")) {
188 if (argc > 1) {
189 const PtpProfile *pProf = ptp_profile_preset_get(ppArgs[1]);
190 if (pProf) {
191 MSG("Loading preset '%s'...\n\n", ppArgs[1]);
192 ptp_load_profile(pProf); // ...inherent reset!
193 } else {
194 MSG("Profile preset '%s' is unknown, settings untouched!\n", ppArgs[1]);
195 }
196 } else {
197 MSG("PTP profile presets: ");
198 size_t N = ptp_profile_preset_cnt();
199 size_t i;
200 for (i = 0; i < N; i++) {
201 MSG("%s", ptp_profile_preset_get_name(i));
202 if ((i + 1) != N) {
203 MSG(", ");
204 }
205 }
206 MSG("\n");
207 printProfileSummary = false;
208 }
209 }
210
211 if (printProfileSummary) {
213 }
214 return 0;
215}
216
217static CMD_FUNCTION(CB_tlv) {
218 bool printLoadedTlvPresetChain = true;
219 if (argc > 0) {
220 if (!strcmp(ppArgs[0], "preset")) {
221 if (argc > 1) {
222 const PtpProfileTlvElement *pTlv = ptp_tlv_chain_preset_get(ppArgs[1]);
223 if (pTlv) {
224 MSG("Loading TLV-chain '%s'...\n\n", ppArgs[1]);
225 ptp_set_tlv_chain_by_name(ppArgs[1]); // ...inherent reset!
226 } else {
227 MSG("TLV-chain preset '%s' is unknown, settings are not tampered with!\n", ppArgs[1]);
228 }
229 printLoadedTlvPresetChain = false;
230
231 } else {
232 MSG("TLV-chain presets: ");
233 size_t N = ptp_tlv_chain_preset_cnt();
234 size_t i;
235 for (i = 0; i < N; i++) {
236 MSG("%s", ptp_tlv_chain_preset_get_name(i));
237 if ((i + 1) != N) {
238 MSG(", ");
239 }
240 }
241 MSG("\n");
242
243 printLoadedTlvPresetChain = false;
244 }
245 } else if (!strcmp(ppArgs[0], "unload")) {
246 MSG("Unloading any TLV-chain...\n\n");
248 printLoadedTlvPresetChain = false;
249 }
250 }
251
252 if (printLoadedTlvPresetChain) {
253 MSG("Loaded TLV-chain: ");
254 const char *tlvSet = ptp_get_loaded_tlv_chain();
255 if (!strcmp(tlvSet, "")) {
256 MSG("none\n\n");
257 } else {
258 MSG("'%s'\n\n", tlvSet);
259 }
260 }
261
262 return 0;
263}
264
265static CMD_FUNCTION(CB_profile_flags) {
266 if (argc > 0) { // set profile flags
267 uint8_t pf = atoi(ppArgs[0]);
269 }
270
271 MSG("Profile flags: %X\n", ptp_get_profile_flags());
272
273 return 0;
274}
275
276static CMD_FUNCTION(CB_logPeriod) {
277 if (argc > 1) {
278 if (!strcmp(ppArgs[0], "delreq")) {
279 if (!strcmp(ppArgs[1], "match")) {
281 } else {
282 int8_t lp = atoi(ppArgs[1]);
285 }
286 } else if (!strcmp(ppArgs[0], "sync")) {
287 int8_t lp = atoi(ppArgs[1]);
290 } else if (!strcmp(ppArgs[0], "ann")) {
291 int8_t lp = atoi(ppArgs[1]);
294 }
295 }
296
297 MSG("(P)Delay_Req log. period: ");
298 int8_t drlp = ptp_get_delay_req_log_period();
299 if (drlp != PTP_LOGPER_SYNCMATCHED) {
300 MSG("%d\n", drlp);
301 } else {
302 MSG("MATCHED\n");
303 }
304
305 MSG("Sync log. period: %d\n", ptp_get_sync_log_period());
306 MSG("Announce log. period: %d\n", ptp_get_announce_log_period());
307
308 return 0;
309}
310
311static CMD_FUNCTION(CB_coarseThreshold) {
312 if (argc > 0) {
313 ptp_set_coarse_threshold(atoi(ppArgs[0]));
314 }
315
316 MSG("PTP coarse correction threshold: %" __PRI64_PREFIX "u ns\n", ptp_get_coarse_threshold());
317 return 0;
318}
319
320static CMD_FUNCTION(CB_priority) {
321 if (argc >= 2) {
322 ptp_set_priority1(atoi(ppArgs[0]));
323 ptp_set_priority2(atoi(ppArgs[1]));
324 }
325
326 MSG("PTP priorities: priority1: %u, priority2: %u\n", ptp_get_priority1(), ptp_get_priority2());
327 return 0;
328}
329
330// command assignments
331enum PTP_CMD_IDS {
332 CMD_RESET,
333 CMD_OFFSET,
334 CMD_LOG,
335 CMD_TIME,
336 CMD_MASTER,
337 CMD_PTPINFO,
338 CMD_PTPDOMAIN,
339 CMD_ADDEND_TUNING,
340 CMD_TRANSPORTTYPE,
341 CMD_DELAYMECH,
342 CMD_TRANSPEC,
343 CMD_PROFILE,
344 CMD_TLV,
345 CMD_PROFILE_FLAGS,
346 CMD_LOGPERIOD,
347 CMD_COARSE_THRESHOLD,
348 CMD_PRIORITY,
349 CMD_N
350};
351
352// command descriptors
353static int sCmds[CMD_N + 1];
354
355#endif // CLI_REG_CMD
356
357// register cli commands
359#ifdef CLI_REG_CMD
360 sCmds[CMD_RESET] = CLI_REG_CMD("ptp reset \t\t\tReset PTP subsystem", 2, 0, CB_reset);
361 sCmds[CMD_OFFSET] = CLI_REG_CMD("ptp servo offset [offset_ns] \t\t\tSet or query clock offset", 3, 0, CB_offset);
362 sCmds[CMD_LOG] = CLI_REG_CMD("ptp log {def|corr|ts|info|locked|bmca} {on|off} \t\t\tTurn on or off logging", 2, 2, CB_log);
363 sCmds[CMD_TIME] = CLI_REG_CMD("time [ns] \t\t\tPrint time", 1, 0, CB_time);
364 sCmds[CMD_MASTER] = CLI_REG_CMD("ptp master [[un]prefer] [clockid] \t\t\tMaster clock settings", 2, 0, CB_master);
365 sCmds[CMD_PTPINFO] = CLI_REG_CMD("ptp info \t\t\tPrint PTP info", 2, 0, CB_ptpinfo);
366 sCmds[CMD_PTPDOMAIN] = CLI_REG_CMD("ptp domain [domain]\t\t\tPrint or set PTP domain", 2, 0, CB_ptpdomain);
367#ifdef PTP_ADDEND_INTERFACE
368 sCmds[CMD_ADDEND_TUNING] = CLI_REG_CMD("ptp addend [addend]\t\t\tPrint or set addend", 2, 0, CB_addend);
369#elif defined(PTP_HLT_INTERFACE)
370 sCmds[CMD_ADDEND_TUNING] = CLI_REG_CMD("ptp tuning [tuning]\t\t\tPrint or set tuning", 2, 0, CB_tuning);
371#endif
372 sCmds[CMD_TRANSPORTTYPE] = CLI_REG_CMD("ptp transport [{ipv4|802.3}]\t\t\tSet or get PTP transport layer", 2, 0, CB_transportType);
373 sCmds[CMD_DELAYMECH] = CLI_REG_CMD("ptp delmech [{e2e|p2p}]\t\t\tSet or get PTP delay mechanism", 2, 0, CB_delayMechanism);
374 sCmds[CMD_TRANSPEC] = CLI_REG_CMD("ptp transpec [{def|gPTP}]\t\t\tSet or get PTP transportSpecific field (majorSdoId)", 2, 0, CB_transpec);
375 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);
376 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);
377 sCmds[CMD_PROFILE_FLAGS] = CLI_REG_CMD("ptp pflags [<flags>]\t\t\tPrint or set profile flags", 2, 0, CB_profile_flags);
378 sCmds[CMD_LOGPERIOD] = CLI_REG_CMD("ptp period <delreq|sync|ann> [<lp>|matched]\t\t\tPrint or set log. periods", 2, 0, CB_logPeriod);
379 sCmds[CMD_COARSE_THRESHOLD] = CLI_REG_CMD("ptp coarse [threshold]\t\t\tPrint or set coarse correction threshold", 2, 0, CB_coarseThreshold);
380 sCmds[CMD_PRIORITY] = CLI_REG_CMD("ptp priority [<p1> <p2>]\t\t\tPrint or set clock priority fields", 2, 0, CB_priority);
381 sCmds[CMD_N] = -1;
382#endif // CLI_REG_CMD
383}
384
386#ifdef CLI_REMOVE_CMD
387 for (uint8_t i = 0; i < CMD_N; i++) {
388 CLI_REMOVE_CMD(i);
389 }
390#endif // CLI_REMOVE_CMD
391}
void ptp_register_cli_commands()
Definition: cli_cmds.c:358
void ptp_remove_cli_commands()
Definition: cli_cmds.c:385
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:51
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_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:234
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:305
@ PTP_LOGPER_MIN
Minimal logarithmic messaging period.
Definition: ptp_types.h:304
@ PTP_LOGPER_SYNCMATCHED
Messaging occurs whenever a Sync arrives.
Definition: ptp_types.h:306
@ 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:356
PTP profile additional data list element.
Definition: ptp_types.h:336
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