diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2017-11-26 08:25:14 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2017-11-26 08:25:14 +0000 |
commit | e4637bd9ed150244a906bc8b080f649034b68c8f (patch) | |
tree | 4a56d9683737ec68d8f0e5615abfea118eec6426 /ip/iplink_can.c | |
parent | 1934149f47ee4dfe2b22258c2e18f55a510b5889 (diff) | |
parent | 2d868b48b2f313deb4853e8ac5047d05132969c5 (diff) | |
download | platform_external_iproute2-e4637bd9ed150244a906bc8b080f649034b68c8f.tar.gz platform_external_iproute2-e4637bd9ed150244a906bc8b080f649034b68c8f.tar.bz2 platform_external_iproute2-e4637bd9ed150244a906bc8b080f649034b68c8f.zip |
Snap for 4468711 from 2d868b48b2f313deb4853e8ac5047d05132969c5 to pi-releaseandroid-vts-9.0_r9android-vts-9.0_r8android-vts-9.0_r7android-vts-9.0_r6android-vts-9.0_r5android-vts-9.0_r4android-vts-9.0_r14android-vts-9.0_r13android-vts-9.0_r12android-vts-9.0_r11android-vts-9.0_r10android-p-preview-5android-p-preview-4android-p-preview-1android-cts-9.0_r9android-cts-9.0_r8android-cts-9.0_r7android-cts-9.0_r6android-cts-9.0_r5android-cts-9.0_r4android-cts-9.0_r3android-cts-9.0_r2android-cts-9.0_r13android-cts-9.0_r12android-cts-9.0_r11android-cts-9.0_r10android-cts-9.0_r1android-9.0.0_r9android-9.0.0_r8android-9.0.0_r7android-9.0.0_r60android-9.0.0_r6android-9.0.0_r59android-9.0.0_r58android-9.0.0_r57android-9.0.0_r56android-9.0.0_r55android-9.0.0_r54android-9.0.0_r53android-9.0.0_r52android-9.0.0_r51android-9.0.0_r50android-9.0.0_r5android-9.0.0_r49android-9.0.0_r48android-9.0.0_r3android-9.0.0_r2android-9.0.0_r18android-9.0.0_r17android-9.0.0_r10android-9.0.0_r1security-pi-releasepie-vts-releasepie-security-releasepie-s2-releasepie-release-2pie-releasepie-r2-s2-releasepie-r2-s1-releasepie-r2-releasepie-platform-releasepie-gsipie-cuttlefish-testingpie-cts-releasepie-arcp-preview-1
Change-Id: Ic9de3ebd76d093ed177a6197aee2a9beaed4a247
Diffstat (limited to 'ip/iplink_can.c')
-rw-r--r-- | ip/iplink_can.c | 342 |
1 files changed, 279 insertions, 63 deletions
diff --git a/ip/iplink_can.c b/ip/iplink_can.c index f1b089df..587413da 100644 --- a/ip/iplink_can.c +++ b/ip/iplink_can.c @@ -23,13 +23,11 @@ static void print_usage(FILE *f) { fprintf(f, "Usage: ip link set DEVICE type can\n" - "\t[ bitrate BITRATE [ sample-point SAMPLE-POINT] ] | \n" - "\t[ tq TQ prop-seg PROP_SEG phase-seg1 PHASE-SEG1\n " - "\t phase-seg2 PHASE-SEG2 [ sjw SJW ] ]\n" + "\t[ bitrate BITRATE [ sample-point SAMPLE-POINT] ] |\n" + "\t[ tq TQ prop-seg PROP_SEG phase-seg1 PHASE-SEG1\n \t phase-seg2 PHASE-SEG2 [ sjw SJW ] ]\n" "\n" - "\t[ dbitrate BITRATE [ dsample-point SAMPLE-POINT] ] | \n" - "\t[ dtq TQ dprop-seg PROP_SEG dphase-seg1 PHASE-SEG1\n " - "\t dphase-seg2 PHASE-SEG2 [ dsjw SJW ] ]\n" + "\t[ dbitrate BITRATE [ dsample-point SAMPLE-POINT] ] |\n" + "\t[ dtq TQ dprop-seg PROP_SEG dphase-seg1 PHASE-SEG1\n \t dphase-seg2 PHASE-SEG2 [ dsjw SJW ] ]\n" "\n" "\t[ loopback { on | off } ]\n" "\t[ listen-only { on | off } ]\n" @@ -43,6 +41,8 @@ static void print_usage(FILE *f) "\t[ restart-ms TIME-MS ]\n" "\t[ restart ]\n" "\n" + "\t[ termination { 0..65535 } ]\n" + "\n" "\tWhere: BITRATE := { 1..1000000 }\n" "\t SAMPLE-POINT := { 0.000..0.999 }\n" "\t TQ := { NUMBER }\n" @@ -73,7 +73,7 @@ static int get_float(float *val, const char *arg) return 0; } -static void set_ctrlmode(char* name, char *arg, +static void set_ctrlmode(char *name, char *arg, struct can_ctrlmode *cm, __u32 flags) { if (strcmp(arg, "on") == 0) { @@ -89,11 +89,11 @@ static void set_ctrlmode(char* name, char *arg, static void print_ctrlmode(FILE *f, __u32 cm) { - fprintf(f, "<"); -#define _PF(cmflag, cmname) \ - if (cm & cmflag) { \ - cm &= ~cmflag; \ - fprintf(f, "%s%s", cmname, cm ? "," : ""); \ + open_json_array(PRINT_ANY, is_json_context() ? "ctrlmode" : "<"); +#define _PF(cmflag, cmname) \ + if (cm & cmflag) { \ + cm &= ~cmflag; \ + print_string(PRINT_ANY, NULL, cm ? "%s," : "%s", cmname); \ } _PF(CAN_CTRLMODE_LOOPBACK, "LOOPBACK"); _PF(CAN_CTRLMODE_LISTENONLY, "LISTEN-ONLY"); @@ -105,18 +105,16 @@ static void print_ctrlmode(FILE *f, __u32 cm) _PF(CAN_CTRLMODE_PRESUME_ACK, "PRESUME-ACK"); #undef _PF if (cm) - fprintf(f, "%x", cm); - fprintf(f, "> "); + print_hex(PRINT_ANY, NULL, "%x", cm); + close_json_array(PRINT_ANY, "> "); } static int can_parse_opt(struct link_util *lu, int argc, char **argv, struct nlmsghdr *n) { - struct can_bittiming bt, dbt; + struct can_bittiming bt = {}, dbt = {}; struct can_ctrlmode cm = {0, 0}; - memset(&bt, 0, sizeof(bt)); - memset(&dbt, 0, sizeof(dbt)); while (argc > 0) { if (matches(*argv, "bitrate") == 0) { NEXT_ARG(); @@ -224,6 +222,14 @@ static int can_parse_opt(struct link_util *lu, int argc, char **argv, if (get_u32(&val, *argv, 0)) invarg("invalid \"restart-ms\" value\n", *argv); addattr32(n, 1024, IFLA_CAN_RESTART_MS, val); + } else if (matches(*argv, "termination") == 0) { + __u16 val; + + NEXT_ARG(); + if (get_u16(&val, *argv, 0)) + invarg("invalid \"termination\" value\n", + *argv); + addattr16(n, 1024, IFLA_CAN_TERMINATION, val); } else if (matches(*argv, "help") == 0) { usage(); return -1; @@ -245,7 +251,7 @@ static int can_parse_opt(struct link_util *lu, int argc, char **argv, return 0; } -static const char *can_state_names[] = { +static const char *can_state_names[CAN_STATE_MAX] = { [CAN_STATE_ERROR_ACTIVE] = "ERROR-ACTIVE", [CAN_STATE_ERROR_WARNING] = "ERROR-WARNING", [CAN_STATE_ERROR_PASSIVE] = "ERROR-PASSIVE", @@ -254,6 +260,14 @@ static const char *can_state_names[] = { [CAN_STATE_SLEEPING] = "SLEEPING" }; +static void can_print_json_timing_min_max(const char *attr, int min, int max) +{ + open_json_object(attr); + print_int(PRINT_JSON, "min", NULL, min); + print_int(PRINT_JSON, "max", NULL, max); + close_json_object(); +} + static void can_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) { if (!tb) @@ -267,79 +281,267 @@ static void can_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) } if (tb[IFLA_CAN_STATE]) { - int *state = RTA_DATA(tb[IFLA_CAN_STATE]); + uint32_t state = rta_getattr_u32(tb[IFLA_CAN_STATE]); - fprintf(f, "state %s ", *state <= CAN_STATE_MAX ? - can_state_names[*state] : "UNKNOWN"); + fprintf(f, "state %s ", state < CAN_STATE_MAX ? + can_state_names[state] : "UNKNOWN"); } if (tb[IFLA_CAN_BERR_COUNTER]) { struct can_berr_counter *bc = RTA_DATA(tb[IFLA_CAN_BERR_COUNTER]); - fprintf(f, "(berr-counter tx %d rx %d) ", bc->txerr, bc->rxerr); + if (is_json_context()) { + open_json_object("berr_counter"); + print_int(PRINT_JSON, "tx", NULL, bc->txerr); + print_int(PRINT_JSON, "rx", NULL, bc->rxerr); + close_json_object(); + } else { + fprintf(f, "(berr-counter tx %d rx %d) ", + bc->txerr, bc->rxerr); + } } if (tb[IFLA_CAN_RESTART_MS]) { __u32 *restart_ms = RTA_DATA(tb[IFLA_CAN_RESTART_MS]); - fprintf(f, "restart-ms %d ", *restart_ms); + print_int(PRINT_ANY, + "restart_ms", + "restart-ms %d ", + *restart_ms); } - if (tb[IFLA_CAN_BITTIMING]) { + /* bittiming is irrelevant if fixed bitrate is defined */ + if (tb[IFLA_CAN_BITTIMING] && !tb[IFLA_CAN_BITRATE_CONST]) { struct can_bittiming *bt = RTA_DATA(tb[IFLA_CAN_BITTIMING]); - fprintf(f, "\n " - "bitrate %d sample-point %.3f ", - bt->bitrate, (float)bt->sample_point / 1000.); - fprintf(f, "\n " - "tq %d prop-seg %d phase-seg1 %d phase-seg2 %d sjw %d", - bt->tq, bt->prop_seg, bt->phase_seg1, bt->phase_seg2, - bt->sjw); + if (is_json_context()) { + open_json_object("bittiming"); + print_int(PRINT_ANY, "bitrate", NULL, bt->bitrate); + jsonw_float_field_fmt(get_json_writer(), + "sample_point", "%.3f", + (float) bt->sample_point / 1000.); + print_int(PRINT_ANY, "tq", NULL, bt->tq); + print_int(PRINT_ANY, "prop_seg", NULL, bt->prop_seg); + print_int(PRINT_ANY, "phase_seg1", + NULL, bt->phase_seg1); + print_int(PRINT_ANY, "phase_seg2", + NULL, bt->phase_seg2); + print_int(PRINT_ANY, "sjw", NULL, bt->sjw); + close_json_object(); + } else { + fprintf(f, "\n bitrate %d sample-point %.3f ", + bt->bitrate, (float) bt->sample_point / 1000.); + fprintf(f, + "\n tq %d prop-seg %d phase-seg1 %d phase-seg2 %d sjw %d", + bt->tq, bt->prop_seg, + bt->phase_seg1, bt->phase_seg2, + bt->sjw); + } } - if (tb[IFLA_CAN_BITTIMING_CONST]) { + /* bittiming const is irrelevant if fixed bitrate is defined */ + if (tb[IFLA_CAN_BITTIMING_CONST] && !tb[IFLA_CAN_BITRATE_CONST]) { struct can_bittiming_const *btc = RTA_DATA(tb[IFLA_CAN_BITTIMING_CONST]); - fprintf(f, "\n " - "%s: tseg1 %d..%d tseg2 %d..%d " - "sjw 1..%d brp %d..%d brp-inc %d", - btc->name, btc->tseg1_min, btc->tseg1_max, - btc->tseg2_min, btc->tseg2_max, btc->sjw_max, - btc->brp_min, btc->brp_max, btc->brp_inc); + if (is_json_context()) { + open_json_object("bittiming_const"); + print_string(PRINT_JSON, "name", NULL, btc->name); + can_print_json_timing_min_max("tseg1", + btc->tseg1_min, + btc->tseg1_max); + can_print_json_timing_min_max("tseg2", + btc->tseg2_min, + btc->tseg2_max); + can_print_json_timing_min_max("sjw", 1, btc->sjw_max); + can_print_json_timing_min_max("brp", + btc->brp_min, + btc->brp_max); + print_int(PRINT_JSON, "brp_inc", NULL, btc->brp_inc); + close_json_object(); + } else { + fprintf(f, "\n %s: tseg1 %d..%d tseg2 %d..%d " + "sjw 1..%d brp %d..%d brp-inc %d", + btc->name, btc->tseg1_min, btc->tseg1_max, + btc->tseg2_min, btc->tseg2_max, btc->sjw_max, + btc->brp_min, btc->brp_max, btc->brp_inc); + } + } + + if (tb[IFLA_CAN_BITRATE_CONST]) { + __u32 *bitrate_const = RTA_DATA(tb[IFLA_CAN_BITRATE_CONST]); + int bitrate_cnt = RTA_PAYLOAD(tb[IFLA_CAN_BITRATE_CONST]) / + sizeof(*bitrate_const); + int i; + __u32 bitrate = 0; + + if (tb[IFLA_CAN_BITTIMING]) { + struct can_bittiming *bt = + RTA_DATA(tb[IFLA_CAN_BITTIMING]); + bitrate = bt->bitrate; + } + + if (is_json_context()) { + print_uint(PRINT_JSON, + "bittiming_bitrate", + NULL, bitrate); + open_json_array(PRINT_JSON, "bitrate_const"); + for (i = 0; i < bitrate_cnt; ++i) + print_uint(PRINT_JSON, NULL, NULL, + bitrate_const[i]); + close_json_array(PRINT_JSON, NULL); + } else { + fprintf(f, "\n bitrate %u", bitrate); + fprintf(f, "\n ["); + + for (i = 0; i < bitrate_cnt - 1; ++i) { + /* This will keep lines below 80 signs */ + if (!(i % 6) && i) + fprintf(f, "\n "); + + fprintf(f, "%8u, ", bitrate_const[i]); + } + + if (!(i % 6) && i) + fprintf(f, "\n "); + fprintf(f, "%8u ]", bitrate_const[i]); + } } - if (tb[IFLA_CAN_DATA_BITTIMING]) { + /* data bittiming is irrelevant if fixed bitrate is defined */ + if (tb[IFLA_CAN_DATA_BITTIMING] && !tb[IFLA_CAN_DATA_BITRATE_CONST]) { struct can_bittiming *dbt = RTA_DATA(tb[IFLA_CAN_DATA_BITTIMING]); - fprintf(f, "\n " - "dbitrate %d dsample-point %.3f ", - dbt->bitrate, (float)dbt->sample_point / 1000.); - fprintf(f, "\n " - "dtq %d dprop-seg %d dphase-seg1 %d " - "dphase-seg2 %d dsjw %d", - dbt->tq, dbt->prop_seg, dbt->phase_seg1, - dbt->phase_seg2, dbt->sjw); + if (is_json_context()) { + open_json_object("data_bittiming"); + print_int(PRINT_JSON, "bitrate", NULL, dbt->bitrate); + jsonw_float_field_fmt(get_json_writer(), + "sample_point", + "%.3f", + (float) dbt->sample_point / 1000.); + print_int(PRINT_JSON, "tq", NULL, dbt->tq); + print_int(PRINT_JSON, "prop_seg", NULL, dbt->prop_seg); + print_int(PRINT_JSON, "phase_seg1", + NULL, dbt->phase_seg1); + print_int(PRINT_JSON, "phase_seg2", + NULL, dbt->phase_seg2); + print_int(PRINT_JSON, "sjw", NULL, dbt->sjw); + close_json_object(); + } else { + fprintf(f, "\n dbitrate %d dsample-point %.3f ", + dbt->bitrate, + (float) dbt->sample_point / 1000.); + fprintf(f, "\n dtq %d dprop-seg %d dphase-seg1 %d " + "dphase-seg2 %d dsjw %d", + dbt->tq, dbt->prop_seg, dbt->phase_seg1, + dbt->phase_seg2, dbt->sjw); + } } - if (tb[IFLA_CAN_DATA_BITTIMING_CONST]) { + /* data bittiming const is irrelevant if fixed bitrate is defined */ + if (tb[IFLA_CAN_DATA_BITTIMING_CONST] && + !tb[IFLA_CAN_DATA_BITRATE_CONST]) { struct can_bittiming_const *dbtc = RTA_DATA(tb[IFLA_CAN_DATA_BITTIMING_CONST]); - fprintf(f, "\n " - "%s: dtseg1 %d..%d dtseg2 %d..%d " - "dsjw 1..%d dbrp %d..%d dbrp-inc %d", - dbtc->name, dbtc->tseg1_min, dbtc->tseg1_max, - dbtc->tseg2_min, dbtc->tseg2_max, dbtc->sjw_max, - dbtc->brp_min, dbtc->brp_max, dbtc->brp_inc); + if (is_json_context()) { + open_json_object("data_bittiming_const"); + print_string(PRINT_JSON, "name", NULL, dbtc->name); + can_print_json_timing_min_max("tseg1", + dbtc->tseg1_min, + dbtc->tseg1_max); + can_print_json_timing_min_max("tseg2", + dbtc->tseg2_min, + dbtc->tseg2_max); + can_print_json_timing_min_max("sjw", 1, dbtc->sjw_max); + can_print_json_timing_min_max("brp", + dbtc->brp_min, + dbtc->brp_max); + + print_int(PRINT_JSON, "brp_inc", NULL, dbtc->brp_inc); + close_json_object(); + } else { + fprintf(f, "\n %s: dtseg1 %d..%d dtseg2 %d..%d " + "dsjw 1..%d dbrp %d..%d dbrp-inc %d", + dbtc->name, dbtc->tseg1_min, dbtc->tseg1_max, + dbtc->tseg2_min, dbtc->tseg2_max, dbtc->sjw_max, + dbtc->brp_min, dbtc->brp_max, dbtc->brp_inc); + } + } + + if (tb[IFLA_CAN_DATA_BITRATE_CONST]) { + __u32 *dbitrate_const = + RTA_DATA(tb[IFLA_CAN_DATA_BITRATE_CONST]); + int dbitrate_cnt = + RTA_PAYLOAD(tb[IFLA_CAN_DATA_BITRATE_CONST]) / + sizeof(*dbitrate_const); + int i; + __u32 dbitrate = 0; + + if (tb[IFLA_CAN_DATA_BITTIMING]) { + struct can_bittiming *dbt = + RTA_DATA(tb[IFLA_CAN_DATA_BITTIMING]); + dbitrate = dbt->bitrate; + } + + if (is_json_context()) { + print_uint(PRINT_JSON, "data_bittiming_bitrate", + NULL, dbitrate); + open_json_array(PRINT_JSON, "data_bitrate_const"); + for (i = 0; i < dbitrate_cnt; ++i) + print_uint(PRINT_JSON, NULL, NULL, + dbitrate_const[i]); + close_json_array(PRINT_JSON, NULL); + } else { + fprintf(f, "\n dbitrate %u", dbitrate); + fprintf(f, "\n ["); + + for (i = 0; i < dbitrate_cnt - 1; ++i) { + /* This will keep lines below 80 signs */ + if (!(i % 6) && i) + fprintf(f, "\n "); + + fprintf(f, "%8u, ", dbitrate_const[i]); + } + + if (!(i % 6) && i) + fprintf(f, "\n "); + fprintf(f, "%8u ]", dbitrate_const[i]); + } + } + + if (tb[IFLA_CAN_TERMINATION_CONST] && tb[IFLA_CAN_TERMINATION]) { + __u16 *trm = RTA_DATA(tb[IFLA_CAN_TERMINATION]); + __u16 *trm_const = RTA_DATA(tb[IFLA_CAN_TERMINATION_CONST]); + int trm_cnt = RTA_PAYLOAD(tb[IFLA_CAN_TERMINATION_CONST]) / + sizeof(*trm_const); + int i; + + if (is_json_context()) { + print_hu(PRINT_JSON, "termination", NULL, *trm); + open_json_array(PRINT_JSON, "termination_const"); + for (i = 0; i < trm_cnt; ++i) + print_hu(PRINT_JSON, NULL, NULL, trm_const[i]); + close_json_array(PRINT_JSON, NULL); + } else { + fprintf(f, "\n termination %hu [ ", *trm); + + for (i = 0; i < trm_cnt - 1; ++i) + fprintf(f, "%hu, ", trm_const[i]); + + fprintf(f, "%hu ]", trm_const[i]); + } } if (tb[IFLA_CAN_CLOCK]) { struct can_clock *clock = RTA_DATA(tb[IFLA_CAN_CLOCK]); - fprintf(f, "\n clock %d", clock->freq); + print_int(PRINT_ANY, + "clock", + "\n clock %d", + clock->freq); } } @@ -351,18 +553,32 @@ static void can_print_xstats(struct link_util *lu, if (xstats && RTA_PAYLOAD(xstats) == sizeof(*stats)) { stats = RTA_DATA(xstats); - fprintf(f, "\n " - "re-started bus-errors arbit-lost " - "error-warn error-pass bus-off"); - fprintf(f, "\n %-10d %-10d %-10d %-10d %-10d %-10d", - stats->restarts, stats->bus_error, - stats->arbitration_lost, stats->error_warning, - stats->error_passive, stats->bus_off); + + if (is_json_context()) { + print_int(PRINT_JSON, "restarts", + NULL, stats->restarts); + print_int(PRINT_JSON, "bus_error", + NULL, stats->bus_error); + print_int(PRINT_JSON, "arbitration_lost", + NULL, stats->arbitration_lost); + print_int(PRINT_JSON, "error_warning", + NULL, stats->error_warning); + print_int(PRINT_JSON, "error_passive", + NULL, stats->error_passive); + print_int(PRINT_JSON, "bus_off", NULL, stats->bus_off); + } else { + fprintf(f, "\n re-started bus-errors arbit-lost " + "error-warn error-pass bus-off"); + fprintf(f, "\n %-10d %-10d %-10d %-10d %-10d %-10d", + stats->restarts, stats->bus_error, + stats->arbitration_lost, stats->error_warning, + stats->error_passive, stats->bus_off); + } } } static void can_print_help(struct link_util *lu, int argc, char **argv, - FILE *f) + FILE *f) { print_usage(f); } |