int Reset_get_at_at2_response(char *response) { char buf[128]; int next_state; int status; status = read_comport(buf); // read comport if (status == DATA) // if new data detected in com port buffer { strcat(response, buf); // append contents of buf to response next_state = RESET_GET_AT_AT2_RESPONSE; // come back for more data } else if (status == PROMPT) // if '>' detected { stop_serial_timer(); strcat(response, buf); status = process_response("at@2", response); if (status == STN_MFR_STRING) next_state = RESET_START_ECU_TIMER; else next_state = RESET_HANDLE_CLONE; } else if (serial_time_out) { stop_serial_timer(); alert("Connection with interface lost", NULL, NULL, "OK", NULL, 0, 0); next_state = RESET_CLOSE_DIALOG; // close dialog } else // serial buffer was empty, but we still got time next_state = RESET_GET_AT_AT2_RESPONSE; return next_state; }
void start_serial_timer(int delay) { stop_serial_timer(); install_int_ex(serial_time_out_handler, MSEC_TO_TIMER(delay)); // install the timer serial_time_out = FALSE; serial_timer_running = TRUE; }
int Reset_get_reply_to_reset(char *response, int *device) { char buf[128]; int next_state; int status; status = read_comport(buf); // read comport if (status == DATA) // if new data detected in com port buffer { strcat(response, buf); // append contents of buf to response next_state = RESET_GET_REPLY_TO_RESET; // come back for more data } else if (status == PROMPT) // if '>' detected { stop_serial_timer(); strcat(response, buf); *device = process_response("atz", response); if (*device == INTERFACE_ELM323) next_state = RESET_START_ECU_TIMER; else if (*device == INTERFACE_ELM327) next_state = RESET_SEND_AT_AT1_REQUEST; else next_state = RESET_CLOSE_DIALOG; } else if (serial_time_out) // if the timer timed out { stop_serial_timer(); // stop the timer alert("Interface was not found", NULL, NULL, "OK", NULL, 0, 0); next_state = RESET_CLOSE_DIALOG; // close dialog } else // serial buffer was empty, but we still got time next_state = RESET_GET_REPLY_TO_RESET; return next_state; }
int Reset_get_reply_to_detect_protocol(char *response) { char buf[128]; int next_state; int status; status = read_comport(buf); if(status == DATA) // if new data detected in com port buffer { strcat(response, buf); // append contents of buf to response next_state = RESET_GET_REPLY_TO_DETECT_PROTOCOL; // come back for more } else if (status == PROMPT) // if we got the prompt { stop_serial_timer(); strcat(response, buf); status = process_response("0100", response); if (status == ERR_NO_DATA || status == UNABLE_TO_CONNECT) alert("Protocol could not be detected.", "Please check connection to the vehicle,", "and make sure the ignition is ON", "OK", NULL, 0, 0); else if (status != HEX_DATA) alert("Communication error", buf, NULL, "OK", NULL, 0, 0); next_state = RESET_CLOSE_DIALOG; } else if (serial_time_out) { stop_serial_timer(); alert("Connection with interface lost", NULL, NULL, "OK", NULL, 0, 0); next_state = RESET_CLOSE_DIALOG; } else next_state = RESET_GET_REPLY_TO_DETECT_PROTOCOL; return next_state; }
int Reset_wait_for_ecu_timeout(int device) { int next_state; if (serial_time_out) // if the timer timed out { stop_serial_timer(); // stop the timer if (device == INTERFACE_ELM327) next_state = RESET_SEND_DETECT_PROTOCOL_REQUEST; else next_state = RESET_CLOSE_DIALOG; } else next_state = RESET_WAIT_FOR_ECU_TIMEOUT; return next_state; }
// DO NOT TRANSLATE ANY STRINGS IN THIS FUNCTION! int process_response(const char *cmd_sent, char *msg_received) { int i = 0; char *msg = msg_received; int echo_on = TRUE; //echo status int is_hex_num = TRUE; char temp_buf[80]; if (cmd_sent) { for(i = 0; cmd_sent[i]; i++) { if (cmd_sent[i] != *msg) // if the characters are not the same, { echo_on = FALSE; // say that echo is off break; // break out of the loop } msg++; } if (echo_on == TRUE) //if echo is on { send_command("ate0"); // turn off the echo start_serial_timer(AT_TIMEOUT); // wait for chip response or timeout while ((read_comport(temp_buf) != PROMPT) && !serial_time_out) ; stop_serial_timer(); if (!serial_time_out) { send_command("atl0"); // turn off linefeeds start_serial_timer(AT_TIMEOUT); // wait for chip response or timeout while ((read_comport(temp_buf) != PROMPT) && !serial_time_out) ; stop_serial_timer(); } } else //if echo is off msg = msg_received; } while(*msg && (*msg <= ' ')) msg++; if (strncmp(msg, "SEARCHING...", 12) == 0) msg += 13; else if (strncmp(msg, "BUS INIT: OK", 12) == 0) msg += 13; else if (strncmp(msg, "BUS INIT: ...OK", 15) == 0) msg += 16; for(i = 0; *msg; msg++) //loop to copy data { if (*msg > ' ') // if the character is not a special character or space { if (*msg == '<') // Detect <DATA_ERROR { if (strncmp(msg, "<DATA ERROR", 10) == 0) return DATA_ERROR2; else return RUBBISH; } msg_received[i] = *msg; // rewrite response if (!isxdigit(*msg) && *msg != ':') is_hex_num = FALSE; i++; } else if (((*msg == '\n') || (*msg == '\r')) && (msg_received[i-1] != SPECIAL_DELIMITER)) // if the character is a CR or LF msg_received[i++] = SPECIAL_DELIMITER; // replace CR with SPECIAL_DELIMITER } if (i > 0) if (msg_received[i-1] == SPECIAL_DELIMITER) i--; msg_received[i] = '\0'; // terminate the string if (is_hex_num) return HEX_DATA; if (strcmp(msg_received, "NODATA") == 0) return ERR_NO_DATA; if (strcmp(msg_received + strlen(msg_received) - 15, "UNABLETOCONNECT") == 0) return UNABLE_TO_CONNECT; if (strcmp(msg_received + strlen(msg_received) - 7, "BUSBUSY") == 0) return BUS_BUSY; if (strcmp(msg_received + strlen(msg_received) - 9, "DATAERROR") == 0) return DATA_ERROR; if (strcmp(msg_received + strlen(msg_received) - 8, "BUSERROR") == 0 || strcmp(msg_received + strlen(msg_received) - 7, "FBERROR") == 0) return BUS_ERROR; if (strcmp(msg_received + strlen(msg_received) - 8, "CANERROR") == 0) return CAN_ERROR; if (strcmp(msg_received + strlen(msg_received) - 10, "BUFFERFULL") == 0) return BUFFER_FULL; if (strncmp(msg_received, "BUSINIT:", 8) == 0) { if (strcmp(msg_received + strlen(msg_received) - 5, "ERROR") == 0) return BUS_INIT_ERROR; else return SERIAL_ERROR; } if (strcmp(msg_received, "?") == 0) return UNKNOWN_CMD; if (strncmp(msg_received, "ELM320", 6) == 0) return INTERFACE_ELM320; if (strncmp(msg_received, "ELM322", 6) == 0) return INTERFACE_ELM322; if (strncmp(msg_received, "ELM323", 6) == 0) return INTERFACE_ELM323; if (strncmp(msg_received, "ELM327", 6) == 0) return INTERFACE_ELM327; if (strncmp(msg_received, "OBDLink", 7) == 0 || strncmp(msg_received, "STN1000", 7) == 0 || strncmp(msg_received, "STN11", 5) == 0) return INTERFACE_OBDLINK; if (strncmp(msg_received, "SCANTOOL.NET", 12) == 0) return STN_MFR_STRING; if (strcmp(msg_received, "OBDIItoRS232Interpreter") == 0) return ELM_MFR_STRING; return RUBBISH; }
// heart of the trouble_code_reader module: int tr_code_proc(int msg, DIALOG *d, int c) { static char vehicle_response[1024]; // character buffer for car response static int first_read_occured = FALSE; static int receiving_response = FALSE; // flag, "are we receiving response?" static int verifying_connection = FALSE; // flag, "are we verifying connection?" static int current_request = CRQ_NONE; // NUM_OF_CODES, READ_CODES, CLEAR_CODES int response_status = EMPTY; // EMPTY, DATA, PROMPT int response_type; // BUS_BUSY, BUS_ERROR, DATA_ERROR, etc. int pending_codes_cnt = 0; char comport_buffer[256]; // temporary storage for comport data char buf1[64]; char buf2[64]; switch (msg) { case MSG_IDLE: if (!first_read_occured) { if (!simulate) read_codes(); first_read_occured = TRUE; return D_O_K; } if (simulate) break; if (comport.status == READY) { if (!receiving_response) { if (verifying_connection) { send_command("0100"); // send request that requires a response receiving_response = TRUE; // now we're waiting for response vehicle_response[0] = 0; //get buffer ready for the response start_serial_timer(OBD_REQUEST_TIMEOUT); // start the timer } else if (current_request == READ_PENDING) { send_command("07"); // request "pending" codes receiving_response = TRUE; // and receiving response vehicle_response[0] = '\0'; // clear the buffer start_serial_timer(OBD_REQUEST_TIMEOUT); // start the timer... } } else { response_status = read_comport(comport_buffer); if (response_status == DATA) // if data detected in com port buffer { // append contents of comport_buffer to vehicle_response: strcat(vehicle_response, comport_buffer); start_serial_timer(OBD_REQUEST_TIMEOUT); // we got data, reset the timer } else if (response_status == PROMPT) // if ">" is detected { receiving_response = FALSE; // we're not waiting for response any more stop_serial_timer(); // stop the timer // append contents of comport_buffer to vehicle_response: strcat(vehicle_response, comport_buffer); if (verifying_connection) // *** if we are verifying connection *** { // NOTE: we only get here if we got "NO DATA" somewhere else response_type = process_response("0100", vehicle_response); verifying_connection = FALSE; // we're not verifying connection anymore if (response_type == HEX_DATA) // if everything seems to be fine now, { if (current_request == CLEAR_CODES) alert("There may have been a temporary loss of connection.", "Please try clearing codes again.", NULL, "OK", NULL, 0, 0); else if (current_request == NUM_OF_CODES) alert("There may have been a temporary loss of connection.", "Please try reading codes again.", NULL, "OK", NULL, 0, 0); else if (current_request == READ_CODES) { current_request = READ_PENDING; break; } } else if (response_type == ERR_NO_DATA) { if (current_request == CLEAR_CODES) // if we were clearing codes, alert("Communication problem: vehicle did not confirm successful", "deletion of trouble codes. Please check connection to the vehicle,", "make sure the ignition is ON, and try clearing the codes again.", "OK", NULL, 0, 0); else // if we were reading codes or requesting number or DTCs alert("There may have been a loss of connection.", "Please check connection to the vehicle,", "and make sure the ignition is ON", "OK", NULL, 0, 0); } else display_error_message(response_type, FALSE); broadcast_dialog_message(MSG_READY, 0); // tell everyone we're done } else if (current_request == NUM_OF_CODES) // *** if we are getting number of codes *** { response_type = process_response("0101", vehicle_response); if (response_type == ERR_NO_DATA) // if we received "NO DATA" verifying_connection = TRUE; // verify connection else if (response_type != HEX_DATA) // if we got an error, handle_errors(response_type, NUM_OF_CODES); // handle it else // if process response returned HEX_DATA (i.e. there are no errors) { // extract # of codes from vehicle_response num_of_codes_reported = handle_num_of_codes(vehicle_response); send_command("03"); // request "stored" codes current_request = READ_CODES; // we're reading stored codes now receiving_response = TRUE; // and receiving response vehicle_response[0] = '\0'; // clear the buffer start_serial_timer(OBD_REQUEST_TIMEOUT); // start the timer... } } else if (current_request == READ_CODES) // if we are reading codes, { response_type = process_response("03", vehicle_response); if (response_type == ERR_NO_DATA) // vehicle didn't respond, check connection { if (num_of_codes_reported > 0) verifying_connection = TRUE; else current_request = READ_PENDING; } else if (response_type == HEX_DATA) { handle_read_codes(vehicle_response, FALSE); current_request = READ_PENDING; } else // if we got an error handle_errors(response_type, READ_CODES); } else if(current_request == READ_PENDING) // if we are reading pending codes, { response_type = process_response("07", vehicle_response); if (response_type == ERR_NO_DATA) { if (get_number_of_codes() == 0 && num_of_codes_reported == 0) alert("No Diagnostic Trouble Codes (DTCs) detected", NULL, NULL, "OK", NULL, 0, 0); } else if(response_type != HEX_DATA) // if we got an error, { handle_errors(response_type, READ_PENDING); break; } else // if there were *no* errors, pending_codes_cnt = handle_read_codes(vehicle_response, TRUE); // if number of DTCs reported by 0101 request does not equal either number or total DTCs or just stored DTCs if ((get_number_of_codes() != num_of_codes_reported) && (get_number_of_codes() - pending_codes_cnt != num_of_codes_reported)) { sprintf(buf1, "Vehicle reported %i Diagnostic Trouble Codes (DTCs).", num_of_codes_reported); sprintf(buf2, "However, %i non-pending DTC(s) have been successfully read.", get_number_of_codes() - pending_codes_cnt); alert(buf1, buf2, "Try reading codes again.", "OK", NULL, 0, 0); } populate_trouble_codes_list(); broadcast_dialog_message(MSG_READY, 0); // tell everyone we're done } else if(current_request == CLEAR_CODES) { response_type = process_response("04", vehicle_response); if (response_type == ERR_NO_DATA)// vehicle didn't respond, check connection verifying_connection = TRUE; else if(response_type != HEX_DATA) // if we got an error, handle_errors(response_type, CLEAR_CODES); else // if everything's fine (received confirmation) { clear_trouble_codes(); num_of_codes_reported = 0; mil_is_on = FALSE; broadcast_dialog_message(MSG_READY, 0); } } } else if (serial_time_out) // if request timed out, { stop_serial_timer(); receiving_response = FALSE; num_of_codes_reported = 0; mil_is_on = FALSE; clear_trouble_codes(); broadcast_dialog_message(MSG_READY, 0); if(alert("Device is not responding.", "Please check that it is connected", "and the port settings are correct", "OK", "&Configure Port", 27, 'c') == 2) display_options(); // let the user choose correct settings while (comport.status == NOT_OPEN) { if (alert("Port is not ready.", "Please check that you specified the correct port", "and that no other application is using it", "&Configure Port", "&Ignore", 'c', 'i') == 1) display_options(); // let the user choose correct settings else comport.status = USER_IGNORED; } } } } break; // end case MSG_IDLE case MSG_START: first_read_occured = FALSE; num_of_codes_reported = 0; mil_is_on = FALSE; // fall through case MSG_READY: receiving_response = FALSE; verifying_connection = FALSE; current_request = CRQ_NONE; break; case MSG_READ_CODES: if (comport.status == READY) { send_command("0101"); // request number of trouble codes start_serial_timer(OBD_REQUEST_TIMEOUT); // start the timer current_request = NUM_OF_CODES; receiving_response = TRUE; // now we're waiting for response vehicle_response[0] = 0; clear_trouble_codes(); num_of_codes_reported = 0; mil_is_on = FALSE; } else serial_time_out = TRUE; break; case MSG_CLEAR_CODES: if (comport.status == READY) { send_command("04"); // "clear codes" request current_request = CLEAR_CODES; receiving_response = TRUE; // now we're waiting for response vehicle_response[0] = 0; start_serial_timer(OBD_REQUEST_TIMEOUT); // start the timer } else serial_time_out = TRUE; break; case MSG_END: stop_serial_timer(); break; } return D_O_K; } // end of tr_codes_proc()