obd-raw-data-parser
Version:
A React Native hook library to manage Bluetooth Low Energy connections and communication with ELM327 OBD-II adapters.
2 lines • 10 kB
JavaScript
var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports,"__esModule",{value:true});exports.CanSingleFrame=void 0;var _toConsumableArray2=_interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));var _classCallCheck2=_interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));var _createClass2=_interopRequireDefault(require("@babel/runtime/helpers/createClass"));var _possibleConstructorReturn2=_interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));var _getPrototypeOf2=_interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));var _inherits2=_interopRequireDefault(require("@babel/runtime/helpers/inherits"));var _logger=require("../../logger");var _BaseDecoder2=require("./BaseDecoder");var _utils=require("../../utils");var _dtcConverter=require("../utils/dtcConverter");function _callSuper(t,o,e){return o=(0,_getPrototypeOf2.default)(o),(0,_possibleConstructorReturn2.default)(t,_isNativeReflectConstruct()?Reflect.construct(o,e||[],(0,_getPrototypeOf2.default)(t).constructor):o.apply(t,e));}function _isNativeReflectConstruct(){try{var t=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}));}catch(t){}return(_isNativeReflectConstruct=function _isNativeReflectConstruct(){return!!t;})();}var CanSingleFrame=exports.CanSingleFrame=function(_BaseDecoder){function CanSingleFrame(modeResponse){var _this;(0,_classCallCheck2.default)(this,CanSingleFrame);_this=_callSuper(this,CanSingleFrame);_this.leftoverByte=null;_this.expectedDTCCount=0;_this.currentDTCCount=0;_this.rawDtcObjects=[];_this.modeResponse=modeResponse||0x43;return _this;}(0,_inherits2.default)(CanSingleFrame,_BaseDecoder);return(0,_createClass2.default)(CanSingleFrame,[{key:"setModeResponse",value:function setModeResponse(response){this.modeResponse=response;}},{key:"_isAsciiHexFormat",value:function _isAsciiHexFormat(frames){if(!frames||frames.length===0)return false;for(var frame of frames){if(frame.length<2)continue;var firstChar=String.fromCharCode(frame[0]);var secondChar=String.fromCharCode(frame[1]);if(firstChar==='4'&&(secondChar==='3'||secondChar==='7'||secondChar==='A'||secondChar==='a')){return true;}}return false;}},{key:"_isEmptyAsciiFormat",value:function _isEmptyAsciiFormat(frames){var modeResponseHex=this.modeResponse.toString(16).toUpperCase();for(var frame of frames){if(frame.length<4)continue;var frameString=frame.map(function(byte){return String.fromCharCode(byte);}).join('');if(frameString.startsWith(`${modeResponseHex}00`)&&frameString.substring(4).replace(/[\r\n>]/g,'').match(/^A+$/i)){return true;}}return false;}},{key:"decodeDTCs",value:function decodeDTCs(rawResponseBytes){try{this.reset();if(this._isEmptyAsciiFormat(rawResponseBytes)){(0,_logger.log)('debug','Detected empty ASCII hex format, returning empty array');return[];}var isAsciiHexFormat=this._isAsciiHexFormat(rawResponseBytes);if(isAsciiHexFormat){(0,_logger.log)('debug','Detected ASCII hex format response');return this._processStandardAsciiHexFormat(rawResponseBytes);}var dtcs=new Set();var rawDtcs=new Set();(0,_logger.log)('debug','Processing raw response bytes:',rawResponseBytes);if(!rawResponseBytes.length||!rawResponseBytes[0].length){return[];}for(var frame of rawResponseBytes){if(!frame.length)continue;if(frame.length<=2&&frame.some(function(b){return b===13||b===10||b===62;})){continue;}var bytes=[];var frameString=frame.map(function(byte){return String.fromCharCode(byte);}).join('');(0,_logger.log)('debug','Processing frame as string:',frameString);var colonIndex=frameString.indexOf(':');if(colonIndex!==-1){var dataAfterColon=frameString.substring(colonIndex+1);bytes=[];var currentByte=-1;for(var i=0;i<dataAfterColon.length;i++){var nibble=this._getNibbleValue(dataAfterColon.charCodeAt(i));if(nibble===-1)continue;if(currentByte===-1){currentByte=nibble<<4;}else{currentByte|=nibble;bytes.push(currentByte);currentByte=-1;}}}else{bytes=this._convertAsciiToBytes(frame);}(0,_logger.log)('debug','Converted bytes:',bytes);if(bytes.length<2)continue;var startIndex=0;var modeResponseByte=this.getModeResponseByte();for(var _i=0;_i<bytes.length;_i++){if(bytes[_i]===modeResponseByte){startIndex=_i;break;}}if(startIndex>=bytes.length)continue;var dtcData=bytes.slice(startIndex+1);if(dtcData.length>0){var dataStartIndex=0;var possibleCount=dtcData[0];if(possibleCount<modeResponseByte&&possibleCount<=dtcData.length/2){dataStartIndex=1;this.expectedDTCCount=possibleCount;}for(var _i2=dataStartIndex;_i2<dtcData.length-1;_i2+=2){var byte1=dtcData[_i2];var byte2=dtcData[_i2+1];if(byte1===0&&byte2===0)continue;var dtc=this._decodeDTC(byte1.toString(16).padStart(2,'0'),byte2.toString(16).padStart(2,'0'));if(dtc){if(!dtcs.has(dtc)){dtcs.add(dtc);rawDtcs.add(dtc);this.setDTC(dtc);(0,_logger.log)('debug','Found DTC:',dtc);}}}}}this.rawDtcObjects=Array.from(rawDtcs);var dtcArray=Array.from(dtcs);(0,_logger.log)('debug','Discovered DTC count:',dtcArray.length);return dtcArray;}catch(error){(0,_logger.log)('error','Failed to parse response:',error);return[];}}},{key:"_processStandardAsciiHexFormat",value:function _processStandardAsciiHexFormat(frames){var dtcs=new Set();var modeResponseHex=(0,_utils.toHexString)(this.getModeResponseByte()).toUpperCase();for(var frame of frames){var frameString=(0,_utils.byteArrayToString)(frame).replace(/[\r\n>]/g,'');(0,_logger.log)('debug',`Processing ASCII hex frame: ${frameString}`);if(!frameString.startsWith(modeResponseHex)){(0,_logger.log)('debug',`Frame doesn't start with ${modeResponseHex}, skipping`);continue;}var dataAfterMode=frameString.substring(2);(0,_logger.log)('debug',`Full data after mode response: ${dataAfterMode}`);var dtcData=dataAfterMode;var countByte=false;if(dataAfterMode.length>=2){var possibleCountHex=dataAfterMode.substring(0,2);var possibleCount=parseInt(possibleCountHex,16);if(!isNaN(possibleCount)&&possibleCount>0&&possibleCount<=20){(0,_logger.log)('debug',`Detected count byte: ${possibleCountHex} (${possibleCount} DTCs)`);this.expectedDTCCount=possibleCount;dtcData=dataAfterMode.substring(2);countByte=true;}else{(0,_logger.log)('debug',`No count byte detected, parsing all data as DTCs`);}}(0,_logger.log)('debug',`DTC hex data: ${dtcData}`);if(countByte){for(var i=0;i<this.expectedDTCCount;i++){var startPos=i*4;if(startPos+1<dtcData.length){var dtcHex=void 0;if(startPos+3<dtcData.length){dtcHex=dtcData.substring(startPos,startPos+4);}else{var shortCode=dtcData.substring(startPos);if(shortCode.length===2){dtcHex=`01${shortCode}`;(0,_logger.log)('debug',`Expanded shortened DTC code: ${shortCode} -> ${dtcHex}`);}else{dtcHex=shortCode.padEnd(4,'0');}}if(dtcHex==='0000'||!/^[0-9A-F]{4}$/i.test(dtcHex)){continue;}var dtc=(0,_dtcConverter.hexToDTC)(dtcHex);if(dtc){dtcs.add(dtc);(0,_logger.log)('debug',`Found DTC: ${dtc} from hex ${dtcHex}`);this.currentDTCCount++;}}}var processedChars=this.expectedDTCCount*4;if(dtcData.length>processedChars){var remainingData=dtcData.substring(processedChars);for(var _i3=0;_i3<remainingData.length;_i3+=2){if(_i3+1<remainingData.length){var _shortCode=remainingData.substring(_i3,_i3+2);var additionalDtcHex=`01${_shortCode}`;var additionalDtc=(0,_dtcConverter.hexToDTC)(additionalDtcHex);if(additionalDtc){dtcs.add(additionalDtc);(0,_logger.log)('debug',`Found additional DTC: ${additionalDtc} from hex ${additionalDtcHex}`);}}}}}else{for(var _i4=0;_i4<dtcData.length;_i4+=4){if(_i4+3<dtcData.length){var _dtcHex=dtcData.substring(_i4,_i4+4);if(_dtcHex==='0000'||!/^[0-9A-F]{4}$/i.test(_dtcHex)){continue;}var _dtc=(0,_dtcConverter.hexToDTC)(_dtcHex);if(_dtc){dtcs.add(_dtc);(0,_logger.log)('debug',`Found DTC: ${_dtc} from hex ${_dtcHex}`);this.currentDTCCount++;}}}}}var result=Array.from(dtcs);(0,_logger.log)('debug',`Discovered DTC count: ${result.length}`);return result;}},{key:"_decodeDTC",value:function _decodeDTC(byte1,byte2){try{var combinedHex=byte1.padStart(2,'0')+byte2.padStart(2,'0');return(0,_dtcConverter.hexToDTC)(combinedHex);}catch(error){(0,_logger.log)('error','Failed to decode DTC:',error);return null;}}},{key:"_convertAsciiToBytes",value:function _convertAsciiToBytes(asciiBytes){var bytes=[];var currentByte=-1;var asciiString=(0,_utils.byteArrayToString)(asciiBytes);(0,_logger.log)('debug','Converting ASCII string:',asciiString);var modeResponseHex=(0,_utils.toHexString)(this.getModeResponseByte()).toUpperCase();if(asciiString.startsWith(modeResponseHex)){var hexDump=asciiString.replace(/[\r\n>]/g,'');for(var i=0;i<hexDump.length;i+=2){if(i+1<hexDump.length){var hexPair=hexDump.substring(i,i+2);var byteValue=parseInt(hexPair,16);if(!isNaN(byteValue)){bytes.push(byteValue);}}}return bytes;}for(var ascii of asciiBytes){if(ascii===13)continue;var nibble=this._getNibbleValue(ascii);if(nibble===-1)continue;if(currentByte===-1){currentByte=nibble<<4;}else{currentByte|=nibble;bytes.push(currentByte);currentByte=-1;}}return bytes;}},{key:"_getNibbleValue",value:function _getNibbleValue(byte){if(byte>=48&&byte<=57)return byte-48;if(byte>=65&&byte<=70)return byte-55;if(byte>=97&&byte<=102)return byte-87;return-1;}},{key:"_dtcToString",value:function _dtcToString(dtc){return dtc;}},{key:"reset",value:function reset(){this.rawDtcObjects=[];this.expectedDTCCount=0;this.currentDTCCount=0;this.leftoverByte=null;}},{key:"getModeResponseByte",value:function getModeResponseByte(){return this.modeResponse;}},{key:"setDTC",value:function setDTC(dtc){(0,_logger.log)('debug',`Setting DTC: ${dtc}`);}},{key:"isNoDataResponse",value:function isNoDataResponse(frame){if(frame.length>=7){var noDataString=String.fromCharCode.apply(String,(0,_toConsumableArray2.default)(frame.slice(0,7)));return noDataString==='NO DATA';}return false;}},{key:"isAllAFrameResponse",value:function isAllAFrameResponse(frameString){var cleanFrame=frameString.replace(/[\r\n]/g,'');return /^[Aa]+$/.test(cleanFrame);}}]);}(_BaseDecoder2.BaseDecoder);
//# sourceMappingURL=CanSingleFrame.js.map