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 <string.h>
4
5#include "clock_utils.h"
6#include "logging.h"
7#include "profiles.h"
8#include "ptp_core.h"
10#include "ptp_types.h"
11#include "settings_interface.h"
12
13#ifdef MIN
14#undef MIN
15#endif
16
17#define MIN(a, b) (((a) < (b)) ? (a) : (b))
18
19#ifdef MAX
20#undef MAX
21#endif
22
23#define MAX(a, b) (((a) > (b)) ? (a) : (b))
24
25
26// #define S (gPtpCoreState)
27
28// ---- COMPILE ONLY IF CLI_REG_CMD is provided ----
29
30#ifdef CLI_REG_CMD
31
32static int CB_reset(const CliToken_Type *ppArgs, uint8_t argc) {
33 ptp_reset();
34 MSG("> PTP reset!\n");
35 return 0;
36}
37
38static int CB_offset(const CliToken_Type *ppArgs, uint8_t argc) {
39 if (argc > 0) {
40 ptp_set_clock_offset(atoi(ppArgs[0]));
41 }
42
43 MSG("> PTP clock offset: %d ns\n", ptp_get_clock_offset());
44 return 0;
45}
46
47static int CB_log(const CliToken_Type *ppArgs, uint8_t argc) {
48 bool logEn = false;
49
50 if (argc > 1) {
51 if (!strcmp(ppArgs[1], "on")) {
52 logEn = true;
53 } else if (!strcmp(ppArgs[1], "off")) {
54 logEn = false;
55 } else {
56 return -1;
57 }
58
59 if (!strcmp(ppArgs[0], "def")) {
61 } else if (!strcmp(ppArgs[0], "corr")) {
63 } else if (!strcmp(ppArgs[0], "ts")) {
65 } else if (!strcmp(ppArgs[0], "info")) {
67 } else if (!strcmp(ppArgs[0], "locked")) {
69 } else if (!strcmp(ppArgs[0], "bmca")) {
71 } else {
72 return -1;
73 }
74
75 } else {
76 return -1;
77 }
78
79 return 0;
80}
81
82static int CB_time(const CliToken_Type *ppArgs, uint8_t argc) {
83 char datetime[24];
84 TimestampU t;
85 ptp_time(&t);
86
87 if (argc > 0 && !strcmp(ppArgs[0], "ns")) {
88 MSG("%lu %u\n", t.sec, t.nanosec);
89 } else {
90 tsPrint(datetime, (const TimestampI *)&t);
91 MSG("%s\n", datetime);
92 }
93
94 return 0;
95}
96
97static int CB_master(const CliToken_Type *ppArgs, uint8_t argc) {
98 if (argc > 0) {
99 if (!strcmp(ppArgs[0], "prefer")) {
101 if (argc > 1) {
102 idM = hextoclkid(ppArgs[1]);
103 }
105 } else if (!strcmp(ppArgs[0], "unprefer")) {
107 }
108 }
109
110 MSG("Master clock ID: ");
112 MSG("\n");
113 return 0;
114}
115
116static int CB_ptpinfo(const CliToken_Type *ppArgs, uint8_t argc) {
117 MSG("Own clock ID: ");
119 MSG("\nMaster clock ID: ");
121 MSG("\n");
122 return 0;
123}
124
125static int CB_ptpdomain(const CliToken_Type *ppArgs, uint8_t argc) {
126 if (argc > 0) {
127 ptp_set_domain(atoi(ppArgs[0]));
128 }
129 MSG("PTP domain: %d\n", (int)ptp_get_domain());
130 return 0;
131}
132
133static int CB_addend(const CliToken_Type *ppArgs, uint8_t argc) {
134 if (argc > 0) {
135 ptp_set_addend((uint32_t)atol(ppArgs[0]));
136 }
137 MSG("Addend: %u\n", ptp_get_addend());
138 return 0;
139}
140
141static int CB_transportType(const CliToken_Type *ppArgs, uint8_t argc) {
142 if (argc > 0) {
143 if (!strcmp(ppArgs[0], "ipv4")) {
145 } else if (!strcmp(ppArgs[0], "802.3")) {
147 }
148 }
149
150 MSG("Transport layer: %s\n", PTP_TRANSPORT_TYPE_HINT[ptp_get_transport_type()]);
151 return 0;
152}
153
154static int CB_delayMechanism(const CliToken_Type *ppArgs, uint8_t argc) {
155 if (argc > 0) { // If changing delay mechanism, PTP will be inherently reset!
156 if (!strcmp(ppArgs[0], "e2e")) {
158 } else if (!strcmp(ppArgs[0], "p2p")) {
160 }
161 }
162
163 MSG("Delay mechanism: %s\n", PTP_DELMECH_HINT[(int)ptp_get_delay_mechanism()]);
164 return 0;
165}
166
167static int CB_transpec(const CliToken_Type *ppArgs, uint8_t argc) {
168 if (argc > 0) { // ...inherent reset!
169 if (!strcmp(ppArgs[0], "def") || !strcmp(ppArgs[0], "unknown")) {
171 } else if (!strcmp(ppArgs[0], "gPTP")) {
173 }
174 }
175
176 MSG("PTP transport specific: %s\n", PTP_TRANSPEC_HINT[(int)ptp_get_transport_specific()]);
177 return 0;
178}
179
180static int CB_profile(const CliToken_Type *ppArgs, uint8_t argc) {
181 bool printProfileSummary = true;
182 if (argc > 0 && !strcmp(ppArgs[0], "preset")) {
183 if (argc > 1) {
184 const PtpProfile *pProf = ptp_profile_preset_get(ppArgs[1]);
185 if (pProf) {
186 MSG("Loading preset '%s'...\n\n", ppArgs[1]);
187 ptp_load_profile(pProf); // ...inherent reset!
188 } else {
189 MSG("Profile preset '%s' is unknown, settings untouched!\n", ppArgs[1]);
190 }
191 } else {
192 MSG("PTP profile presets: ");
193 size_t N = ptp_profile_preset_cnt();
194 size_t i;
195 for (i = 0; i < N; i++) {
196 MSG("%s", ptp_profile_preset_get_name(i));
197 if ((i + 1) != N) {
198 MSG(", ");
199 }
200 }
201 MSG("\n");
202 printProfileSummary = false;
203 }
204 }
205
206 if (printProfileSummary) {
208 }
209 return 0;
210}
211
212static int CB_tlv(const CliToken_Type *ppArgs, uint8_t argc) {
213 bool printLoadedTlvPresetChain = true;
214 if (argc > 0) {
215 if (!strcmp(ppArgs[0], "preset")) {
216 if (argc > 1) {
217 const PtpProfileTlvElement *pTlv = ptp_tlv_chain_preset_get(ppArgs[1]);
218 if (pTlv) {
219 MSG("Loading TLV-chain '%s'...\n\n", ppArgs[1]);
220 ptp_set_tlv_chain_by_name(ppArgs[1]); // ...inherent reset!
221 } else {
222 MSG("TLV-chain preset '%s' is unknown, settings are not tampered with!\n", ppArgs[1]);
223 }
224 printLoadedTlvPresetChain = false;
225
226 } else {
227 MSG("TLV-chain presets: ");
228 size_t N = ptp_tlv_chain_preset_cnt();
229 size_t i;
230 for (i = 0; i < N; i++) {
231 MSG("%s", ptp_tlv_chain_preset_get_name(i));
232 if ((i + 1) != N) {
233 MSG(", ");
234 }
235 }
236 MSG("\n");
237
238 printLoadedTlvPresetChain = false;
239 }
240 } else if (!strcmp(ppArgs[0], "unload")) {
241 MSG("Unloading any TLV-chain...\n\n");
243 printLoadedTlvPresetChain = false;
244 }
245 }
246
247 if (printLoadedTlvPresetChain) {
248 MSG("Loaded TLV-chain: ");
249 const char *tlvSet = ptp_get_loaded_tlv_chain();
250 if (!strcmp(tlvSet, "")) {
251 MSG("none\n\n");
252 } else {
253 MSG("'%s'\n\n", tlvSet);
254 }
255 }
256
257 return 0;
258}
259
260static int CB_profile_flags(const CliToken_Type *ppArgs, uint8_t argc) {
261 if (argc > 0) { // set profile flags
262 uint8_t pf = atoi(ppArgs[0]);
264 }
265
266 MSG("Profile flags: %X\n", ptp_get_profile_flags());
267
268 return 0;
269}
270
271static int CB_logPeriod(const CliToken_Type *ppArgs, uint8_t argc) {
272 if (argc > 1) {
273 if (!strcmp(ppArgs[0], "delreq")) {
274 if (!strcmp(ppArgs[1], "match")) {
276 } else {
277 int8_t lp = atoi(ppArgs[1]);
280 }
281 } else if (!strcmp(ppArgs[0], "sync")) {
282 int8_t lp = atoi(ppArgs[1]);
285 } else if (!strcmp(ppArgs[0], "ann")) {
286 int8_t lp = atoi(ppArgs[1]);
289 }
290 }
291
292 MSG("(P)Delay_Req log. period: ");
293 int8_t drlp = ptp_get_delay_req_log_period();
294 if (drlp != PTP_LOGPER_SYNCMATCHED) {
295 MSG("%d\n", drlp);
296 } else {
297 MSG("MATCHED\n");
298 }
299
300 MSG("Sync log. period: %d\n", ptp_get_sync_log_period());
301 MSG("Announce log. period: %d\n", ptp_get_announce_log_period());
302
303 return 0;
304}
305
306static int CB_coarseThreshold(const CliToken_Type *ppArgs, uint8_t argc) {
307 if (argc > 0) {
308 ptp_set_coarse_threshold(atoi(ppArgs[0]));
309 }
310
311 MSG("PTP coarse correction threshold: %lu ns\n", ptp_get_coarse_threshold());
312 return 0;
313}
314
315static int CB_priority(const CliToken_Type *ppArgs, uint8_t argc) {
316 if (argc >= 2) {
317 ptp_set_priority1(atoi(ppArgs[0]));
318 ptp_set_priority2(atoi(ppArgs[1]));
319 }
320
321 MSG("PTP priorities: priority1: %u, priority2: %u\n", ptp_get_priority1(), ptp_get_priority2());
322 return 0;
323}
324
325// command assignments
326enum PTP_CMD_IDS {
327 CMD_RESET,
328 CMD_OFFSET,
329 CMD_LOG,
330 CMD_TIME,
331 CMD_MASTER,
332 CMD_PTPINFO,
333 CMD_PTPDOMAIN,
334 CMD_ADDEND,
335 CMD_TRANSPORTTYPE,
336 CMD_DELAYMECH,
337 CMD_TRANSPEC,
338 CMD_PROFILE,
339 CMD_TLV,
340 CMD_PROFILE_FLAGS,
341 CMD_LOGPERIOD,
342 CMD_COARSE_THRESHOLD,
343 CMD_PRIORITY,
344 CMD_N
345};
346
347// command descriptors
348static int sCmds[CMD_N + 1];
349
350#endif // CLI_REG_CMD
351
352// register cli commands
354#ifdef CLI_REG_CMD
355 sCmds[CMD_RESET] = CLI_REG_CMD("ptp reset \t\t\tReset PTP subsystem", 2, 0, CB_reset);
356 sCmds[CMD_OFFSET] = CLI_REG_CMD("ptp servo offset [offset_ns] \t\t\tSet or query clock offset", 3, 0, CB_offset);
357 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);
358 sCmds[CMD_TIME] = CLI_REG_CMD("time [ns] \t\t\tPrint time", 1, 0, CB_time);
359 sCmds[CMD_MASTER] = CLI_REG_CMD("ptp master [[un]prefer] [clockid] \t\t\tMaster clock settings", 2, 0, CB_master);
360 sCmds[CMD_PTPINFO] = CLI_REG_CMD("ptp info \t\t\tPrint PTP info", 2, 0, CB_ptpinfo);
361 sCmds[CMD_PTPDOMAIN] = CLI_REG_CMD("ptp domain [domain]\t\t\tPrint or set PTP domain", 2, 0, CB_ptpdomain);
362 sCmds[CMD_ADDEND] = CLI_REG_CMD("ptp addend [addend]\t\t\tPrint or set addend", 2, 0, CB_addend);
363 sCmds[CMD_TRANSPORTTYPE] = CLI_REG_CMD("ptp transport [{ipv4|802.3}]\t\t\tSet or get PTP transport layer", 2, 0, CB_transportType);
364 sCmds[CMD_DELAYMECH] = CLI_REG_CMD("ptp delmech [{e2e|p2p}]\t\t\tSet or get PTP delay mechanism", 2, 0, CB_delayMechanism);
365 sCmds[CMD_TRANSPEC] = CLI_REG_CMD("ptp transpec [{def|gPTP}]\t\t\tSet or get PTP transportSpecific field (majorSdoId)", 2, 0, CB_transpec);
366 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);
367 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);
368 sCmds[CMD_PROFILE_FLAGS] = CLI_REG_CMD("ptp pflags [<flags>]\t\t\tPrint or set profile flags", 2, 0, CB_profile_flags);
369 sCmds[CMD_LOGPERIOD] = CLI_REG_CMD("ptp period <delreq|sync|ann> [<lp>|matched]\t\t\tPrint or set log. periods", 2, 0, CB_logPeriod);
370 sCmds[CMD_COARSE_THRESHOLD] = CLI_REG_CMD("ptp coarse [threshold]\t\t\tPrint or set coarse correction threshold", 2, 0, CB_coarseThreshold);
371 sCmds[CMD_PRIORITY] = CLI_REG_CMD("ptp priority [<p1> <p2>]\t\t\tPrint or set clock priority fields", 2, 0, CB_priority);
372 sCmds[CMD_N] = -1;
373#endif // CLI_REG_CMD
374}
375
377#ifdef CLI_REG_CMD
378 cli_remove_command_array(sCmds);
379#endif // CLI_REG_CMD
380}
void ptp_register_cli_commands()
Definition: cli_cmds.c:353
#define MIN(a, b)
Definition: cli_cmds.c:17
void ptp_remove_cli_commands()
Definition: cli_cmds.c:376
#define MAX(a, b)
Definition: cli_cmds.c:23
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:45
This module handles various logging capabilities.
@ PTP_LOG_BMCA
Notifies the user about BMCA state changes.
Definition: logging.h:23
@ PTP_LOG_INFO
If enabled, the user will be notified of unexpected events occurred and exceptions.
Definition: logging.h:21
@ PTP_LOG_CORR_FIELD
The PTP engine will print the correction fields of particular PTP messages.
Definition: logging.h:19
@ PTP_LOG_LOCKED_STATE
Signals the user if the PTP engine consideres the clock have gotten locked.
Definition: logging.h:22
@ PTP_LOG_TIMESTAMPS
The PTP engine will print the T1-T4/T6 timestamps (in E2E/P2P modes).
Definition: logging.h:20
@ PTP_LOG_DEF
Default PTP log, prints sync-cycle related data (e.g. time error, tuning, code word etc....
Definition: logging.h:18
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:165
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:129
@ PTP_TP_802_3
Ethernet Transport Type.
Definition: ptp_types.h:130
@ PTP_LOGPER_MAX
Maximal logarithmic messaging period.
Definition: ptp_types.h:280
@ PTP_LOGPER_MIN
Minimal logarithmic messaging period.
Definition: ptp_types.h:279
@ PTP_LOGPER_SYNCMATCHED
Messaging occurs whenever a Sync arrives.
Definition: ptp_types.h:281
@ PTP_DM_E2E
End-to-End Delay Mechanism.
Definition: ptp_types.h:137
@ PTP_DM_P2P
Peer-to-Peer Delay Mechanism.
Definition: ptp_types.h:138
@ PTP_TSPEC_GPTP_8021AS
802.1AS Transport Specific Flag
Definition: ptp_types.h:146
@ PTP_TSPEC_UNKNOWN_DEF
Unkown Transport Specific Flag (default)
Definition: ptp_types.h:145
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.
PTP profile structure.
Definition: ptp_types.h:331
PTP profile additional data list element.
Definition: ptp_types.h:311
Timestamp (signed)
Definition: timeutils.h:29
Timestamp (unsigned)
Definition: timeutils.h:20
uint32_t nanosec
nanoseconds
Definition: timeutils.h:22
uint64_t sec
seconds
Definition: timeutils.h:21
void tsPrint(char *str, const TimestampI *ts)
Definition: timeutils.c:73