• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# gmlan unit tests
2#
3# Type the following command to launch start the tests:
4# $ sudo bash test/run_tests -t test/gmlan.uts -F
5
6% gmlan unit tests
7
8+ Configuration of scapy
9= Load gmlan layer
10~ conf
11
12load_contrib("automotive.ecu", globals_dict=globals())
13load_contrib("automotive.gm.gmlan", globals_dict=globals())
14
15from scapy.contrib.automotive.gm.gmlan_ecu_states import *
16from scapy.contrib.automotive.gm.gmlan_logging import *
17
18+ Basic Packet Tests()
19= Set GMLAN ECU AddressingScheme
20
21conf.contribs['GMLAN']['GMLAN_ECU_AddressingScheme'] = 2
22assert conf.contribs['GMLAN']['GMLAN_ECU_AddressingScheme'] == 2
23
24= Craft Packet
25x = GMLAN(b'\x52\x02\x01\x16\x71\x00\x00\x0c\xaa\xbb')
26x.load == b'\x00\x0c\xaa\xbb'
27x.service == 0x52
28
29= Craft VIN Packet
30x = GMLAN(b'\x5a\x90'+ raw(b"WOOOJBF35W1042000"))
31x.load == b'WOOOJBF35W1042000'
32x.dataIdentifier == 0x90
33
34= Test Packet with ECU AddressingScheme2
35x = GMLAN()/GMLAN_RMBA(b'\x11\x22\x44\x22')
36x.memoryAddress == 0x1122
37x.memorySize == 0x4422
38
39= Test Packet GMLAN_RMBAPR with ECU AddressingScheme2
40y = GMLAN()/GMLAN_RMBAPR(b'\x11\x22\x44\x22')
41y.memoryAddress == 0x1122
42y.dataRecord == b'\x44\x22'
43y.answers(x) == True
44
45= Craft Packet with ECU AddressingScheme2
46x = GMLAN() / GMLAN_RMBA(b'\x11\x22\x44\x22')
47y = GMLAN()/GMLAN_RMBA(memoryAddress=0x1122, memorySize=0x4422)
48bytes(x) == bytes(y)
49
50= Test Packet with ECU AddressingScheme3
51conf.contribs['GMLAN']['GMLAN_ECU_AddressingScheme'] = 3
52x = GMLAN()/GMLAN_RMBA(b'\x11\x22\x44\x22\x11')
53x.memoryAddress == 0x112244
54x.memorySize == 0x2211
55
56= Test Packet GMLAN_RMBAPR with ECU AddressingScheme3
57y = GMLAN()/GMLAN_RMBAPR(b'\x11\x22\x44\x22\x11')
58y.memoryAddress == 0x112244
59y.dataRecord == b'\x22\x11'
60y.answers(x) == True
61
62= Craft Packet with ECU AddressingScheme3
63x = GMLAN() / GMLAN_RMBA(b'\x11\x22\x44\x22\x11')
64y = GMLAN()/GMLAN_RMBA(memoryAddress=0x112244, memorySize=0x2211)
65bytes(x) == bytes(y)
66
67= Test Packet with ECU AddressingScheme4
68conf.contribs['GMLAN']['GMLAN_ECU_AddressingScheme'] = 4
69x = GMLAN()/GMLAN_RMBA(b'\x11\x22\x44\x22\x11\x00')
70x.memoryAddress == 0x11224422
71x.memorySize == 0x1100
72
73= Test Packet GMLAN_RMBAPR with ECU AddressingScheme4
74y = GMLAN()/GMLAN_RMBAPR(b'\x11\x22\x44\x22\x11\x00')
75y.memoryAddress == 0x11224422
76y.dataRecord == b'\x11\x00'
77y.answers(x) == True
78
79= Craft Packet with ECU AddressingScheme4
80x = GMLAN() / GMLAN_RMBA(b'\x11\x22\x44\x22\x11\x00')
81y = GMLAN()/GMLAN_RMBA(memoryAddress=0x11224422, memorySize=0x1100)
82bytes(x) == bytes(y)
83
84= Craft Packet for RequestDownload2
85conf.contribs['GMLAN']['GMLAN_ECU_AddressingScheme'] = 2
86x = GMLAN(b'\x34\x12\x08\x15')
87x.service == 0x34
88x.dataFormatIdentifier == 0x12
89x.memorySize == 0x815
90
91y = GMLAN()/GMLAN_RD(dataFormatIdentifier=0x12, memorySize=0x815)
92bytes(y) == bytes(x)
93
94= Craft Packet for RequestDownload3
95conf.contribs['GMLAN']['GMLAN_ECU_AddressingScheme'] = 3
96x = GMLAN(b'\x34\x12\x08\x15\x00')
97x.service == 0x34
98x.dataFormatIdentifier == 0x12
99x.memorySize == 0x81500
100
101y = GMLAN()/GMLAN_RD(dataFormatIdentifier=0x12, memorySize=0x81500)
102bytes(y) == bytes(x)
103
104= Craft Packet for RequestDownload4
105conf.contribs['GMLAN']['GMLAN_ECU_AddressingScheme'] = 4
106x = GMLAN(b'\x34\x12\x08\x15\x00\x11')
107x.service == 0x34
108x.dataFormatIdentifier == 0x12
109x.memorySize == 0x8150011
110
111= Craft Packet for RFRD1
112a = GMLAN(b'\x12\x01')
113a.service == 0x12
114a.subfunction == 1
115
116= Craft Packet for RFRD2
117b = GMLAN(b'\x12\x02\x01\x02\x03\x04')
118b.service == 0x12
119b.subfunction == 2
120b.dtc.failureRecordNumber == 1
121b.dtc.DTCHighByte == 2
122b.dtc.DTCLowByte == 3
123b.dtc.DTCFailureType == 4
124
125= Craft Packet for RFRDPR_RFRI
126x = GMLAN(b'\x52\x01\x00\x01\x02\x03\x04')
127x.service == 0x52
128x.subfunction == 1
129x.failureRecordDataStructureIdentifier == 0
130x.dtcs[0].failureRecordNumber == 1
131x.dtcs[0].DTCHighByte == 2
132x.dtcs[0].DTCLowByte == 3
133x.dtcs[0].DTCFailureType == 4
134x.answers(a) == True
135
136= Craft Packet for RFRDPR_RFRI
137x = GMLAN(b'\x52\x01\x00\x01\x02\x03\x04\x01\x02\x03\x04\x01\x02\x03\x04\x01\x02\x03\x04')
138x.service == 0x52
139x.subfunction == 1
140x.failureRecordDataStructureIdentifier == 0
141x.dtcs[0].failureRecordNumber == 1
142x.dtcs[0].DTCHighByte == 2
143x.dtcs[0].DTCLowByte == 3
144x.dtcs[0].DTCFailureType == 4
145x.dtcs[1].failureRecordNumber == 1
146x.dtcs[1].DTCHighByte == 2
147x.dtcs[1].DTCLowByte == 3
148x.dtcs[1].DTCFailureType == 4
149x.dtcs[2].failureRecordNumber == 1
150x.dtcs[2].DTCHighByte == 2
151x.dtcs[2].DTCLowByte == 3
152x.dtcs[2].DTCFailureType == 4
153x.dtcs[3].failureRecordNumber == 1
154x.dtcs[3].DTCHighByte == 2
155x.dtcs[3].DTCLowByte == 3
156x.dtcs[3].DTCFailureType == 4
157x.answers(a) == True
158
159= Craft Packet for RFRDPR_RFRP
160x = GMLAN(b'\x52\x02\x01\x02\x03\x04deadbeef')
161x.service == 0x52
162x.subfunction == 2
163x.dtc.failureRecordNumber == 1
164x.dtc.DTCHighByte == 2
165x.dtc.DTCLowByte == 3
166x.dtc.DTCFailureType == 4
167x.show()
168x.load == b'deadbeef'
169x.answers(b) == True
170
171
172= Craft Packet for RDBI
173x = GMLAN(b'\x1A\x11')
174x.service == 0x1A
175x.dataIdentifier == 0x11
176
177= Craft Packet for RDBIPR
178y = GMLAN(b'\x5A\x11deadbeef')
179y.service == 0x5A
180y.dataIdentifier == 0x11
181y.load == b'deadbeef'
182y.answers(x) == True
183
184
185= Craft Packet for RDBPI
186x = GMLAN(b'\x22\x11\x11\x22\x22\x33\x33\x44\x44\x55\x55\x66\x66\x77\x77\x88\x88\x99\x99')
187x.service == 0x22
188x.identifiers[0] == 0x1111
189x.identifiers[1] == 0x2222
190x.identifiers[2] == 0x3333
191x.identifiers[3] == 0x4444
192x.identifiers[4] == 0x5555
193x.identifiers[5] == 0x6666
194x.identifiers[6] == 0x7777
195x.identifiers[7] == 0x8888
196x.identifiers[8] == 0x9999
197
198= Craft Packet for RDBPIPR
199y = GMLAN(b'\x62\x11\x11deadbeef')
200y.service == 0x62
201y.parameterIdentifier == 0x1111
202y.load == b'deadbeef'
203y.answers(x) == True
204
205= Craft Packet for GMLAN_RDBPKTI1
206x = GMLAN(b'\xAA\x01deadbeef')
207x.service == 0xAA
208x.subfunction == 0x01
209x.request_DPIDs == [0x64, 0x65, 0x61, 0x64, 0x62, 0x65, 0x65, 0x66]
210
211= Craft Packet for GMLAN_RDBPKTI3
212x = GMLAN(b'\xAA\x02deadbeef')
213x.service == 0xAA
214x.subfunction == 0x02
215x.request_DPIDs == [0x64, 0x65, 0x61, 0x64, 0x62, 0x65, 0x65, 0x66]
216
217= Craft Packet for GMLAN_RDBPKTI4
218x = GMLAN(b'\xAA\x03deadbeef')
219x.service == 0xAA
220x.subfunction == 0x03
221x.request_DPIDs == [0x64, 0x65, 0x61, 0x64, 0x62, 0x65, 0x65, 0x66]
222
223= Craft Packet for GMLAN_RDBPKTI2
224x = GMLAN(b'\xAA\x00')
225x.service == 0xAA
226x.subfunction == 0
227
228= Build GMLAN_RDBPKTI1
229x = GMLAN()/GMLAN_RDBPKTI(subfunction=1, request_DPIDs=[0x64, 0x65])
230assert b"\xaa\x01de" == bytes(x)
231
232= Craft Packet for GMLAN_SA1
233a = GMLAN(b'\x27\x01')
234a.service == 0x27
235a.subfunction == 1
236
237= Craft Packet for GMLAN_SA2
238b = GMLAN(b'\x27\x02\xde\xad')
239b.service == 0x27
240b.subfunction == 2
241b.securityKey == 0xdead
242
243= Craft Packet for GMLAN_SAPR1
244x = GMLAN(b'\x67\x02')
245x.service == 0x67
246x.subfunction == 2
247x.answers(b)
248
249ecu = Ecu()
250ecu.update(b)
251ecu.update(x)
252assert ecu.state.security_level == 2
253
254
255= Craft Packet for GMLAN_SAPR2
256x = GMLAN(b'\x67\x01\xde\xad')
257x.service == 0x67
258x.subfunction == 1
259x.securitySeed == 0xdead
260x.answers(a)
261
262= Craft Packet for GMLAN_DDM
263x = GMLAN(b'\x2c\x02dead')
264x.service == 0x2c
265x.DPIDIdentifier == 2
266x.PIDData == b'dead'
267
268= Craft Packet for GMLAN_DDMPR
269y = GMLAN(b'\x6c\x02dead')
270y.service == 0x6c
271y.DPIDIdentifier == 2
272y.answers(x)
273
274= Craft Packet for GMLAN_DPBA1
275conf.contribs['GMLAN']['GMLAN_ECU_AddressingScheme'] = 2
276x = GMLAN(b'\x2D\x02\x02\x11\x11\x33')
277x.service == 0x2d
278x.parameterIdentifier == 0x202
279x.memoryAddress == 0x1111
280x.memorySize == 0x33
281
282= Craft Packet for GMLAN_DPBA2
283conf.contribs['GMLAN']['GMLAN_ECU_AddressingScheme'] = 3
284x = GMLAN(b'\x2D\x02\x02\x11\x11\x11\x33')
285x.service == 0x2d
286x.parameterIdentifier == 0x202
287x.memoryAddress == 0x111111
288x.memorySize == 0x33
289
290= Craft Packet for GMLAN_DPBA3
291conf.contribs['GMLAN']['GMLAN_ECU_AddressingScheme'] = 4
292x = GMLAN(b'\x2D\x02\x02\x11\x11\x11\x11\x33')
293x.service == 0x2d
294x.parameterIdentifier == 0x202
295x.memoryAddress == 0x11111111
296x.memorySize == 0x33
297
298= Craft Packet for GMLAN_DPBAPR
299y = GMLAN(b'\x6D\x02\x02')
300y.service == 0x6d
301y.parameterIdentifier == 0x202
302y.answers(x)
303
304= Craft Packet for GMLAN_RD1
305conf.contribs['GMLAN']['GMLAN_ECU_AddressingScheme'] = 2
306x = GMLAN(b'\x34\x02\x11\x11')
307x.service == 0x34
308x.dataFormatIdentifier == 0x2
309x.memorySize == 0x1111
310
311= Craft Packet for GMLAN_RD2
312conf.contribs['GMLAN']['GMLAN_ECU_AddressingScheme'] = 3
313x = GMLAN(b'\x34\x02\x11\x11\x11')
314x.service == 0x34
315x.dataFormatIdentifier == 0x2
316x.memorySize == 0x111111
317
318= Craft Packet for GMLAN_RD3
319conf.contribs['GMLAN']['GMLAN_ECU_AddressingScheme'] = 4
320x = GMLAN(b'\x34\x02\x11\x11\x11\x11')
321x.service == 0x34
322x.dataFormatIdentifier == 0x2
323x.memorySize == 0x11111111
324
325= Craft Packet for GMLAN_TD1
326conf.contribs['GMLAN']['GMLAN_ECU_AddressingScheme'] = 2
327x = GMLAN(b'\x36\x02\x11\x11dead')
328x.service == 0x36
329x.subfunction == 0x2
330x.startingAddress == 0x1111
331x.dataRecord == b'dead'
332
333= Craft Packet for GMLAN_TD2
334conf.contribs['GMLAN']['GMLAN_ECU_AddressingScheme'] = 3
335x = GMLAN(b'\x36\x02\x11\x11\x11dead')
336x.service == 0x36
337x.subfunction == 0x2
338x.startingAddress == 0x111111
339x.dataRecord == b'dead'
340
341= Craft Packet for GMLAN_TD3
342conf.contribs['GMLAN']['GMLAN_ECU_AddressingScheme'] = 4
343x = GMLAN(b'\x36\x02\x11\x11\x11\x11dead')
344x.service == 0x36
345x.subfunction == 0x2
346x.startingAddress == 0x11111111
347x.dataRecord == b'dead'
348
349= Craft Packet for WDBI
350x = GMLAN(b'\x3b\x11deadbeef')
351x.service == 0x3b
352x.dataIdentifier == 0x11
353x.dataRecord == b'deadbeef'
354
355= Craft Packet for WDBIPR
356y = GMLAN(b'\x7b\x11')
357y.service == 0x7b
358y.dataIdentifier == 0x11
359y.answers(x)
360
361= Craft Packet for RPSPR
362x = GMLAN(b'\xe2\x11')
363x.service == 0xe2
364x.programmedState == 0x11
365
366= Craft Packet for PM
367x = GMLAN(b'\xA5\x11')
368x.service == 0xA5
369x.subfunction == 0x11
370
371= Craft Packet for RDI
372x = GMLAN(b'\xA9\x11')
373x.service == 0xA9
374x.subfunction == 0x11
375
376= Craft Packet for RDI_BN
377x = GMLAN(b'\xA9\x80\x11\x22\x33')
378x.service == 0xA9
379x.subfunction == 0x80
380x.DTCHighByte == 0x11
381x.DTCLowByte == 0x22
382x.DTCFailureType == 0x33
383
384= Craft Packet for RDI_BM1
385x = GMLAN(b'\xA9\x81\x11')
386x.service == 0xA9
387x.subfunction == 0x81
388x.DTCStatusMask == 0x11
389
390= Craft Packet for RDI_BM2
391x = GMLAN(b'\xA9\x82\x11')
392x.service == 0xA9
393x.subfunction == 0x82
394x.DTCStatusMask == 0x11
395
396= Craft Packet for NR
397x = GMLAN(b'\x7f\x11\x00\x11\x22')
398x.service == 0x7f
399x.requestServiceId == 0x11
400x.returnCode == 0
401x.deviceControlLimitExceeded == 0x1122
402
403= Check not answers
404y = GMLAN(b'\x11deadbeef')
405x = GMLAN(b'\x7f\x10\x00\x11\x22')
406assert not x.answers(y)
407
408= Check answers 1
409y = GMLAN(b'\x10deadbeef')
410x = GMLAN(b'\x7f\x10\x00\x11\x22')
411assert x.answers(y)
412
413= Set treat-response-pending-as-answer
414conf.contribs['GMLAN']['treat-response-pending-as-answer'] = False
415assert conf.contribs['GMLAN']['treat-response-pending-as-answer'] == False
416
417= Check response-pending is not considered as answer
418y = GMLAN(b'\x10deadbeef')
419x = GMLAN(b'\x7f\x10\x78\x11\x22')
420assert not x.answers(y)
421
422= Check response-pending is considered as answer
423conf.contribs['GMLAN']['treat-response-pending-as-answer'] = True
424assert conf.contribs['GMLAN']['treat-response-pending-as-answer'] == True
425y = GMLAN(b'\x10deadbeef')
426x = GMLAN(b'\x7f\x10\x78\x11\x22')
427assert x.answers(y)
428
429= Check hashret 1
430print(y.hashret())
431print(x.hashret())
432
433y.hashret() == x.hashret()
434
435= Check answers 2
436y = GMLAN()/GMLAN_SA(subfunction=1)
437x = GMLAN()/GMLAN_SAPR(subfunction=1)
438assert x.answers(y)
439
440= Check hashret 2
441y.hashret() == x.hashret()
442
443= Check modifies ecu state
444ecu = Ecu()
445ecu.update(GMLAN(service="InitiateDiagnosticOperation"))
446ecu.update(GMLAN(service="InitiateDiagnosticOperationPositiveResponse"))
447assert ecu.state.session == 3
448ecu.update(GMLAN(service="ReturnToNormalOperation"))
449ecu.update(GMLAN(service="ReturnToNormalOperationPositiveResponse"))
450assert ecu.state.session == 1
451ecu.update(GMLAN(service="ProgrammingMode"))
452ecu.update(GMLAN(service="ProgrammingModePositiveResponse"))
453assert ecu.state.session == 2
454ecu.update(GMLAN(service="DisableNormalCommunication"))
455ecu.update(GMLAN(service="DisableNormalCommunicationPositiveResponse"))
456assert ecu.state.communication_control == 1
457ecu.update(GMLAN(service="ReturnToNormalOperation"))
458ecu.update(GMLAN(service="ReturnToNormalOperationPositiveResponse"))
459assert ecu.state.session == 1
460
461= Craft GMLAN_DC
462
463req = GMLAN()/GMLAN_DC(CPIDNumber=0x11, CPIDControlBytes=b"\xbe\xefabc")
464assert bytes(req) == b"\xAE\x11\xbe\xefabc"
465
466req2 = GMLAN()/GMLAN_DC(CPIDNumber=0x12)
467assert bytes(req2) == b"\xAE\x12\x00\x00\x00\x00\x00"
468
469resp = GMLAN()/GMLAN_DCPR(CPIDNumber=0x11)
470assert bytes(resp) == b"\xEE\x11"
471
472
473assert resp.answers(req)
474assert not resp.answers(req2)
475
476= Dissect test GMLAN_DC
477
478req = GMLAN(b"\xAE\x14caffe")
479assert req.service == 0xAE
480assert req.CPIDNumber == 20
481assert req.CPIDControlBytes == b"caffe"
482
483resp = GMLAN(b"\xEE\x14")
484assert resp.service == 0xEE
485assert resp.CPIDNumber == 20
486assert resp.answers(req)
487assert resp.hashret() == req.hashret()
488
489= Logging tests
490
491
492def get_log(pkt):
493    for layer in pkt.layers():
494        if not hasattr(layer, "get_log"):
495            continue
496        try:
497            return layer.get_log(pkt)
498        except TypeError:
499            return layer.get_log.im_func(pkt)
500
501pkt = GMLAN()/GMLAN_RFRD(subfunction=1)
502log = get_log(pkt)
503assert len(log) == 2
504assert log[1] == "readFailureRecordIdentifiers"
505assert log[0] == "ReadFailureRecordData"
506
507pkt = GMLAN()/GMLAN_RFRDPR(subfunction=1)
508log = get_log(pkt)
509assert len(log) == 2
510assert log[1] == "readFailureRecordIdentifiers"
511assert log[0] == "ReadFailureRecordDataPositiveResponse"
512
513pkt = GMLAN()/GMLAN_RDBPI(identifiers=[5])
514log = get_log(pkt)
515print(log)
516assert len(log) == 2
517assert log[1] == '[OBD_EngineCoolantTemperature]'
518assert log[0] == "ReadDataByParameterIdentifier"
519
520pkt = GMLAN()/GMLAN_RDBPIPR(parameterIdentifier=5)
521log = get_log(pkt)
522print(log)
523assert len(log) == 2
524assert log[1] == 'OBD_EngineCoolantTemperature'
525assert log[0] == "ReadDataByParameterIdentifierPositiveResponse"
526
527
528pkt = GMLAN()/GMLAN_RDBPKTI(subfunction=0)
529log = get_log(pkt)
530print(log)
531assert len(log) == 2
532assert log[1] == 'stopSending'
533assert log[0] == "ReadDataByPacketIdentifier"
534
535pkt = GMLAN()/GMLAN_RMBA(memoryAddress=0)
536log = get_log(pkt)
537print(log)
538assert len(log) == 2
539assert log[1] == '0x0'
540assert log[0] == "ReadMemoryByAddress"
541
542pkt = GMLAN()/GMLAN_RMBAPR(memoryAddress=0, dataRecord=b"deadbeef")
543log = get_log(pkt)
544print(log)
545assert len(log) == 2
546assert log[1][0] == '0x0'
547assert log[1][1] == b'deadbeef'
548assert log[0] == "ReadMemoryByAddressPositiveResponse"
549
550pkt = GMLAN()/GMLAN_DDM(DPIDIdentifier=0, PIDData=b"deadbeef")
551log = get_log(pkt)
552print(log)
553assert len(log) == 2
554assert log[1][0] == '0x0'
555assert log[1][1] == b'deadbeef'
556assert log[0] == "DynamicallyDefineMessage"
557
558pkt = GMLAN()/GMLAN_DDMPR(DPIDIdentifier=0)
559log = get_log(pkt)
560print(log)
561assert len(log) == 2
562assert log[1] == '0x0'
563assert log[0] == "DynamicallyDefineMessagePositiveResponse"
564
565pkt = GMLAN()/GMLAN_DPBA(parameterIdentifier=0, memoryAddress=1, memorySize=3)
566log = get_log(pkt)
567print(log)
568assert len(log) == 2
569assert log[1][0] == 0
570assert log[1][1] == 1
571assert log[1][2] == 3
572assert log[0] == "DefinePIDByAddress"
573
574pkt = GMLAN()/GMLAN_DPBAPR(parameterIdentifier=0)
575log = get_log(pkt)
576print(log)
577assert len(log) == 2
578assert log[1] == 0
579assert log[0] == "DefinePIDByAddressPositiveResponse"
580
581pkt = GMLAN()/GMLAN_WDBI(dataIdentifier=0, dataRecord=b"deadbeef")
582log = get_log(pkt)
583print(log)
584assert len(log) == 2
585assert log[1][0] == "0x0"
586assert log[1][1] == b"deadbeef"
587assert log[0] == "WriteDataByIdentifier"
588
589pkt = GMLAN()/GMLAN_WDBIPR(dataIdentifier=0)
590log = get_log(pkt)
591print(log)
592assert len(log) == 2
593assert log[1] == "0x0"
594assert log[0] == "WriteDataByIdentifierPositiveResponse"
595
596pkt = GMLAN()/GMLAN_RDI(subfunction=0x80)
597log = get_log(pkt)
598print(log)
599assert len(log) == 2
600assert log[1] == "readStatusOfDTCByDTCNumber"
601assert log[0] == "ReadDiagnosticInformation"
602
603pkt = GMLAN()/GMLAN_DC(CPIDNumber=0x80)
604log = get_log(pkt)
605print(log)
606assert len(log) == 2
607assert log[1] == "0x80"
608assert log[0] == "DeviceControl"
609
610pkt = GMLAN()/GMLAN_DCPR(CPIDNumber=0x80)
611log = get_log(pkt)
612print(log)
613assert len(log) == 2
614assert log[1] == "0x80"
615assert log[0] == "DeviceControlPositiveResponse"