react-native-obd-retriver
Version:
A React Native hook library to manage Bluetooth Low Energy connections and communication with ELM327 OBD-II adapters.
2 lines • 15.5 kB
JavaScript
var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports,"__esModule",{value:true});exports.initializeAdapter=exports.getVehicleVIN=exports.getVehicleDTCs=exports.getRawDTCs=exports.getAdapterInfo=exports.disconnectFromECU=exports.connectToECU=exports.clearVehicleDTCs=void 0;var _asyncToGenerator2=_interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));var _logger=require("../../utils/logger");var _ProtocolManager=require("../protocols/ProtocolManager");var _VINRetriever=require("../retrievers/VINRetriever");var _constants=require("../utils/constants");var _helpers=require("../utils/helpers");var delay=function delay(ms){return new Promise(function(resolve){setTimeout(function(){return resolve();},ms);});};var initializeAdapter=exports.initializeAdapter=function(){var _ref=(0,_asyncToGenerator2.default)(function*(sendCommand){yield _logger.log.debug('[connectionService] Initializing adapter...');var initCommands=[{cmd:_constants.ELM_COMMANDS.RESET,delay:_constants.DELAYS_MS.RESET,ignoreError:true,checkOk:false},{cmd:_constants.ELM_COMMANDS.ECHO_OFF,delay:_constants.DELAYS_MS.INIT,ignoreError:false,checkOk:true},{cmd:_constants.ELM_COMMANDS.LINEFEEDS_OFF,delay:_constants.DELAYS_MS.INIT,ignoreError:false,checkOk:true},{cmd:_constants.ELM_COMMANDS.SPACES_OFF,delay:_constants.DELAYS_MS.INIT,ignoreError:false,checkOk:true},{cmd:_constants.ELM_COMMANDS.HEADERS_OFF,delay:_constants.DELAYS_MS.INIT,ignoreError:false,checkOk:true},{cmd:_constants.ELM_COMMANDS.ADAPTIVE_TIMING_OFF,delay:_constants.DELAYS_MS.INIT,ignoreError:false,checkOk:true}];try{for(var _ref2 of initCommands){var cmd=_ref2.cmd;var cmdDelay=_ref2.delay;var ignoreError=_ref2.ignoreError;var checkOk=_ref2.checkOk;yield _logger.log.debug(`[connectionService] Sending init command: ${cmd}`);var response=yield sendCommand(cmd,2000);yield delay(cmdDelay);if(!ignoreError){if(response===null||(0,_helpers.isResponseError)(response)||checkOk&&!(0,_helpers.isResponseOk)(response)&&(response==null?void 0:response.trim())!=='?'){yield _logger.log.error(`[connectionService] Init command "${cmd}" failed or returned error/unexpected response. Response: ${response!=null?response:'null'}`);return false;}else if((response==null?void 0:response.trim())==='?'){yield _logger.log.warn(`[connectionService] Init command "${cmd}" returned '?', possibly unsupported but continuing.`);}}else{yield _logger.log.debug(`[connectionService] Init command "${cmd}" response (errors ignored): ${response!=null?response:'null'}`);}}var voltageResponse=yield sendCommand(_constants.ELM_COMMANDS.READ_VOLTAGE,2000);var voltage=(0,_helpers.extractVoltage)(voltageResponse);if(!voltageResponse||(0,_helpers.isResponseError)(voltageResponse)||voltage===null){yield _logger.log.error(`[connectionService] Adapter unresponsive after initialization (ATRV failed or returned invalid voltage). Response: ${voltageResponse!=null?voltageResponse:'null'}`);return false;}yield _logger.log.info(`[connectionService] Adapter initialized successfully. Voltage: ${voltage}`);return true;}catch(error){var errorMsg=error instanceof Error?error.message:String(error);yield _logger.log.error('[connectionService] Critical error during adapter initialization:',{error:errorMsg});return false;}});return function initializeAdapter(_x){return _ref.apply(this,arguments);};}();var connectToECU=exports.connectToECU=function(){var _ref3=(0,_asyncToGenerator2.default)(function*(sendCommand){yield _logger.log.info('[connectionService] Attempting to connect to ECU...');var initSuccess=yield initializeAdapter(sendCommand);if(!initSuccess){return{success:false,error:'Adapter initialization failed'};}var protocolManager=new _ProtocolManager.ProtocolManager(sendCommand);var protocolResult=yield protocolManager.detectAndSetProtocol();if(!protocolResult||protocolResult.protocol===null){return{success:false,error:'Protocol detection failed'};}var protocol=protocolResult.protocol,protocolName=protocolResult.name;yield protocolManager.configureProtocolSettings(protocol);var adapterInfo=yield getAdapterInfo(sendCommand);if(adapterInfo.voltage===null){yield _logger.log.error('[connectionService] Failed to read voltage after protocol setup. Connection unstable.');return{success:false,error:'Adapter unresponsive after protocol setup',protocol:protocol,protocolName:protocolName};}var detectedEcus=[];try{var testCmd=_constants.STANDARD_PIDS.SUPPORTED_PIDS_1;yield _logger.log.debug(`[connectionService] Sending final test command: ${testCmd}`);var testResponse=yield sendCommand(testCmd,5000);if(testResponse&&!(0,_helpers.isResponseError)(testResponse)){if((0,_helpers.cleanResponse)(testResponse).includes(_constants.RESPONSE_KEYWORDS.NO_DATA)){yield _logger.log.info(`[connectionService] Test command (${testCmd}) returned NO DATA. Connection likely OK, but no specific ECU response data.`);}else{detectedEcus=(0,_helpers.extractEcuAddresses)(testResponse);if(detectedEcus.length>0){yield _logger.log.info(`[connectionService] Detected ECU addresses: ${detectedEcus.join(', ')}`);}else{yield _logger.log.warn(`[connectionService] Test command (${testCmd}) successful, but no specific ECU addresses extracted from response: ${testResponse}`);}}}else{yield _logger.log.warn(`[connectionService] Test command (${testCmd}) failed or returned error after protocol set. Response: ${testResponse!=null?testResponse:'null'}`);}}catch(error){var errorMsg=error instanceof Error?error.message:String(error);yield _logger.log.warn('[connectionService] Error during final ECU check command:',{error:errorMsg});}yield _logger.log.info(`[connectionService] Connection established. Protocol: ${protocolName} (${protocol}), Voltage: ${adapterInfo.voltage}`);return{success:true,protocol:protocol,protocolName:protocolName,voltage:adapterInfo.voltage,detectedEcus:detectedEcus};});return function connectToECU(_x2){return _ref3.apply(this,arguments);};}();var getAdapterInfo=exports.getAdapterInfo=function(){var _ref4=(0,_asyncToGenerator2.default)(function*(sendCommand){yield _logger.log.debug('[connectionService] Getting adapter info (ATRV)...');try{var voltageResponse=yield sendCommand(_constants.ELM_COMMANDS.READ_VOLTAGE,2000);var voltage=(0,_helpers.extractVoltage)(voltageResponse);if(voltage===null){yield _logger.log.warn(`[connectionService] Failed to extract voltage from ATRV response: ${voltageResponse!=null?voltageResponse:'null'}`);}yield _logger.log.debug(`[connectionService] Adapter Voltage: ${voltage!=null?voltage:'N/A'}`);return{voltage:voltage};}catch(error){var errorMsg=error instanceof Error?error.message:String(error);yield _logger.log.error('[connectionService] Failed to get adapter voltage (ATRV):',{error:errorMsg});return{voltage:null};}});return function getAdapterInfo(_x3){return _ref4.apply(this,arguments);};}();var disconnectFromECU=exports.disconnectFromECU=function(){var _ref5=(0,_asyncToGenerator2.default)(function*(sendCommand){yield _logger.log.info('[connectionService] Disconnecting from ECU (sending ATPC)...');try{yield sendCommand(_constants.ELM_COMMANDS.PROTOCOL_CLOSE,1000);yield _logger.log.debug('[connectionService] Protocol close command (ATPC) sent.');}catch(error){var errorMsg=error instanceof Error?error.message:String(error);yield _logger.log.warn('[connectionService] Error sending protocol close command (ATPC) during disconnect:',{error:errorMsg});}});return function disconnectFromECU(_x4){return _ref5.apply(this,arguments);};}();var getVehicleVIN=exports.getVehicleVIN=function(){var _ref6=(0,_asyncToGenerator2.default)(function*(sendCommand){yield _logger.log.debug('[connectionService] Attempting to retrieve VIN using VINRetriever...');try{var vinRetriever=new _VINRetriever.VINRetriever(sendCommand);var vin=yield vinRetriever.retrieveVIN();if(vin){yield _logger.log.info(`[connectionService] VIN Retrieved successfully: ${vin}`);}else{yield _logger.log.warn('[connectionService] Failed to retrieve VIN.');}return vin;}catch(error){var errorMsg=error instanceof Error?error.message:String(error);yield _logger.log.error('[connectionService] Error during VIN retrieval via VINRetriever:',{error:errorMsg});return null;}});return function getVehicleVIN(_x5){return _ref6.apply(this,arguments);};}();var getVehicleDTCs=exports.getVehicleDTCs=function(){var _ref7=(0,_asyncToGenerator2.default)(function*(sendCommand,mode){yield _logger.log.debug('[connectionService] Requesting DTCs',{mode:mode});var response=yield sendCommand(mode,8000);if(response===null){yield _logger.log.warn('[connectionService] No response for DTC request',{mode:mode});return null;}if((0,_helpers.isResponseError)(response)){yield _logger.log.error('[connectionService] Error response for DTC request',{mode:mode,response:response});return null;}if((0,_helpers.cleanResponse)(response).includes(_constants.RESPONSE_KEYWORDS.NO_DATA)){yield _logger.log.debug(`[connectionService] NO DATA response for DTC request (Mode ${mode}). Vehicle reports no DTCs.`);return[];}var assembledResponse=(0,_helpers.assembleMultiFrameResponse)(response);yield _logger.log.debug(`[connectionService] Assembled DTC response (Mode ${mode}): ${assembledResponse}`);var responsePrefix=(parseInt(mode,16)+0x40).toString(16).toUpperCase();var dtcs=(0,_helpers.parseDtcsFromResponse)(assembledResponse,responsePrefix);if(dtcs===null){yield _logger.log.error(`[connectionService] Failed to parse DTCs from response (Mode ${mode})`,{assembledResponse:assembledResponse});}return dtcs;});return function getVehicleDTCs(_x6,_x7){return _ref7.apply(this,arguments);};}();var clearVehicleDTCs=exports.clearVehicleDTCs=function(){var _ref8=(0,_asyncToGenerator2.default)(function*(sendCommand){var skipVerification=arguments.length>1&&arguments[1]!==undefined?arguments[1]:false;var clearCommand=_constants.OBD_MODE.CLEAR_DTC;yield _logger.log.debug(`[connectionService] Starting DTC clearing sequence (Mode ${clearCommand})...`);yield _logger.log.debug(`[connectionService] Sending DTC clear command (${clearCommand})...`);var response=yield sendCommand(clearCommand,10000);if(response===null){yield _logger.log.error('[connectionService] No response received for Clear DTC command.');return false;}var cleanedResponse=(0,_helpers.cleanResponse)(response);var isSuccessful=cleanedResponse.includes('44')||(0,_helpers.isResponseOk)(response);if(!isSuccessful||(0,_helpers.isResponseError)(response)){yield _logger.log.error(`[connectionService] Clear command failed or returned error. Response: ${response}`);return false;}yield _logger.log.debug(`[connectionService] Clear command received successful-looking response: ${cleanedResponse}`);if(skipVerification){yield _logger.log.debug('[connectionService] Verification skipped as requested.');return true;}yield _logger.log.debug(`[connectionService] Clear command successful. Verifying...`);yield delay(_constants.DELAYS_MS.COMMAND_LONG);var mode03Response=yield sendCommand(_constants.OBD_MODE.CURRENT_DTC,5000);var isMode03Clear=checkMode03Response(mode03Response);if(isMode03Clear){yield _logger.log.debug('[connectionService] Mode 03 verification successful: Response indicates no current DTCs.');}else{yield _logger.log.warn('[connectionService] Mode 03 verification indicates DTCs might still be present.',{response:mode03Response});}var mode0101Response=yield sendCommand(_constants.STANDARD_PIDS.MONITOR_STATUS,5000);var isMode0101Clear=checkMode0101Response(mode0101Response);if(isMode0101Clear){yield _logger.log.debug('[connectionService] Mode 01 PID 01 verification successful: MIL off, DTC count 0.');}else{yield _logger.log.warn('[connectionService] Mode 01 PID 01 verification indicates DTCs or MIL may still be active.',{response:mode0101Response});}var allClear=isMode03Clear;if(allClear){yield _logger.log.info('[connectionService] Verification successful: DTCs appear cleared.');return true;}else{yield _logger.log.warn('[connectionService] Verification suggests DTCs may not be fully cleared (Mode 03 check failed).');return false;}});return function clearVehicleDTCs(_x8){return _ref8.apply(this,arguments);};}();function checkMode03Response(response){if(response===null)return false;var assembledResponse=(0,_helpers.assembleMultiFrameResponse)(response);var cleanedResponse=(0,_helpers.cleanResponse)(assembledResponse);if(cleanedResponse.includes(_constants.RESPONSE_KEYWORDS.NO_DATA)){return true;}if(cleanedResponse.startsWith('43')){var dataPart=cleanedResponse.substring(2);if(dataPart.length===0||/^[0]+$/.test(dataPart)){return true;}}return false;}function checkMode0101Response(response){if(response===null)return false;var assembledResponse=(0,_helpers.assembleMultiFrameResponse)(response);var cleanedResponse=(0,_helpers.cleanResponse)(assembledResponse).replace(/\s/g,'');if(cleanedResponse.length>=6&&cleanedResponse.startsWith('4101')){try{var byteA=parseInt(cleanedResponse.substring(4,6),16);if(isNaN(byteA))return false;var isMilOff=(byteA&0x80)===0;var dtcCount=byteA&0x7f;return isMilOff&&dtcCount===0;}catch(error){void _logger.log.error('[Helper] Error parsing Mode 0101 response byte A',{error:error instanceof Error?error.message:String(error),response:response});return false;}}return false;}var getRawDTCs=exports.getRawDTCs=function(){var _ref9=(0,_asyncToGenerator2.default)(function*(sendCommand,mode){yield _logger.log.debug(`[connectionService] Getting raw DTCs (Mode ${mode})...`);try{var _protocolNum;var protocolNum=null;var isCan=false;try{var protocolResponse=yield sendCommand(_constants.ELM_COMMANDS.GET_PROTOCOL_NUM,1000);var extractedNum=(0,_helpers.extractProtocolNumber)(protocolResponse);if(extractedNum!==null){protocolNum=extractedNum;isCan=extractedNum>=_constants.PROTOCOL.ISO_15765_4_CAN_11BIT_500K&&extractedNum<=_constants.PROTOCOL.ISO_15765_4_CAN_29BIT_250K_8;}}catch(error){var errorMsg=error instanceof Error?error.message:String(error);yield _logger.log.warn('[connectionService] Could not get protocol number for raw DTCs',{error:errorMsg});}var rawResponse=yield sendCommand(mode,8000);if(rawResponse===null){yield _logger.log.warn(`[connectionService] No response for raw DTC request (Mode ${mode})`);return null;}if((0,_helpers.isResponseError)(rawResponse)){yield _logger.log.error(`[connectionService] Error response for raw DTC request (Mode ${mode}): ${rawResponse}`);return null;}var ecuAddress=(0,_helpers.extractEcuAddresses)(rawResponse)[0];var rawBytes=Array.from(rawResponse).map(function(c){return c.charCodeAt(0);});var responseFramesAsStrings=rawResponse.split(/[\r\n]+/).map(function(line){return line.trim();}).filter(function(line){return line.length>0&&!line.startsWith(_constants.RESPONSE_KEYWORDS.PROMPT);});var responseFramesAsHexArrays=responseFramesAsStrings.map(function(line){return line.split(/\s+/).filter(function(hex){return /^[0-9A-F]+$/i.test(hex);});}).filter(function(frame){return frame.length>0;});return{rawString:rawResponse,rawResponse:rawBytes,response:responseFramesAsHexArrays,rawBytesResponseFromSendCommand:responseFramesAsHexArrays,isCan:isCan,protocolNumber:(_protocolNum=protocolNum)!=null?_protocolNum:0,ecuAddress:ecuAddress!=null?ecuAddress:undefined};}catch(error){var _errorMsg=error instanceof Error?error.message:String(error);yield _logger.log.error(`[connectionService] Error getting raw DTCs (Mode ${mode}):`,{error:_errorMsg});return null;}});return function getRawDTCs(_x9,_x10){return _ref9.apply(this,arguments);};}();
//# sourceMappingURL=connectionService.js.map