├── .gitignore
├── README.md
├── ab90_reset.py
├── card_programming.py
├── clio3_eps_reset.py
├── clio4_eps_reset.py
├── laguna2_uch_reset.py
├── laguna3_uch_reset.py
├── megane2_uch_reset.py
├── megane3_ab_reset.py
├── megane3_eps_reset.py
├── megane3_uch_reset.py
├── requirements.txt
├── rsat4_reset.py
└── vin_crc.py
/.gitignore:
--------------------------------------------------------------------------------
1 | /__pycache__/
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ddtplugins
2 |
--------------------------------------------------------------------------------
/ab90_reset.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # (c) 2017
4 |
5 | import PyQt5.QtCore as core
6 | import PyQt5.QtWidgets as gui
7 |
8 | import ecu
9 | import options
10 |
11 | _ = options.translator('ddt4all')
12 |
13 | plugin_name = _("AB90 AIRBAG Reset")
14 | category = _("Airbag Tools")
15 | need_hw = True
16 | ecufile = "AB90_J77_X85"
17 |
18 |
19 | class Virginizer(gui.QDialog):
20 | def __init__(self):
21 | super(Virginizer, self).__init__()
22 | self.airbag_ecu = ecu.Ecu_file(ecufile, True)
23 | layout = gui.QVBoxLayout()
24 | infos = gui.QLabel(_("AB90 (Clio III)/2
"
25 | "AIRBAG VIRGINIZER
THIS PLUGIN WILL UNLOCK AIRBAG CRASH DATA
"
26 | "GO AWAY IF YOU HAVE NO IDEA OF WHAT IT MEANS"))
27 | infos.setAlignment(core.Qt.AlignHCenter)
28 | check_button = gui.QPushButton(_("Check ACU Virgin"))
29 | self.status_check = gui.QLabel(_("Waiting"))
30 | self.status_check.setAlignment(core.Qt.AlignHCenter)
31 | self.virginize_button = gui.QPushButton(_("Virginize ACU"))
32 | layout.addWidget(infos)
33 | layout.addWidget(check_button)
34 | layout.addWidget(self.status_check)
35 | layout.addWidget(self.virginize_button)
36 | self.setLayout(layout)
37 | self.virginize_button.setEnabled(True)
38 | self.virginize_button.clicked.connect(self.reset_ecu)
39 | check_button.clicked.connect(self.check_virgin_status)
40 | self.ecu_connect()
41 |
42 | def ecu_connect(self):
43 | connection = self.airbag_ecu.connect_to_hardware()
44 | if not connection:
45 | options.main_window.logview.append(_("Cannot connect to ECU"))
46 | self.finished()
47 |
48 | def check_virgin_status(self):
49 | self.start_diag_session()
50 |
51 | crash_reset_request = self.airbag_ecu.requests[u'Synthèse état UCE']
52 | values_dict = crash_reset_request.send_request({}, "62 02 04 00 00 00 00 00 00 00 00 00 00 00 00")
53 |
54 | if values_dict is None:
55 | self.status_check.setText(_("UNEXPECTED RESPONSE"))
56 |
57 | crash = values_dict[u'crash détecté']
58 |
59 | if crash == u'crash détecté':
60 | self.status_check.setText(_("CRASH DETECTED"))
61 | else:
62 | self.status_check.setText(_("NO CRASH DETECTED"))
63 |
64 | def start_diag_session(self):
65 | sds_request = self.airbag_ecu.requests[u"Start Diagnostic Session"]
66 |
67 | sds_stream = " ".join(sds_request.build_data_stream({}))
68 | if options.simulation_mode:
69 | print("SdS stream", sds_stream)
70 | return
71 | options.elm.start_session_can(sds_stream)
72 |
73 | def reset_ecu(self):
74 | self.start_diag_session()
75 |
76 | reset_request = self.airbag_ecu.requests[u"Reset crash ou accès au mode fournisseur"]
77 | request_response = reset_request.send_request({u"code d'accès pour reset UCE": '22041998'})
78 |
79 | if request_response is not None:
80 | self.status_check.setText(_("CLEAR EXECUTED"))
81 | else:
82 | self.status_check.setText(_("CLEAR FAILED"))
83 |
84 |
85 | def plugin_entry():
86 | v = Virginizer()
87 | v.exec_()
88 |
--------------------------------------------------------------------------------
/card_programming.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # Plugin to program keys on Megane II
4 | # (c) 2017
5 | # This is an example plugin
6 |
7 |
8 | import PyQt5.QtCore as core
9 | import PyQt5.QtWidgets as gui
10 |
11 | import ecu
12 | import options
13 |
14 | _ = options.translator('ddt4all')
15 |
16 | plugin_name = _("Megane/Scenic II card programming")
17 | category = _("Keys")
18 | need_hw = True
19 | ecufile = "UCH_84_J84_03_60"
20 |
21 | a8_mess = [19, 29, 39, 4, 24, 46, 31, 12,
22 | 16, 28, 7, 10, 15, 0, 40, 26,
23 | 18, 20, 3, 8, 34, 8, 47, 21,
24 | 2, 25, 38, 6, 4, 22, 14, 33,
25 | 17, 1, 44, 11, 32, 41, 36, 42,
26 | 5, 45, 5, 43, 30, 37, 13, 27]
27 |
28 | a8_xor = [0x10, 0x20, 0x20, 0x10, 0x81, 0x88]
29 | a8_xor_2 = [0x10, 0x20, 0x28, 0x10, 0x81, 0x88]
30 |
31 |
32 | def a8(isk_c):
33 | '''MC9S12DG256 (Megane 2, Scenic 2)'''
34 | apv = ''
35 | isk = isk_c.replace(' ', '').decode('hex')
36 | if len(isk) != 6:
37 | return None
38 | bit_i = ''
39 | for c in isk:
40 | bit_i += bin(ord(c))[2:].zfill(8)
41 |
42 | # if not (bit_i[ 4]!=bit_i[23] and bit_i[12]==bit_i[43] and
43 | # bit_i[ 4]==bit_i[35] and bit_i[ 8]==bit_i[ 9] and bit_i[ 4]==bit_i[ 5]):
44 | # return 'Invalid ISK'
45 |
46 | base = ''
47 | for b in a8_xor:
48 | base = base + bin(b)[2:].zfill(8)
49 |
50 | i = 0
51 | for b in base:
52 | z = bit_i[a8_mess[i]]
53 | if b != z:
54 | z = '1'
55 | else:
56 | z = '0'
57 | base = base[:i] + z + base[i + 1:]
58 | i += 1
59 |
60 | for i in range(0, 6):
61 | apv += hex(int(base[i * 8:i * 8 + 8], 2))[2:].zfill(2).upper() + ' '
62 |
63 | return apv
64 |
65 |
66 | def a8_2(isk_c):
67 | '''MC9S12DG256 (algo2)(Megane 2, Scenic 2)'''
68 | apv = ''
69 | isk = isk_c.replace(' ', '').decode('hex')
70 | if len(isk) != 6:
71 | return None
72 | bit_i = ''
73 | for c in isk:
74 | bit_i += bin(ord(c))[2:].zfill(8)
75 |
76 | base = ''
77 | for b in a8_xor_2:
78 | base = base + bin(b)[2:].zfill(8)
79 |
80 | i = 0
81 | for b in base:
82 | z = bit_i[a8_mess[i]]
83 | if b != z:
84 | z = '1'
85 | else:
86 | z = '0'
87 | base = base[:i] + z + base[i + 1:]
88 | i += 1
89 |
90 | for i in range(0, 6):
91 | apv += hex(int(base[i * 8:i * 8 + 8], 2))[2:].zfill(2).upper() + ' '
92 |
93 | return apv
94 |
95 |
96 | def get_isk(ecu_response):
97 | ecu_response = ecu_response.replace(' ', '').strip()
98 | return ecu_response[19 * 2:25 * 2]
99 |
100 |
101 | class CardProg(gui.QDialog):
102 | def __init__(self):
103 | super(CardProg, self).__init__()
104 | options.debug = True
105 | self.apvok = False
106 | self.megane_ecu = ecu.Ecu_file(ecufile, True)
107 | self.start_session_request = self.megane_ecu.requests[u'Start Diagnostic Session']
108 | self.after_sale_request = self.megane_ecu.requests[u'ACCEDER AU MODE APRES-VENTE']
109 | self.learn_key_request = self.megane_ecu.requests[u'APPRENDRE BADGE']
110 | self.key_bits_status = self.megane_ecu.requests[u'Status général des opérations badges Bits']
111 | self.key_bytes_status = self.megane_ecu.requests[u'Status général des opérations badges Octets']
112 | self.reserved_frame_request = self.megane_ecu.requests[u'Trame AB: Trame réservée']
113 | self.learn_validate_request = self.megane_ecu.requests[u'SORTIE DU MODE APV : VALIDATION']
114 | self.learn_cancel_request = self.megane_ecu.requests[u'SORTIE DU MODE APV : ABANDON']
115 |
116 | self.ecu_connect()
117 | self.start_diag_session()
118 |
119 | self.apv_access_button = gui.QPushButton(_("ENTER AFTER SALE MODE"))
120 | self.apv_access_button.clicked.connect(self.set_apv_from_input)
121 | self.pininput = gui.QLineEdit()
122 | self.pininput.setText("0" * 12)
123 | self.pininput.setInputMask("H" * 12)
124 | self.iskoutput = gui.QLineEdit()
125 | self.iskoutput.setInputMask("H" * 12)
126 | self.numkeys_label = gui.QLabel("0")
127 | self.currentcardide = gui.QLineEdit()
128 | self.currentcardide.setReadOnly(True)
129 | self.apv_status = gui.QLabel("")
130 | self.apv_status.setAlignment(core.Qt.AlignHCenter)
131 | label = gui.QLabel(_("MEGANE II CARD PROGRAMMING
EXPERIMENTAL : NOT TESTED YET"))
132 | label.setAlignment(core.Qt.AlignHCenter)
133 | self.learnbutton = gui.QPushButton(_("LEARN"))
134 | self.validatebutton = gui.QPushButton(_("VALIDATE"))
135 | self.cancelbutton = gui.QPushButton(_("CANCEL"))
136 |
137 | self.algocheck = gui.QCheckBox(_("Algo 2"))
138 | self.algocheck.setChecked(False)
139 |
140 | self.learnbutton.clicked.connect(self.learn_action)
141 | self.validatebutton.clicked.connect(self.validate_action)
142 | self.cancelbutton.clicked.connect(self.cancel_action)
143 | self.iskoutput.textChanged.connect(self.calculate_pin)
144 | self.algocheck.toggled.connect(self.calculate_pin)
145 |
146 | layout = gui.QGridLayout()
147 | layout.addWidget(label, 0, 0, 1, 0)
148 | layout.addWidget(gui.QLabel(_("ISK")), 1, 0)
149 | layout.addWidget(self.iskoutput, 1, 1)
150 | layout.addWidget(gui.QLabel(_("PIN")), 2, 0)
151 | layout.addWidget(self.pininput, 2, 1)
152 | layout.addWidget(self.algocheck, 3, 1)
153 | layout.addWidget(self.apv_access_button, 4, 0, 1, 0)
154 | layout.addWidget(self.apv_status, 5, 0, 1, 0)
155 | layout.addWidget(gui.QLabel(_("Num key learnt")), 6, 0)
156 | layout.addWidget(self.numkeys_label, 6, 1)
157 | layout.addWidget(gui.QLabel(_("CARD IDE")), 7, 0)
158 | layout.addWidget(self.currentcardide, 7, 1)
159 | layout.addWidget(self.learnbutton, 8, 0, 1, 0)
160 | layout.addWidget(self.validatebutton, 9, 0)
161 | layout.addWidget(self.cancelbutton, 9, 1)
162 |
163 | self.setLayout(layout)
164 |
165 | # I have to use a timer here to avoid ECU from escaping session mode
166 | # A shot every 1.5 seconds is enough, normally
167 | self.tester_timer = core.QTimer()
168 | self.tester_timer.setSingleShot(False)
169 | self.tester_timer.setInterval(1500)
170 | self.tester_timer.timeout.connect(self.check_all)
171 |
172 | isk = self.get_isk()
173 | self.iskoutput.setText(isk)
174 |
175 | self.tester_timer.start()
176 |
177 | def calculate_pin(self):
178 | ISK = ''.join(str(ord(c)) for c in str(self.iskoutput.text()))
179 | if len(ISK) == 12:
180 | if self.algocheck.checkState():
181 | PIN = a8_2(ISK)
182 | else:
183 | PIN = a8(ISK)
184 | if PIN is not None:
185 | self.pininput.setText(PIN)
186 | self.iskoutput.setStyleSheet("color: green;")
187 | return
188 |
189 | self.pininput.setText("000000000000")
190 | self.iskoutput.setStyleSheet("color: red;")
191 |
192 | def learn_action(self):
193 | self.learn_key_request.send_request()
194 |
195 | def validate_action(self):
196 | self.learn_validate_request.send_request()
197 |
198 | def cancel_action(self):
199 | self.learn_cancel_request.send_request()
200 |
201 | def get_isk(self):
202 | # No dataitem for ISK :(
203 | # Need to decode by myself
204 | if options.simulation_mode:
205 | reply = "61 AB 02 FC 0D 08 51 4C 86 55 54 00 00 00 00 00 00 00 00 8D E8 EE 16 79 D3 C9 A7 A7 CC " \
206 | "F6 AC 00 00 00 00 00 00 2A"
207 | else:
208 | reply = options.elm.request(self.reserved_frame_request.sentbytes)
209 |
210 | if reply.startswith('7F') or reply.startswith('WRONG'):
211 | options.main_window.logview.append(_("Cannot get ISK, check connections and UCH compatibility"))
212 | return
213 |
214 | isk = reply.replace(' ', '').strip()
215 | return get_isk(isk)
216 |
217 | def ecu_connect(self):
218 | connection = self.megane_ecu.connect_to_hardware()
219 | if not connection:
220 | options.main_window.logview.append(_("Cannot connect to ECU"))
221 | self.finished()
222 |
223 | def check_all(self):
224 | self.check_apv_status()
225 | self.check_num_key_learnt()
226 |
227 | def set_apv_from_input(self):
228 | apv = ''.join(str(ord(c)) for c in str(self.pininput.text()))
229 | if len(apv) != 12:
230 | return
231 | self.after_sale_request.send_request({u'Code APV': apv})
232 |
233 | def enable_buttons(self, enable):
234 | self.learnbutton.setEnabled(enable)
235 | self.validatebutton.setEnabled(enable)
236 | self.cancelbutton.setEnabled(enable)
237 |
238 | def check_apv_status(self):
239 | key_bits_status_values = self.key_bits_status.send_request({}, "61 06 21 21 20 00 00 00 08 00 00 80 03")
240 |
241 | value_apv_ok = key_bits_status_values[u'VSC Code APV_Reconnu']
242 | value_apv_reaff = key_bits_status_values[u'VSC ModeAPV_ReaffArmé']
243 | value_apv_uch_reaff = key_bits_status_values[u'VSC ModeAPV_AppUCH_Armé']
244 |
245 | if value_apv_ok == '0':
246 | self.apv_status.setText(_("PIN CODE NOT RECOGNIZED"))
247 | self.apvok = False
248 | self.enable_buttons(False)
249 | return
250 |
251 | if value_apv_reaff == '1':
252 | self.apv_status.setText(_("PIN CODE OK / KEY LEARNING"))
253 | self.enable_buttons(True)
254 | self.apvok = True
255 | return
256 |
257 | elif value_apv_uch_reaff == '1':
258 | self.apv_status.setText(_("PIN CODE OK / UCH LEARNING"))
259 | self.enable_buttons(True)
260 | self.apvok = True
261 | return
262 |
263 | self.apvok = False
264 | self.enable_buttons(False)
265 |
266 | self.apv_status.setText("UCH NOT READY")
267 |
268 | def check_num_key_learnt(self):
269 | key_bytes_status_value = self.key_bytes_status.send_request({}, "61 08 00 00 00 00 00 00 0A 00 00 00 00 00 00 "
270 | "00 00 00 00 00 00 00 00 00 00 02 00 00 01 2C "
271 | "00 00 01 2C 00 00 2C 00 00 01 2C")
272 |
273 | num_key_learnt = key_bytes_status_value[u'VSC NbTotalDeBadgeAppris']
274 | current_key_ide = key_bytes_status_value[u'VSC Code_IDE']
275 |
276 | self.numkeys_label.setText(num_key_learnt)
277 | self.currentcardide.setText(current_key_ide)
278 |
279 | def start_diag_session(self):
280 | sds_request = self.megane_ecu.requests[u"Start Diagnostic Session"]
281 | sds_stream = " ".join(sds_request.build_data_stream({}))
282 | if options.simulation_mode:
283 | print("SdS stream", sds_stream)
284 | return
285 | options.elm.start_session_can(sds_stream)
286 |
287 |
288 | def plugin_entry():
289 | cp = CardProg()
290 | cp.exec_()
291 |
--------------------------------------------------------------------------------
/clio3_eps_reset.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # (c) 2017
4 |
5 | from binascii import unhexlify
6 |
7 | import PyQt5.QtCore as core
8 | import PyQt5.QtWidgets as gui
9 | import crcmod
10 |
11 | import ecu
12 | import options
13 |
14 | _ = options.translator('ddt4all')
15 |
16 | plugin_name = _("Modus/Clio III EPS Reset")
17 | category = _("EPS Tools")
18 | need_hw = True
19 | ecufile = "DAE_J77_X85_Gen2___v3.7"
20 |
21 |
22 | def calc_crc(vin=None):
23 | VIN = vin.encode("hex")
24 | VININT = unhexlify(VIN)
25 |
26 | crc16 = crcmod.predefined.Crc('x-25')
27 | crc16.update(VININT)
28 | crcle = crc16.hexdigest()
29 | # Seems that computed CRC is returned in little endian way
30 | # Convert it to big endian
31 | return crcle[2:4] + crcle[0:2]
32 |
33 |
34 | class Virginizer(gui.QDialog):
35 | def __init__(self):
36 | super(Virginizer, self).__init__()
37 | self.clio_eps = ecu.Ecu_file(ecufile, True)
38 | layout = gui.QVBoxLayout()
39 | infos = gui.QLabel(
40 | _("Modus/Clio III EPS VIRGINIZER
THIS PLUGIN WILL RESET EPS IMMO DATA
GO AWAY IF YOU HAVE NO IDEA OF WHAT IT MEANS"))
41 | infos.setAlignment(core.Qt.AlignHCenter)
42 | check_button = gui.QPushButton(_("BLANK STATUS & VIN READ"))
43 | self.status_check = gui.QLabel(_("Waiting"))
44 | self.status_check.setAlignment(core.Qt.AlignHCenter)
45 | self.virginize_button = gui.QPushButton(_("Virginize EPS"))
46 |
47 | self.setLayout(layout)
48 | self.virginize_button.setEnabled(False)
49 | self.virginize_button.clicked.connect(self.reset_ecu)
50 | check_button.clicked.connect(self.check_virgin_status)
51 | status_vin = gui.QLabel(_("VIN - READ"))
52 | status_vin.setAlignment(core.Qt.AlignHCenter)
53 | self.vin_input = gui.QLineEdit()
54 | self.vin_input.setReadOnly(True)
55 |
56 | status_vinout = gui.QLabel(_("VIN - WRITE"))
57 | status_vinout.setAlignment(core.Qt.AlignHCenter)
58 | self.vin_output = gui.QLineEdit()
59 |
60 | write_vin_button = gui.QPushButton(_("Write VIN"))
61 | write_vin_button.clicked.connect(self.write_vin)
62 |
63 | layout.addWidget(infos)
64 | layout.addWidget(check_button)
65 | layout.addWidget(self.status_check)
66 | layout.addWidget(self.virginize_button)
67 | layout.addWidget(self.virginize_button)
68 |
69 | layout.addWidget(status_vin)
70 | layout.addWidget(self.vin_input)
71 | layout.addWidget(status_vinout)
72 | layout.addWidget(self.vin_output)
73 | layout.addWidget(write_vin_button)
74 |
75 | self.ecu_connect()
76 |
77 | def read_vin(self):
78 | vin_read_request = self.clio_eps.requests[u'RDBLI - VIN']
79 | vin_values = vin_read_request.send_request({}, "61 81 68 69 70 65 65 65 65 65 65 65 65 65 65 65 65 65 66 00 00")
80 | self.vin_input.setText(vin_values[u'VIN'])
81 |
82 | def write_vin(self):
83 | try:
84 | vin = str(self.vin_output.text().toAscii()).upper()
85 | self.vin_output.setText(vin)
86 | except:
87 | self.status_check.setText(_("VIN - INVALID"))
88 | return
89 |
90 | if len(vin) != 17:
91 | self.status_check.setText(_("VIN - BAD LENGTH"))
92 | return
93 |
94 | crc = calc_crc(vin).decode('hex')
95 | self.start_diag_session()
96 | vin_wrtie_request = self.clio_eps.requests[u'WDBLI - VIN']
97 | write_response = vin_wrtie_request.send_request({u'VIN': vin, u'CRC VIN': crc})
98 | if write_response is None:
99 | self.status_check.setText(_("VIN WRITE FAILED"))
100 | return
101 |
102 | self.status_check.setText(_("VIN WRITE OK"))
103 |
104 | def ecu_connect(self):
105 | connection = self.clio_eps.connect_to_hardware()
106 | if not connection:
107 | options.main_window.logview.append(_("Cannot connect to ECU"))
108 | self.finished()
109 |
110 | def check_virgin_status(self):
111 | self.start_diag_session()
112 | self.read_vin()
113 | virigin_check_request = self.clio_eps.requests[u'RDBLI - System Frame']
114 | virgin_check_values = virigin_check_request.send_request({}, "62 01 64 00 00 00 00 00 00 00 00 00 00 00 00 " \
115 | "00 00 00 00 00 00 00 00 00")
116 |
117 | if virgin_check_values is not None:
118 | virgin_status = virgin_check_values[u"Dongle status"]
119 |
120 | if options.debug:
121 | print(virgin_status)
122 |
123 | if virgin_status == u'Système VIERGE - Aucun code mémorisé':
124 | self.virginize_button.setEnabled(False)
125 | self.status_check.setText(_("EPS virgin"))
126 | return
127 | else:
128 | self.virginize_button.setEnabled(True)
129 | self.status_check.setText(_("EPS coded"))
130 | return
131 |
132 | self.status_check.setText(_("UNEXPECTED RESPONSE"))
133 |
134 | def start_diag_session_fb(self):
135 | sds_request = self.clio_eps.requests[u"SDS - Start Diagnostic $FB"]
136 | sds_stream = " ".join(sds_request.build_data_stream({}))
137 |
138 | if options.simulation_mode:
139 | print("SdSFB stream", sds_stream)
140 | return
141 |
142 | options.elm.start_session_can(sds_stream)
143 |
144 | def start_diag_session(self):
145 | sds_request = self.clio_eps.requests[u"Start Diagnostic Session"]
146 | sds_stream = " ".join(sds_request.build_data_stream({}))
147 |
148 | if options.simulation_mode:
149 | print("SdSC0 stream", sds_stream)
150 | return
151 |
152 | options.elm.start_session_can(sds_stream)
153 |
154 | def reset_ecu(self):
155 | self.start_diag_session_fb()
156 | reset_request = self.clio_eps.requests[u"WDBLI - Erase of Dongle_ID code"]
157 | request_response = reset_request.send_request()
158 |
159 | if request_response is not None:
160 | self.status_check.setText(_("CLEAR EXECUTED"))
161 | else:
162 | self.status_check.setText(_("CLEAR FAILED"))
163 |
164 |
165 | def plugin_entry():
166 | v = Virginizer()
167 | v.exec_()
168 |
--------------------------------------------------------------------------------
/clio4_eps_reset.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # (c) 2017
4 |
5 | import PyQt5.QtCore as core
6 | import PyQt5.QtWidgets as gui
7 |
8 | import ecu
9 | import options
10 |
11 | _ = options.translator('ddt4all')
12 |
13 | plugin_name = _("Clio IV EPS Reset")
14 | category = _("EPS Tools")
15 | need_hw = True
16 | ecufile = "X98ph2_X87ph2_EPS_HFP_v1.00_20150622T140219_20160726T172209"
17 |
18 |
19 | class Virginizer(gui.QDialog):
20 | def __init__(self):
21 | super(Virginizer, self).__init__()
22 | self.clio_eps = ecu.Ecu_file(ecufile, True)
23 | layout = gui.QVBoxLayout()
24 | infos = gui.QLabel(
25 | _("Clio IV EPS VIRGINIZER
THIS PLUGIN WILL RESET EPS IMMO DATA
GO AWAY IF YOU HAVE NO IDEA OF WHAT IT MEANS"))
26 | infos.setAlignment(core.Qt.AlignHCenter)
27 | check_button = gui.QPushButton(_("Check EPS Virgin"))
28 | self.status_check = gui.QLabel(_("Waiting"))
29 | self.status_check.setAlignment(core.Qt.AlignHCenter)
30 | self.virginize_button = gui.QPushButton(_("Virginize EPS"))
31 | layout.addWidget(infos)
32 | layout.addWidget(check_button)
33 | layout.addWidget(self.status_check)
34 | layout.addWidget(self.virginize_button)
35 | self.setLayout(layout)
36 | self.virginize_button.setEnabled(False)
37 | self.virginize_button.clicked.connect(self.reset_ecu)
38 | check_button.clicked.connect(self.check_virgin_status)
39 | self.ecu_connect()
40 |
41 | def ecu_connect(self):
42 | connection = self.clio_eps.connect_to_hardware()
43 | if not connection:
44 | options.main_window.logview.append(_("Cannot connect to ECU"))
45 | self.finished()
46 |
47 | def check_virgin_status(self):
48 | self.start_diag_session_c0()
49 |
50 | virigin_check_request = self.clio_eps.requests[u'DataRead.DongleState']
51 | request_values = virigin_check_request.send_request()
52 |
53 | if request_values is not None:
54 | if u'DongleState' in request_values:
55 | donglestate = request_values[u'DongleState']
56 |
57 | if donglestate == u'NotOperational':
58 | self.virginize_button.setEnabled(False)
59 | self.status_check.setText(_("EPS not operational"))
60 | return
61 |
62 | if donglestate == u'OperationalBlanked':
63 | self.virginize_button.setEnabled(False)
64 | self.status_check.setText(_("EPS virgin"))
65 | return
66 |
67 | if donglestate == u'OperationalLearnt':
68 | self.virginize_button.setEnabled(True)
69 | self.status_check.setText(_("EPS coded"))
70 | return
71 |
72 | self.status_check.setText(_("UNEXPECTED RESPONSE"))
73 |
74 | def start_diag_session_fa(self):
75 | sds_request = self.clio_eps.requests[u"StartDiagnosticSession.supplierSession"]
76 | sds_stream = " ".join(sds_request.build_data_stream({}))
77 | if options.simulation_mode:
78 | print("SdSFA stream", sds_stream)
79 | return
80 | options.elm.start_session_can(sds_stream)
81 |
82 | def start_diag_session_c0(self):
83 | sds_request = self.clio_eps.requests[u"StartDiagnosticSession.extendedSession"]
84 | sds_stream = " ".join(sds_request.build_data_stream({}))
85 | if options.simulation_mode:
86 | print("SdSC0 stream", sds_stream)
87 | return
88 | options.elm.start_session_can(sds_stream)
89 |
90 | def reset_ecu(self):
91 | self.start_diag_session_fa()
92 |
93 | reset_request = self.clio_eps.requests[u"SRBLID.DongleBlanking.Request"]
94 | request_response = reset_request.send_request({u'Dongle.Code': '1976'})
95 |
96 | if request_response is not None:
97 | self.status_check.setText(_("CLEAR EXECUTED"))
98 | else:
99 | self.status_check.setText(_("CLEAR FAILED"))
100 |
101 |
102 | def plugin_entry():
103 | v = Virginizer()
104 | v.exec_()
105 |
--------------------------------------------------------------------------------
/laguna2_uch_reset.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # (c) 2017
4 | # This is an example plugin
5 |
6 | import PyQt5.QtCore as core
7 | import PyQt5.QtWidgets as gui
8 |
9 | import ecu
10 | import options
11 |
12 | _ = options.translator('ddt4all')
13 |
14 | plugin_name = _("Laguna II UCH Reset")
15 | category = _("UCH Tools")
16 | need_hw = True
17 | ecufile = "UCH___M2S_X74_et_X73"
18 |
19 |
20 | class Virginizer(gui.QDialog):
21 | def __init__(self):
22 | super(Virginizer, self).__init__()
23 | self.laguna_uch = ecu.Ecu_file(ecufile, True)
24 | layout = gui.QVBoxLayout()
25 | infos = gui.QLabel(
26 | _("LAGUNA II UCH VIRGINIZER
THIS PLUGIN WILL ERASE YOUR UCH
GO AWAY IF YOU HAVE NO IDEA OF WHAT IT MEANS"))
27 | infos.setAlignment(core.Qt.AlignHCenter)
28 | check_button = gui.QPushButton(_("Check UCH Virgin"))
29 | self.status_check = gui.QLabel(_("Waiting"))
30 | self.status_check.setAlignment(core.Qt.AlignHCenter)
31 | self.virginize_button = gui.QPushButton(_("Virginize UCH"))
32 | layout.addWidget(infos)
33 | layout.addWidget(check_button)
34 | layout.addWidget(self.status_check)
35 | layout.addWidget(self.virginize_button)
36 | self.setLayout(layout)
37 | self.virginize_button.setEnabled(False)
38 | self.virginize_button.clicked.connect(self.reset_ecu)
39 | check_button.clicked.connect(self.check_virgin_status)
40 | self.ecu_connect()
41 | # Start comm immediately
42 | self.start_diag_session_study()
43 |
44 | def ecu_connect(self):
45 | connection = self.laguna_uch.connect_to_hardware()
46 | if not connection:
47 | options.main_window.logview.append(_("Cannot connect to ECU"))
48 | self.finished()
49 |
50 | def check_virgin_status(self):
51 | self.start_diag_session_aftersales()
52 |
53 | virigin_check_request = self.laguna_uch.requests[u'Lecture Etats Antidémarrage et acces']
54 | response_values = virigin_check_request.send_request()
55 |
56 | if response_values is not None:
57 | virgin = response_values[u"UCH vierge"]
58 |
59 | if virgin == u'oui':
60 | self.virginize_button.setEnabled(False)
61 | self.status_check.setText(_("UCH virgin"))
62 | return
63 |
64 | if virgin == u'non':
65 | self.virginize_button.setEnabled(True)
66 | self.status_check.setText(_("UCH coded"))
67 | return
68 |
69 | self.status_check.setText(_("UNEXPECTED RESPONSE"))
70 |
71 | def start_diag_session_study(self):
72 | sds_request = self.laguna_uch.requests[u"Start Diagnostic Session"]
73 | sds_stream = " ".join(sds_request.build_data_stream({u'Session Name': u'Etude'}))
74 | if options.simulation_mode:
75 | print("SdSA stream", sds_stream)
76 | return
77 | options.elm.start_session_iso(sds_stream)
78 |
79 | def start_diag_session_aftersales(self):
80 | sds_request = self.laguna_uch.requests[u"Start Diagnostic Session"]
81 | sds_stream = " ".join(sds_request.build_data_stream({u'Session Name': u'APV'}))
82 | if options.simulation_mode:
83 | print("SdSS stream", sds_stream)
84 | return
85 | options.elm.request(sds_stream)
86 |
87 | def reset_ecu(self):
88 | self.start_diag_session_study()
89 |
90 | reset_request = self.laguna_uch.requests[u"Effacement_données_antidem_acces"]
91 | request_response = reset_request.send_request()
92 |
93 | if request_response is not None:
94 | self.status_check.setText(_("CLEAR EXECUTED"))
95 | else:
96 | self.status_check.setText(_("CLEAR FAILED"))
97 |
98 |
99 | def plugin_entry():
100 | v = Virginizer()
101 | v.exec_()
102 |
--------------------------------------------------------------------------------
/laguna3_uch_reset.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # (c) 2017
4 |
5 | import PyQt5.QtCore as core
6 | import PyQt5.QtWidgets as gui
7 |
8 | import ecu
9 | import options
10 |
11 | _ = options.translator('ddt4all')
12 |
13 | plugin_name = _("Laguna III UCH Reset")
14 | category = _("UCH Tools")
15 | need_hw = True
16 | ecufile = "BCM_X91_L43_S_S_SWC_v1.30_20140613T140906"
17 |
18 |
19 | class Virginizer(gui.QDialog):
20 | def __init__(self):
21 | super(Virginizer, self).__init__()
22 | self.megane_uch = ecu.Ecu_file(ecufile, True)
23 | layout = gui.QVBoxLayout()
24 | infos = gui.QLabel(
25 | _("LAGUNA III UCH VIRGINIZER
THIS PLUGIN WILL ERASE YOUR UCH
GO AWAY IF YOU HAVE NO IDEA OF WHAT IT MEANS"))
26 | infos.setAlignment(core.Qt.AlignHCenter)
27 | check_button = gui.QPushButton(_("Check UCH Virgin"))
28 | self.status_check = gui.QLabel(_("Waiting"))
29 | self.status_check.setAlignment(core.Qt.AlignHCenter)
30 | self.virginize_button = gui.QPushButton(_("Virginize UCH"))
31 | layout.addWidget(infos)
32 | layout.addWidget(check_button)
33 | layout.addWidget(self.status_check)
34 | layout.addWidget(self.virginize_button)
35 | self.setLayout(layout)
36 | self.virginize_button.setEnabled(False)
37 | self.virginize_button.clicked.connect(self.reset_ecu)
38 | check_button.clicked.connect(self.check_virgin_status)
39 | self.ecu_connect()
40 |
41 | def ecu_connect(self):
42 | connection = self.megane_uch.connect_to_hardware()
43 | if not connection:
44 | options.main_window.logview.append(_("Cannot connect to ECU"))
45 | self.finished()
46 |
47 | def check_virgin_status(self):
48 | self.start_diag_session_aftersales()
49 |
50 | virigin_check_request = self.megane_uch.requests[
51 | u'Read_A_AC_General_Identifiers_Learning_Status_(bits)_BCM_Input/Output']
52 | virgin_check_values = virigin_check_request.send_request()
53 |
54 | if virgin_check_values is not None:
55 | virgin = virgin_check_values[u"BCM_IS_BLANK_S"]
56 | if virgin == u'true':
57 | self.virginize_button.setEnabled(False)
58 | self.status_check.setText(_("UCH virgin"))
59 | return
60 |
61 | if virgin == u'false':
62 | self.virginize_button.setEnabled(True)
63 | self.status_check.setText(_("UCH coded"))
64 | return
65 |
66 | self.status_check.setText("UNEXPECTED RESPONSE")
67 |
68 | def start_diag_session_aftersales(self):
69 | sds_request = self.megane_uch.requests[u"Start Diagnostic Session"]
70 | sds_stream = " ".join(sds_request.build_data_stream({}))
71 | if options.simulation_mode:
72 | print("SdSS stream", sds_stream)
73 | return
74 | options.elm.start_session_can(sds_stream)
75 |
76 | def reset_ecu(self):
77 | self.start_diag_session_aftersales()
78 |
79 | reset_request = self.megane_uch.requests[u"SR_RESERVED VSC 1"]
80 | request_response = reset_request.send_request()
81 |
82 | if request_response is not None:
83 | self.status_check.setText(_("CLEAR EXECUTED"))
84 | else:
85 | self.status_check.setText(_("CLEAR FAILED"))
86 |
87 |
88 | def plugin_entry():
89 | v = Virginizer()
90 | v.exec_()
91 |
--------------------------------------------------------------------------------
/megane2_uch_reset.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # (c) 2017
4 | # This is an example plugin
5 |
6 | import PyQt5.QtCore as core
7 | import PyQt5.QtWidgets as gui
8 |
9 | import ecu
10 | import options
11 |
12 | _ = options.translator('ddt4all')
13 |
14 | plugin_name = _("Megane/Scenic II UCH Reset")
15 | category = _("UCH Tools")
16 | need_hw = True
17 |
18 |
19 | class Virginizer(gui.QDialog):
20 | def __init__(self):
21 | super(Virginizer, self).__init__()
22 | self.megane_uch = ecu.Ecu_file("UCH_84_J84_03_60", True)
23 | layout = gui.QVBoxLayout()
24 | infos = gui.QLabel(
25 | _("MEGANE II UCH VIRGINIZER
THIS PLUGIN WILL ERASE YOUR UCH
GO AWAY IF YOU HAVE NO IDEA OF WHAT IT MEANS"))
26 | infos.setAlignment(core.Qt.AlignHCenter)
27 | check_button = gui.QPushButton(_("Check UCH Virgin"))
28 | self.status_check = gui.QLabel(_("Waiting"))
29 | self.status_check.setAlignment(core.Qt.AlignHCenter)
30 | self.virginize_button = gui.QPushButton(_("Virginize UCH"))
31 | layout.addWidget(infos)
32 | layout.addWidget(check_button)
33 | layout.addWidget(self.status_check)
34 | layout.addWidget(self.virginize_button)
35 | self.setLayout(layout)
36 | self.virginize_button.setEnabled(False)
37 | self.virginize_button.clicked.connect(self.reset_ecu)
38 | check_button.clicked.connect(self.check_virgin_status)
39 | self.ecu_connect()
40 |
41 | def ecu_connect(self):
42 | connection = self.megane_uch.connect_to_hardware()
43 | if not connection:
44 | options.main_window.logview.append(_("Cannot connect to ECU"))
45 | self.finished()
46 |
47 | def check_virgin_status(self):
48 | self.start_diag_session_aftersales()
49 |
50 | virigin_check_request = self.megane_uch.requests[u'Status général des opérations badges Bits']
51 | request_values = virigin_check_request.send_request()
52 |
53 | if request_values is not None:
54 | virgin = request_values[u"VSC UCH vierge (NbBadgeAppris=0)"]
55 | if virgin == u'Vierge':
56 | self.virginize_button.setEnabled(False)
57 | self.status_check.setText(_("UCH virgin"))
58 | return
59 |
60 | if virgin == u'Codée':
61 | self.virginize_button.setEnabled(True)
62 | self.status_check.setText(_("UCH coded"))
63 | return
64 |
65 | self.status_check.setText(_("UNEXPECTED RESPONSE"))
66 |
67 | def start_diag_session_study(self):
68 | sds_request = self.megane_uch.requests[u"StartDiagSession Etude"]
69 | sds_stream = " ".join(sds_request.build_data_stream({}))
70 | if options.simulation_mode:
71 | print("SdSA stream", sds_stream)
72 | return
73 | options.elm.start_session_can(sds_stream)
74 |
75 | def start_diag_session_aftersales(self):
76 | sds_request = self.megane_uch.requests[u"Start Diagnostic Session"]
77 | sds_stream = " ".join(sds_request.build_data_stream({}))
78 | if options.simulation_mode:
79 | print("SdSS stream", sds_stream)
80 | return
81 | options.elm.start_session_can(sds_stream)
82 |
83 | def reset_ecu(self):
84 | self.start_diag_session_study()
85 |
86 | reset_request = self.megane_uch.requests[u"RAZ EEPROM"]
87 | request_response = reset_request.send_request()
88 |
89 | if request_response is not None:
90 | self.status_check.setText(_("CLEAR EXECUTED"))
91 | else:
92 | self.status_check.setText(_("CLEAR FAILED"))
93 |
94 |
95 | def plugin_entry():
96 | v = Virginizer()
97 | v.exec_()
98 |
--------------------------------------------------------------------------------
/megane3_ab_reset.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # (c) 2017
4 |
5 | import PyQt5.QtCore as core
6 | import PyQt5.QtWidgets as gui
7 |
8 | import ecu
9 | import options
10 |
11 | _ = options.translator('ddt4all')
12 |
13 | plugin_name = _("Megane3 AIRBAG Reset")
14 | category = _("Airbag Tools")
15 | need_hw = True
16 | ecufile = "MRSZ_X95_L38_L43_L47_20110505T101858"
17 |
18 |
19 | class Virginizer(gui.QDialog):
20 | def __init__(self):
21 | super(Virginizer, self).__init__()
22 | self.airbag_ecu = ecu.Ecu_file(ecufile, True)
23 | layout = gui.QVBoxLayout()
24 | infos = gui.QLabel(_("Megane III
"
25 | "AIRBAG VIRGINIZER
THIS PLUGIN WILL UNLOCK AIRBAG CRASH DATA
"
26 | "GO AWAY IF YOU HAVE NO IDEA OF WHAT IT MEANS"))
27 | infos.setAlignment(core.Qt.AlignHCenter)
28 | check_button = gui.QPushButton(_("Check ACU Virgin"))
29 | self.status_check = gui.QLabel(_("Waiting"))
30 | self.status_check.setAlignment(core.Qt.AlignHCenter)
31 | self.virginize_button = gui.QPushButton(_("Virginize ACU"))
32 | layout.addWidget(infos)
33 | layout.addWidget(check_button)
34 | layout.addWidget(self.status_check)
35 | layout.addWidget(self.virginize_button)
36 | self.setLayout(layout)
37 | self.virginize_button.setEnabled(True)
38 | self.virginize_button.clicked.connect(self.reset_ecu)
39 | check_button.clicked.connect(self.check_virgin_status)
40 | self.ecu_connect()
41 |
42 | def ecu_connect(self):
43 | connection = self.airbag_ecu.connect_to_hardware()
44 | if not connection:
45 | options.main_window.logview.append(_("Cannot connect to ECU"))
46 | self.finished()
47 |
48 | def check_virgin_status(self):
49 | self.start_diag_session()
50 |
51 | crash_reset_request = self.airbag_ecu.requests[u'Synthèse état UCE avant crash']
52 | values_dict = crash_reset_request.send_request({}, "62 02 04 00 00 00 00 00 00 00 00 00 00 00 00")
53 |
54 | if values_dict is None:
55 | self.status_check.setText(_("UNEXPECTED RESPONSE"))
56 |
57 | crash = values_dict[u'crash détecté']
58 |
59 | if options.debug:
60 | print(">> ", crash)
61 |
62 | if crash == u'crash détecté':
63 | self.status_check.setText(_("CRASH DETECTED"))
64 | else:
65 | self.status_check.setText(-("NO CRASH DETECTED"))
66 |
67 | def start_diag_session_fa(self):
68 | sds_request = self.airbag_ecu.requests[u"Start Diagnostic Session"]
69 |
70 | sds_stream = " ".join(sds_request.build_data_stream({u"Session Name": u"systemSupplierSpecific"}))
71 | if options.simulation_mode:
72 | print("SdSFA stream", sds_stream)
73 | return
74 | options.elm.start_session_can(sds_stream)
75 |
76 | def start_diag_session(self):
77 | sds_request = self.airbag_ecu.requests[u"Start Diagnostic Session"]
78 |
79 | sds_stream = " ".join(sds_request.build_data_stream({u"Session Name": u"extendedDiagnosticSession"}))
80 | if options.simulation_mode:
81 | print("SdS stream", sds_stream)
82 | return
83 | options.elm.start_session_can(sds_stream)
84 |
85 | def reset_ecu(self):
86 | self.start_diag_session_fa()
87 |
88 | reset_request = self.airbag_ecu.requests[u"Reset crash ou accès au mode fournisseur"]
89 | request_response = reset_request.send_request({u"code d'accès pour reset UCE": '27081977'})
90 |
91 | if request_response is not None:
92 | self.status_check.setText(_("CLEAR EXECUTED"))
93 | else:
94 | self.status_check.setText(_("CLEAR FAILED"))
95 |
96 |
97 | def plugin_entry():
98 | v = Virginizer()
99 | v.exec_()
100 |
--------------------------------------------------------------------------------
/megane3_eps_reset.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # (c) 2017
4 |
5 | import PyQt5.QtCore as core
6 | import PyQt5.QtWidgets as gui
7 |
8 | import ecu
9 | import options
10 |
11 | _ = options.translator('ddt4all')
12 |
13 | plugin_name = _("ZOE/FLENCE/Megane III/Scenic III EPS Reset")
14 | category = _("EPS Tools")
15 | need_hw = True
16 |
17 |
18 | class Virginizer(gui.QDialog):
19 | def __init__(self):
20 | super(Virginizer, self).__init__()
21 | self.megane_eps = ecu.Ecu_file("DAE_X95_X38_X10_v1.88_20120228T113904", True)
22 | layout = gui.QVBoxLayout()
23 | infos = gui.QLabel(
24 | _("ZOE/FLENCE/Megane III/Scenic III EPS VIRGINIZER
THIS PLUGIN WILL RESET EPS IMMO DATA
GO AWAY IF YOU HAVE NO IDEA OF WHAT IT MEANS"))
25 | infos.setAlignment(core.Qt.AlignHCenter)
26 | check_button = gui.QPushButton(_("Check EPS Virgin"))
27 | self.status_check = gui.QLabel(_("Waiting"))
28 | self.status_check.setAlignment(core.Qt.AlignHCenter)
29 | self.virginize_button = gui.QPushButton(_("Virginize EPS"))
30 | layout.addWidget(infos)
31 | layout.addWidget(check_button)
32 | layout.addWidget(self.status_check)
33 | layout.addWidget(self.virginize_button)
34 | self.setLayout(layout)
35 | self.virginize_button.setEnabled(False)
36 | self.virginize_button.clicked.connect(self.reset_ecu)
37 | check_button.clicked.connect(self.check_virgin_status)
38 | self.ecu_connect()
39 |
40 | def ecu_connect(self):
41 | connection = self.megane_eps.connect_to_hardware()
42 | if not connection:
43 | options.main_window.logview.append(_("Cannot connect to ECU"))
44 | self.finished()
45 |
46 | def check_virgin_status(self):
47 | self.start_diag_session_c0()
48 |
49 | virigin_check_request = self.megane_eps.requests[u'DataRead.DID - Dongle state']
50 | request_response = virigin_check_request.send_request({}, "62 01 64 00 00 00 00 00 00 00 00 00 00 00 00")
51 |
52 | if request_response is not None:
53 | if u'DID - Dongle state' in request_response:
54 | donglestate = request_response[u'DID - Dongle state']
55 | if donglestate == u'Not operational':
56 | self.virginize_button.setEnabled(False)
57 | self.status_check.setText(_("EPS not operational"))
58 | return
59 |
60 | if donglestate == u'Operational blank':
61 | self.virginize_button.setEnabled(False)
62 | self.status_check.setText(_("EPS virgin"))
63 | return
64 |
65 | if donglestate == u'Operational learnt':
66 | self.virginize_button.setEnabled(True)
67 | self.status_check.setText(_("EPS coded"))
68 | return
69 |
70 | self.status_check.setText(_("UNEXPECTED RESPONSE"))
71 |
72 | def start_diag_session_fa(self):
73 | sds_request = self.megane_eps.requests[u"SDS - Start Diagnostic Session $FA"]
74 | sds_stream = " ".join(sds_request.build_data_stream({}))
75 | if options.simulation_mode:
76 | print("SdSFA stream", sds_stream)
77 | return
78 | options.elm.start_session_can(sds_stream)
79 |
80 | def start_diag_session_c0(self):
81 | sds_request = self.megane_eps.requests[u"SDS - Start Diagnostic Session $C0"]
82 | sds_stream = " ".join(sds_request.build_data_stream({}))
83 | if options.simulation_mode:
84 | print("SdSC0 stream", sds_stream)
85 | return
86 | options.elm.start_session_can(sds_stream)
87 |
88 | def reset_ecu(self):
89 | self.start_diag_session_fa()
90 |
91 | reset_request = self.megane_eps.requests[u"SRBLID - Dongle blanking"]
92 | request_response = reset_request.send_request()
93 |
94 | if request_response is not None:
95 | self.status_check.setText(_("CLEAR EXECUTED"))
96 | else:
97 | self.status_check.setText(_("CLEAR FAILED"))
98 |
99 |
100 | def plugin_entry():
101 | v = Virginizer()
102 | v.exec_()
103 |
--------------------------------------------------------------------------------
/megane3_uch_reset.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # (c) 2017
4 |
5 |
6 | import PyQt5.QtCore as core
7 | import PyQt5.QtWidgets as gui
8 |
9 | import ecu
10 | import options
11 |
12 | _ = options.translator('ddt4all')
13 |
14 | plugin_name = _("Megane/Scenic III UCH Reset")
15 | category = _("UCH Tools")
16 | need_hw = True
17 | ecufile = "BCM_X95_SW_2_V_1_2"
18 |
19 |
20 | class Virginizer(gui.QDialog):
21 | def __init__(self):
22 | super(Virginizer, self).__init__()
23 | self.megane_uch = ecu.Ecu_file(ecufile, True)
24 | layout = gui.QVBoxLayout()
25 | infos = gui.QLabel(
26 | _("MEGANE III UCH VIRGINIZER
THIS PLUGIN WILL ERASE YOUR UCH
GO AWAY IF YOU HAVE NO IDEA OF WHAT IT MEANS"))
27 | infos.setAlignment(core.Qt.AlignHCenter)
28 | check_button = gui.QPushButton(_("Check UCH Virgin"))
29 | self.status_check = gui.QLabel(_("Waiting"))
30 | self.status_check.setAlignment(core.Qt.AlignHCenter)
31 | self.virginize_button = gui.QPushButton(_("Virginize UCH"))
32 | layout.addWidget(infos)
33 | layout.addWidget(check_button)
34 | layout.addWidget(self.status_check)
35 | layout.addWidget(self.virginize_button)
36 | self.setLayout(layout)
37 | self.virginize_button.setEnabled(False)
38 | self.virginize_button.clicked.connect(self.reset_ecu)
39 | check_button.clicked.connect(self.check_virgin_status)
40 | self.ecu_connect()
41 |
42 | def ecu_connect(self):
43 | connection = self.megane_uch.connect_to_hardware()
44 | if not connection:
45 | options.main_window.logview.append(_("Cannot connect to ECU"))
46 | self.finished()
47 |
48 | def check_virgin_status(self):
49 | self.start_diag_session_aftersales()
50 |
51 | virigin_check_request = self.megane_uch.requests[
52 | u'Read_A_AC_General_Identifiers_Learning_Status_(bits)_BCM_Input/Output']
53 | virgin_check_request_values = virigin_check_request.send_request()
54 |
55 | if virgin_check_request_values is not None:
56 | virgin_value = virgin_check_request_values[u"VSC UCH vierge (NbBadgeAppris=0)"]
57 |
58 | if virgin_value == u'Actif':
59 | self.virginize_button.setEnabled(False)
60 | self.status_check.setText(_("UCH virgin"))
61 | return
62 |
63 | if virgin_value == u'inactif':
64 | self.virginize_button.setEnabled(True)
65 | self.status_check.setText(_("UCH coded"))
66 | return
67 |
68 | self.status_check.setText(_("UNEXPECTED RESPONSE"))
69 |
70 | def start_diag_session_aftersales(self):
71 | sds_request = self.megane_uch.requests[u"Start Diagnostic Session"]
72 | sds_stream = " ".join(sds_request.build_data_stream({}))
73 | if options.simulation_mode:
74 | print("SdSS stream", sds_stream)
75 | return
76 | options.elm.start_session_can(sds_stream)
77 |
78 | def reset_ecu(self):
79 | self.start_diag_session_aftersales()
80 |
81 | reset_request = self.megane_uch.requests[u"SR_RESERVED VSC 1"]
82 | request_response = reset_request.send_request()
83 |
84 | if request_response is not None:
85 | self.status_check.setText(_("CLEAR EXECUTED"))
86 | else:
87 | self.status_check.setText(_("CLEAR FAILED"))
88 |
89 |
90 | def plugin_entry():
91 | v = Virginizer()
92 | v.exec_()
93 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | crcmod==1.7
--------------------------------------------------------------------------------
/rsat4_reset.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # (c) 2017
4 |
5 |
6 | import PyQt5.QtCore as core
7 | import PyQt5.QtWidgets as gui
8 |
9 | import ecu
10 | import options
11 |
12 | _ = options.translator('ddt4all')
13 |
14 | plugin_name = _("RSAT4 AIRBAG Reset")
15 | category = _("Airbag Tools")
16 | need_hw = True
17 | ecufile = "RSAT4_ACU_eng_v15_20150511T131328"
18 |
19 |
20 | class Virginizer(gui.QDialog):
21 | def __init__(self):
22 | super(Virginizer, self).__init__()
23 | self.airbag_ecu = ecu.Ecu_file(ecufile, True)
24 | layout = gui.QVBoxLayout()
25 | infos = gui.QLabel(_("TWINGO III/ZOE/DOKKER/DUSTER ph2/TRAFIC III/CAPTUR/LODGY ph1/2
"
26 | "AIRBAG VIRGINIZER
THIS PLUGIN WILL UNLOCK AIRBAG CRASH DATA
"
27 | "GO AWAY IF YOU HAVE NO IDEA OF WHAT IT MEANS"))
28 | infos.setAlignment(core.Qt.AlignHCenter)
29 | check_button = gui.QPushButton(_("Check ACU Virgin"))
30 | self.status_check = gui.QLabel(_("Waiting"))
31 | self.status_check.setAlignment(core.Qt.AlignHCenter)
32 | self.virginize_button = gui.QPushButton(_("Virginize ACU"))
33 | layout.addWidget(infos)
34 | layout.addWidget(check_button)
35 | layout.addWidget(self.status_check)
36 | layout.addWidget(self.virginize_button)
37 | self.setLayout(layout)
38 | self.virginize_button.setEnabled(True)
39 | self.virginize_button.clicked.connect(self.reset_ecu)
40 | check_button.clicked.connect(self.check_virgin_status)
41 | self.ecu_connect()
42 |
43 | def ecu_connect(self):
44 | connection = self.airbag_ecu.connect_to_hardware()
45 | if not connection:
46 | options.main_window.logview.append(_("Cannot connect to ECU"))
47 | self.finished()
48 |
49 | def check_virgin_status(self):
50 | self.start_diag_session()
51 |
52 | crash_reset_request = self.airbag_ecu.requests[u'Reading of ECU state synthesis']
53 | crash_response = crash_reset_request.send_request({}, "62 02 04 00 00 00 00 00 00 00 00 00 00 00 00")
54 |
55 | if crash_response is not None:
56 | if u"crash detected" in crash_response:
57 | crash = crash_response[u"crash detected"]
58 |
59 | if crash == u'crash detected':
60 | self.status_check.setText(_("CRASH DETECTED"))
61 | return
62 | if crash == u'no crash detected':
63 | self.status_check.setText(_("NO CRASH DETECTED"))
64 | return
65 |
66 | self.status_check.setText(_("UNEXPECTED RESPONSE"))
67 |
68 | def start_diag_session(self):
69 | sds_request = self.airbag_ecu.requests[u"Start Diagnostic Session"]
70 |
71 | sds_stream = " ".join(sds_request.build_data_stream({u'Session Name': u'extendedDiagnosticSession'}))
72 | if options.simulation_mode:
73 | print("SdSEX stream", sds_stream)
74 | return
75 | options.elm.start_session_can(sds_stream)
76 |
77 | def reset_ecu(self):
78 | self.start_diag_session()
79 |
80 | reset_request = self.airbag_ecu.requests[u"Reset Crash"]
81 | request_response = reset_request.send_request({u'CLEDEV For reset crash': '13041976'})
82 |
83 | if request_response is not None:
84 | self.status_check.setText(_("CLEAR EXECUTED"))
85 | else:
86 | self.status_check.setText(_("CLEAR FAILED"))
87 |
88 |
89 | def plugin_entry():
90 | v = Virginizer()
91 | v.exec_()
92 |
--------------------------------------------------------------------------------
/vin_crc.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # Plugin to compute CRC from VIN
4 | # (c) 2017
5 |
6 | from binascii import hexlify
7 | from binascii import unhexlify
8 |
9 | import PyQt5.QtCore as core
10 | import PyQt5.QtWidgets as gui
11 | import crcmod.predefined
12 |
13 | import options
14 |
15 | _ = options.translator('ddt4all')
16 |
17 | plugin_name = _("CRC calculator")
18 | category = _("VIN")
19 | # We need an ELM to work
20 | need_hw = False
21 |
22 |
23 | def calc_crc(vin=None):
24 | VIN = hexlify(bytes(vin, 'utf-8'))
25 | VININT = unhexlify(VIN)
26 |
27 | crc16 = crcmod.predefined.mkCrcFun('x-25')
28 | crcle = hex(crc16(VININT))[2:].upper().zfill(4)
29 | print(crcle)
30 | # crcle = crc16.hexdigest()
31 | # Seems that computed CRC is returned in little endian way
32 | # Convert it to big endian
33 | return crcle[2:4] + crcle[0:2]
34 |
35 |
36 | class CrcWidget(gui.QDialog):
37 | def __init__(self):
38 | super(CrcWidget, self).__init__(None)
39 | layout = gui.QVBoxLayout()
40 | self.input = gui.QLineEdit()
41 | self.output = gui.QLineEdit()
42 | self.output.setStyleSheet("QLineEdit { color: rgb(255, 0, 0); }")
43 | info = gui.QLabel(_("CRC CALCULATOR"))
44 | info.setAlignment(core.Qt.AlignHCenter)
45 | self.output.setAlignment(core.Qt.AlignHCenter)
46 | layout.addWidget(info)
47 | layout.addWidget(self.input)
48 | layout.addWidget(self.output)
49 | self.input.textChanged.connect(self.recalc)
50 | self.setLayout(layout)
51 | self.output.setReadOnly(True)
52 |
53 | def recalc(self):
54 | vin = str(self.input.text()).upper()
55 | crc = calc_crc(vin)
56 | self.output.setText('%s' % crc)
57 |
58 |
59 | def plugin_entry():
60 | a = CrcWidget()
61 | a.exec_()
62 |
--------------------------------------------------------------------------------