📄 scantool_cli.c
字号:
static voidformat_fuel(char *buf, int english, struct pid *p, response_t *data, int n){ int s = DATA_1(p, n, data); switch (s) { case 1 << 0: sprintf(buf, "Open"); break; case 1 << 1: sprintf(buf, "Closed"); break; case 1 << 2: sprintf(buf, "Open-Driving"); break; case 1 << 3: sprintf(buf, "Open-Fault"); break; case 1 << 4: sprintf(buf, "Closed-Fault"); break; default: sprintf(buf, "Open(rsvd)"); break; } /* XXX Fuel system 2 status */}static voidformat_data(char *buf, int english, struct pid *p, response_t *data, int n){ double v; v = DATA_SCALED(p, DATA_RAW(p, n, data)); if (english && p->fmt2) sprintf(buf, p->fmt2, DATA_ENGLISH(p, v)); else sprintf(buf, p->fmt1, v);}static voidformat_o2(char *buf, int english, struct pid *p, response_t *data, int n){ double v = DATA_SCALED(p, DATA_1(p, n, data)); int t = DATA_1(p, n + 1, data); if (t == 0xff) sprintf(buf, p->fmt1, v); else sprintf(buf, p->fmt2, v, t * p->scale2 + p->offset2);}static voidformat_aux(char *buf, int english, struct pid *p, response_t *data, int n){ sprintf(buf, (DATA_RAW(p, n, data) & 1) ? "PTO Active" : "----");}/* conversion factors from the "units" package */struct pid pids[] = { {0x03, "Fuel System Status", format_fuel, 2}, {0x04, "Calculated Load Value", format_data, 1, "%5.1f%%", (100.0/255)}, {0x05, "Engine Coolant Temperature", format_data, 1, "%3.0fC", 1, -40, "%3.0fF", 1.8, 32}, {0x06, "Short term fuel trim Bank 1", format_data, 1, "%5.1f%%", (100.0/128), -100}, {0x07, "Long term fuel trim Bank 1", format_data, 1, "%5.1f%%", (100.0/128), -100}, {0x08, "Short term fuel trim Bank 2", format_data, 1, "%5.1f%%", (100.0/128), -100}, {0x09, "Long term fuel trim Bank 2", format_data, 1, "%5.1f%%", (100.0/128), -100}, {0x0a, "Fuel Pressure", format_data, 1, "%3.0fkPaG", 3, 0, "%4.1fpsig", 0.14503774}, {0x0b, "Intake Manifold Pressure", format_data, 1, "%3.0fkPaA", 1, 0, "%4.1finHg", 0.29529983}, {0x0c, "Engine RPM", format_data, 2, "%5.0fRPM", 0.25}, {0x0d, "Vehicle Speed", format_data, 1, "%3.0fkm/h", 1, 0, "%3.0fmph", 0.62137119}, {0x0e, "Ignition timing advance Cyl #1", format_data, 1, "%4.1f deg", 0.5, -64}, {0x0f, "Intake Air Temperature", format_data, 1, "%3.0fC", 1, -40, "%3.0fF", 1.8, 32}, {0x10, "Air Flow Rate", format_data, 2, "%6.2fgm/s", 0.01, 0, "%6.1flb/min", 0.13227736}, {0x11, "Absolute Throttle Position", format_data, 1, "%5.1f%%", (100.0/255)}, /* XXX 0x12 Commanded secondary air status */ /* XXX 0x13 Oxygen sensor locations */ {0x14, "Bank 1 Sensor 1 Voltage/Trim", format_o2, 2, "%5.3fV", 0.005, 0, "%5.3fV/%5.1f%%", (100.0/128), -100}, {0x15, "Bank 1 Sensor 2 Voltage/Trim", format_o2, 2, "%5.3fV", 0.005, 0, "%5.3fV/%5.1f%%", (100.0/128), -100}, {0x16, "Bank 1 Sensor 3 Voltage/Trim", format_o2, 2, "%5.3fV", 0.005, 0, "%5.3fV/%5.1f%%", (100.0/128), -100}, {0x17, "Bank 1 Sensor 4 Voltage/Trim", format_o2, 2, "%5.3fV", 0.005, 0, "%5.3fV/%5.1f%%", (100.0/128), -100}, {0x18, "Bank 2 Sensor 1 Voltage/Trim", format_o2, 2, "%5.3fV", 0.005, 0, "%5.3fV/%5.1f%%", (100.0/128), -100}, {0x19, "Bank 2 Sensor 2 Voltage/Trim", format_o2, 2, "%5.3fV", 0.005, 0, "%5.3fV/%5.1f%%", (100.0/128), -100}, {0x1a, "Bank 2 Sensor 3 Voltage/Trim", format_o2, 2, "%5.3fV", 0.005, 0, "%5.3fV/%5.1f%%", (100.0/128), -100}, {0x1b, "Bank 2 Sensor 4 Voltage/Trim", format_o2, 2, "%5.3fV", 0.005, 0, "%5.3fV/%5.1f%%", (100.0/128), -100}, {0x1e, "Auxiliary Input Status", format_aux, 1},};/* * Print the monitorable data out, use SI units by default, or "english" * units */static voidprint_current_data(int english){ char buf[24]; struct pid *p; ecu_data_t *ep; int i; printf("\n\nPress return to checkpoint then return to quit\n"); printf("%-30.30s %-15.15s FreezeFrame\n", "Parameter", "Current"); for (p = pids; p < &pids[ARRAY_SIZE(pids)]; p++) { for (i=0, ep=ecu_info; i<ecu_count; i++, ep++) { if (DATA_VALID(p, ep->mode1_data) || DATA_VALID(p, ep->mode2_data)) { printf("%-30.30s ", p->desc); if (DATA_VALID(p, ep->mode1_data)) p->sprintf(buf, english, p, ep->mode1_data, 2); else sprintf(buf, "-----"); printf("%-15.15s ", buf); if (DATA_VALID(p, ep->mode2_data)) p->sprintf(buf, english, p, ep->mode2_data, 3); else sprintf(buf, "-----"); printf("%-15.15s\n", buf); } } }}static voidlog_response(int ecu, response_t *r){ int i; /* Only print good records */ if (r->type != TYPE_GOOD) return; printf("%d: ", ecu); for (i = 0; i < r->len; i++) { fprintf(global_logfp, "%02x ", r->data[i]); } fprintf(global_logfp, "\n");}static voidlog_current_data(void){ response_t *r; ecu_data_t *ep; int i; if (!global_logfp) return; log_timestamp("D"); fprintf(global_logfp, "MODE 1 DATA\n"); for (i=0, ep=ecu_info; i<ecu_count; i++, ep++) { for (r = ep->mode1_data; r < &ep->mode1_data[ARRAY_SIZE(ep->mode1_data)]; r++) { log_response(i, r); } } log_timestamp("D"); fprintf(global_logfp, "MODE 2 DATA\n"); for (i=0, ep=ecu_info; i<ecu_count; i++, ep++) { for (r = ep->mode2_data; r < &ep->mode2_data[ARRAY_SIZE(ep->mode2_data)]; r++) { log_response(i, r); } }}intcmd_monitor(int argc, char **argv){ int rv; diag_l3_conn_t *d_conn; int english = 0; d_conn = global_l3_conn; if (global_state < STATE_SCANDONE) { printf("SCAN has not been done, please do a scan\n"); return(CMD_OK); } // If user states English or Metric, use that, else use config item if (argc > 1) { if (strcasecmp(argv[1], "english") == 0) english = 1; else if (strcasecmp(argv[1], "metric") == 0) english = 0; else return (CMD_USAGE); } else english = set_display; printf("Please wait\n"); /* * Now just receive data and log it for ever */ while (1) { rv = do_j1979_getdata(1); /* Key pressed */ if (rv == 1) { /* * XX, if ' ' then this is a mark, * if return, then quit */ break; } /* print the data */ print_current_data(english); /* Save the data */ log_current_data(); /* Get/Print current DTCs */ do_j1979_cms(); } return(CMD_OK);}intcmd_scan(int argc, char **argv){ int rv; if (global_state >= STATE_CONNECTED) { printf("Already connected, please disconnect first\n"); return(CMD_FAILED); } rv = ecu_connect(); if (rv == 0) { printf("Connection to ECU established\n"); /* Now ask basic info from ECU */ do_j1979_basics(); /* Now get test results for continuously monitored systems */ do_j1979_cms(); /* And the non continuously monitored tests */ printf("Non-continuously monitored system tests (failures only): -\n"); do_j1979_ncms(0); } else { printf("Connection to ECU failed\n"); printf("Please check :-\n"); printf(" Adapter is connected to PC\n"); printf(" Cable is connected to Vehicle\n"); printf(" Vehicle is switched on\n"); printf(" Vehicle is OBDII compliant\n"); return (CMD_FAILED); } return (CMD_OK);}intcmd_cleardtc(int argc, char **argv){ char *input; if (global_state < STATE_CONNECTED) { printf("Not connected to ECU\n"); return(CMD_OK); } input = basic_get_input("Are you sure you wish to clear the Diagnostic " "Trouble Codes (y/n) ? "); if (!input) return(CMD_OK); if ((strcasecmp(input, "yes") == 0) || (strcasecmp(input, "y")==0)) { if (diag_cleardtc() == 0) printf("Done\n"); else printf("Failed\n"); } else { printf("Not done\n"); } free(input); return (CMD_OK);}intcmd_ecus(int argc, char **argv){ ecu_data_t *ep; int i; if (global_state < STATE_SCANDONE) { printf("SCAN has not been done, please do a scan\n"); return(CMD_OK); } printf("%d ECUs found\n", ecu_count); for (i=0, ep=ecu_info; i<ecu_count; i++, ep++) { printf("ECU %d: Address 0x%02x ", i, ep->ecu_addr & 0xff); if (ep->supress) printf("output supressed for monitor mode\n"); else printf("\n"); } return (CMD_OK);}/* * CLI, returns results as CMD_xxx (such as CMD_EXIT) * If argc is supplied, then this is one shot cli, ie run the command */intdo_cli(struct cmd_tbl_entry *cmd_tbl, char *prompt, int argc, char **argv){ /* Built up argc/argv */ struct cmd_tbl_entry *ctp; int cmd_argc; char *cmd_argv[20]; char *input = NULL; int rv, done; int i; char promptbuf[1024]; rv = 0, done = 0; sprintf(promptbuf, "%s> ", prompt); while (!done) { char *inptr, *s; if (argc == 0) { /* Get Input */ if (input) free(input); input = command_line_input(promptbuf); if (!input) { if (instream == stdin) printf("\n"); break; } /* Parse it */ inptr = input; cmd_argc = 0; while ( (s = strtok(inptr, " ")) != NULL ) { cmd_argv[cmd_argc] = s; cmd_argc++; inptr = NULL; } cmd_argv[cmd_argc] = "\0"; } else /* Use supplied argc */ { cmd_argc = argc; for (i=0; i<=argc; i++) cmd_argv[i] = argv[i]; } if (cmd_argc != 0) { ctp = cmd_tbl; while (ctp->command) { if (strcasecmp(ctp->command, cmd_argv[0]) == 0) { if (ctp->sub_cmd_tbl) { log_command(1, cmd_argv); sprintf(promptbuf,"%s/%s", prompt, ctp->command); /* Sub menu */ rv = do_cli(ctp->sub_cmd_tbl, promptbuf, cmd_argc-1, &cmd_argv[1]); sprintf(promptbuf, "%s> ", prompt); } else { /* Found command */ log_command(cmd_argc, cmd_argv); rv = ctp->routine(cmd_argc, cmd_argv); switch (rv) { case CMD_USAGE: printf("Usage: %s\n", ctp->usage); break; case CMD_EXIT: rv = CMD_EXIT; done = 1; break; case CMD_UP: rv = CMD_UP; done = 1; break; } } break; } if (!done) ctp++; } if (ctp->command == NULL) { printf("Huh? Try \"help\"\n"); } if (argc) { /* Single command */ done = 1; break; } } if (done) break; } if (input) free(input); if (rv == CMD_UP) return(CMD_OK); return(rv);}static intcommand_file(char *filename){ FILE *prev_instream = instream; int status = 0; instream = fopen(filename, "r"); if (!instream) goto out; do_cli(root_cmd_table, progname, 0, NULL); fclose(instream); status = 1;out: instream = prev_instream; return status;}intcmd_source(int argc, char **argv){ char *file; if (argc < 2) { printf("No filename\n"); return (CMD_USAGE); } file = argv[1]; if (!command_file(file)) { printf("Couldn't read %s\n", file); return (CMD_FAILED); } return (CMD_OK);}static voidrc_file(void){ char *homedir, *homeinit; homedir = getenv("HOME"); if (!homedir) return; /* we add "/." and "rc" ... 4 characters */ homeinit = malloc(strlen(homedir) + strlen(progname) + 5); if (!homeinit) return; strcpy(homeinit, homedir); strcat(homeinit, "/."); strcat(homeinit, progname); strcat(homeinit, "rc"); command_file(homeinit); free(homeinit);}voidenter_cli(char *name){ global_logfp = NULL; progname = name; printf("%s: version %s\n", progname, PACKAGE_VERSION); printf("%s: Type HELP for a list of commands\n", progname); printf("%s: Type SCAN to start ODBII Scan\n", progname); printf("%s: Then use MONITOR to monitor real-time data\n", progname); readline_init(); rc_file(); /* And go start CLI */ instream = stdin; (void)do_cli(root_cmd_table, progname, 0, NULL);}/* * ************ * Useful, non specific routines * ************ *//* * Decimal/Octal/Hex to integer routine */int htoi(char *buf){ /* Hex text to int */ int rv = 0; int base = 10; if (buf[0] == '$') { base = 16; buf++; } else if (buf[0] == '0') { base = 8; buf++; if (tolower(buf[0]) == 'x') { base = 16; buf++; } } while (*buf) { char upp = toupper(*buf); int val; if ((upp >= '0') && (upp <= '9')) { val = ((*buf) - '0'); } else if ((upp >= 'A') && (upp <= 'F')) { val = (upp - 'A' + 10); } else { return(-1); } if (val >= base) /* Value too big for this base */ return(0); rv *= base; rv += val; buf++; } return(rv);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -