📄 scantool.c
字号:
}voidprint_dtcs(u_int8_t *data){ /* Print the DTCs just received */ int i, j; for (i=0, j=1; i<3; i++, j+=2) { if ((data[j]==0) && (data[j+1]==0)) continue; print_single_dtc(data[j], data[j+1]); }}/* * Get test results for constantly monitored systems */voiddo_j1979_cms(){ int rv, i; diag_l3_conn_t *d_conn; diag_msg_t *msg; d_conn = global_l3_conn; rv = l3_do_j1979_rqst(d_conn, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (void *)0); if (rv == DIAG_ERR_TIMEOUT) { /* Didn't get a response, this is valid if there are no DTCs */ return; } if (rv != 0) { printf("Failed to get test results for continuously monitored systems\n"); return; } printf("Currently monitored DTCs: "); for (i=0; i<ecu_count;i++) { for (msg=ecu_info[i].rxmsg; msg; msg=msg->next) { print_dtcs(msg->data); } } printf("\n"); return;}/* * Get test results for non-constantly monitored systems */voiddo_j1979_ncms(int printall){ int rv; diag_l3_conn_t *d_conn; int i, j; int supported; ecu_data_t *ep; u_int8_t merged_mode6_info[0x100]; d_conn = global_l3_conn; /* Merge all ECU mode6 info into one place*/ memset(merged_mode6_info, 0, sizeof(merged_mode6_info)); for (i=0, ep=ecu_info, supported = 0; i<ecu_count; i++, ep++) { for (j=0; j<sizeof(ep->mode6_info);j++) merged_mode6_info[j] |= ep->mode6_info[j] ; if (ep->mode6_info[0] != 0) supported = 1; } if (merged_mode6_info[0] == 0x00) { /* Either not supported, or tests havent been done */ do_j1979_getmodeinfo(6, 3); } if (merged_mode6_info[0] == 0x00) { printf("ECU doesn't support non-continuously monitored system tests\n"); return; } /* * Now do the tests */ for (i=0 ; i < 60; i++) { if ((merged_mode6_info[i]) && ((i & 0x1f) != 0)) { /* Do test */ rv = l3_do_j1979_rqst(d_conn, 6, i, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (void *)(printall?RQST_HANDLE_NCMS:RQST_HANDLE_NCMS2)); if (rv < 0) { printf("Mode 6 Test ID 0x%d failed\n", i); } } } return;}/* * Get mode info */voiddo_j1979_getmodeinfo(int mode, int response_offset){ int rv; diag_l3_conn_t *d_conn; int i, j, pid; diag_msg_t *msg; ecu_data_t *ep; int not_done; u_int8_t *data; d_conn = global_l3_conn; /* * Test 0, 0x20, 0x40, 0x60 (etc) for each mode returns information * as to which tests are supported. Test 0 will return a bitmask 4 * bytes long showing which of the tests 0->0x1f are supported. Test * 0x20 will show 0x20->0x3f etc */ for (pid = 0; pid < 0x100; pid += 0x20) { /* * Do Mode 'mode' Pid 'pid' request to find out * what is supported */ rv = l3_do_j1979_rqst(d_conn, mode, pid, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (void *)0); if (rv != 0) { /* No response */ break; } /* Process the results */ for (j=0, ep=ecu_info, not_done = 0; j<ecu_count; j++, ep++) { if (ep->rxmsg == NULL) continue; if (ep->rxmsg->data[0] != (mode + 0x40)) continue; /* Valid response for this request */ /* Sort out where to store the received data */ switch (mode) { case 1: data = ep->pids; break; case 2: data = ep->mode2_info; break; case 5: data = ep->mode5_info; break; case 6: data = ep->mode6_info; break; case 8: data = ep->mode8_info; break; case 9: data = ep->mode9_info; break; default: data = NULL; break; } if (data == NULL) break; data[0] = 1; /* Pid 0, 0x20, 0x40 always supported */ for (i=0 ; i<=0x20; i++) { if (l2_check_pid_bits(&ep->rxmsg->data[response_offset], i)) data[i + pid] = 1; } if (data[0x20 + pid] == 1) not_done = 1; } /* Now, check if all ECUs said the next pid isnt supported */ if (not_done == 0) break; } return;}/* * Get the supported PIDs and Tests (Mode 1, 2, 5, 6, 9) * * This doesnt get the data for those pids, just the info as to * what the ECU supports */voiddo_j1979_getpids(){ diag_l3_conn_t *d_conn; ecu_data_t *ep; int i, j; int PID = 0x00; d_conn = global_l3_conn; do_j1979_getmodeinfo(1, 2); do_j1979_getmodeinfo(2, 2); do_j1979_getmodeinfo(5, 3); do_j1979_getmodeinfo(6, 3); do_j1979_getmodeinfo(8, 2); do_j1979_getmodeinfo(9, 3); /* * Combine all the supported Mode1 PIDS * from the ECUs into one bitmask, do same * for Mode5 */ memset(merged_mode1_info, 0, sizeof(merged_mode1_info)); for (i=0, ep=ecu_info; i<ecu_count; i++, ep++) { for (j=0; j<sizeof(ep->pids);j++) merged_mode1_info[j] |= ep->pids[j] ; } memset(merged_mode5_info, 0, sizeof(merged_mode5_info)); for (i=0, ep=ecu_info; i<ecu_count; i++, ep++) { for (j=0; j<sizeof(ep->mode5_info);j++) merged_mode5_info[j] |= ep->mode5_info[j] ; } return;}/* * Do the O2 tests for this O2 sensor */voiddo_j1979_O2tests(){ int i; if (merged_mode5_info[0] == 0) { printf("Oxygen (O2) sensor tests not supported\n"); return; } for (i=0; i<=7; i++) { if (global_O2_sensors & (1<<i)) do_j1979_getO2tests(i); } return;}/* * Do O2 tests for O2Sensor * * O2sensor is the bit number */voiddo_j1979_getO2tests(int O2sensor){ int rv; diag_l3_conn_t *d_conn; int i; u_int8_t o2s = 1<<O2sensor ; d_conn = global_l3_conn; for (i=1 ; i<=0x1f; i++) { printf("O2 Sensor %d Tests: -\n", O2sensor); if ((merged_mode5_info[i]) && ((i & 0x1f) != 0)) { /* Do test for of i + testID */ rv = l3_do_j1979_rqst(d_conn, 5, i, o2s, 0x00, 0x00, 0x00, 0x00, 0x00, (void *)RQST_HANDLE_O2S); if ((rv < 0) || (find_ecu_msg(0, 0x45)==NULL)) { printf("Mode 5 Test ID 0x%d failed\n", i); } /* Receive routine will have printed results */ } }}/* * Get current DTCs/MIL lamp status/Tests supported for this ECU * and test, and wait for those tests to complete */intdo_j1979_getdtcs(){ int rv; diag_l3_conn_t *d_conn; int tests_complete = 0; int first = 1; int waiting_msg = 0; diag_msg_t *msg; ecu_data_t *ep; int i; int num_dtcs, readiness, mil; d_conn = global_l3_conn; if (merged_mode1_info[1] == 0) { printf("ECU(s) do not support DTC#/test query - can't do tests\n"); return(0); } rv = l3_do_j1979_rqst(d_conn, 1, 1, 0, 0x00, 0x00, 0x00, 0x00, 0x00, (void *)0); if ((rv < 0) || (find_ecu_msg(0, 0x41)==NULL)) { printf("Mode 1 Pid 1 request failed %d\n", rv); return(-1); } /* Go thru the received messages, and see readiness/MIL light */ mil = 0; readiness = 0, num_dtcs = 0; for (i=0, ep=ecu_info; i<ecu_count; i++, ep++) { if ((ep->rxmsg) && (ep->rxmsg->data[0] == 0x41)) { /* Go thru received msgs looking for DTC responses */ if ( (ep->mode1_data[1].data[3] & 0xf0) || ep->mode1_data[1].data[5] ) readiness = 1; if (ep->mode1_data[1].data[2] & 0x80) mil = 1; num_dtcs += ep->mode1_data[1].data[2] & 0x7f; } } if (readiness == 1) printf("Not all readiness tests have completed\n"); if (mil == 1) printf("MIL light ON, "); else printf("MIL light OFF, "); printf("%d stored DTC%c\n", num_dtcs, (num_dtcs==1)?' ':'s'); if (num_dtcs) { /* * Do Mode3 command to get DTCs */ rv = l3_do_j1979_rqst(d_conn, 3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (void *)0); if ((rv < 0) || (find_ecu_msg(0, 0x43)==NULL)) { printf("ECU would not return DTCs\n"); return(-1); } /* Go thru received msgs looking for DTC responses */ for (i=0, ep=ecu_info; i<ecu_count; i++, ep++) { if ((ep->rxmsg) && (ep->rxmsg->data[0] == 0x43)) { for (msg=ep->rxmsg; msg; msg=msg->next) { print_dtcs(ep->rxmsg->data); } printf("\n"); } } } return(0);}/* * Get supported DTCS */intdo_j1979_getO2sensors(){ int rv; diag_l3_conn_t *d_conn; int i, j; int num_sensors; ecu_data_t *ep; d_conn = global_l3_conn; global_O2_sensors = 0; num_sensors = 0; /* Pid 1 is "number of O2 sensors" */ rv = l3_do_j1979_rqst(d_conn, 1, 0x13, 0, 0x00, 0x00, 0x00, 0x00, 0x00, (void *)0); if ((rv < 0) || (find_ecu_msg(0, 0x41)==NULL)) { printf("Mode 1 Pid 0x13 request failed %d\n", rv); return(0); } for (i=0, ep=ecu_info; i<ecu_count; i++, ep++) { if ((ep->rxmsg) && (ep->rxmsg->data[0] == 0x41)) { /* Maintain bitmap of sensors */ global_O2_sensors |= ep->rxmsg->data[2]; /* And count additional sensors on this ECU */ for (j=0; j<=7; j++) { if (ep->rxmsg->data[2] & (1<<j)) num_sensors++; } } } printf("%d Oxygen (O2) sensors in vehicle\n", num_sensors); return(0);}intdiag_cleardtc(void){ /* Clear DTCs */ diag_l3_conn_t *d_conn; diag_msg_t msg; int rv; diag_msg_t *rxmsg; d_conn = global_l3_conn; rv = l3_do_j1979_rqst(d_conn, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (void *)0); rxmsg = find_ecu_msg(0, 0x44); if (rxmsg == NULL) { printf("ClearDTC requested failed - no appropriate response\n"); return(-1); } return (rv);}typedef int (start_fn)(int);struct protocol { char *desc; start_fn *start; int flags; int protocol; int conmode;};struct protocol protocols[] = { {"SAEJ1850-VPW", do_l2_j1850_start, DIAG_L1_J1850_VPW, PROTOCOL_SAEJ1850}, {"SAEJ1850-PWM", do_l2_j1850_start, DIAG_L1_J1850_PWM, PROTOCOL_SAEJ1850}, {"ISO14230_FAST", do_l2_14230_start, DIAG_L2_TYPE_FASTINIT, PROTOCOL_ISO14230, DIAG_L2_TYPE_FASTINIT}, {"ISO9141-2", do_l2_9141_start, 0x33, PROTOCOL_ISO9141_2, DIAG_L2_TYPE_SLOWINIT}, {"ISO14230_SLOW", do_l2_14230_start, DIAG_L2_TYPE_SLOWINIT, PROTOCOL_ISO14230, DIAG_L2_TYPE_SLOWINIT},};/* * Connect to ECU by trying all protocols * - We do the fast initialising protocols before the slow ones */intecu_connect(void){ int connected; int rv; struct protocol *p; connected = 0; for (p = protocols; !connected && p < &protocols[ARRAY_SIZE(protocols)]; p++) { printf("Trying %s ... ", p->desc); fflush(stdout); rv = p->start(p->flags); if (rv == 0) { global_conmode = p->conmode; global_protocol = p->protocol; connected = 1; printf("connected!\n"); } else printf("failed!\n"); } printf("\n"); /* * Connected, now add J1979 protocol */ if (connected) { diag_l3_conn_t *d_l3_conn; global_state = STATE_CONNECTED; d_l3_conn = diag_l3_start("SAEJ1979", global_l2_conn); if (d_l3_conn == NULL) { printf("Failed to enable SAEJ1979 mode\n"); rv = -1; } global_l3_conn = d_l3_conn; global_state = STATE_L3ADDED; } if (diag_cmd_debug > 0) printf("debug: L2 connection ID 0x%x, L3 ID 0x%x\n", global_l2_conn, global_l3_conn); return (rv);}/* * Clear data that is relevant to an ECU */intclear_data(void){ ecu_count = 0; memset(ecu_info, 0, sizeof(ecu_info)); memset(merged_mode1_info, 0, sizeof(merged_mode1_info)); memset(merged_mode5_info, 0, sizeof(merged_mode5_info)); return(0);}/* * Initialise */intdo_init(void){ clear_data(); return(0);}/* * Main */intmain(int argc, char **argv){ /* Input buffer */ do_init(); progname = strrchr(argv[0], '/'); progname = (progname)?(progname+1):argv[0]; enter_cli(progname); /* Done */ exit(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -