• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1% EtherCat test campaign
2
3#
4# execute test:
5# $ test/run_tests -P "load_contrib('ethercat')" -t test/contrib/ethercat.uts
6#
7
8+ LEBitFields
9= regression test
10
11TEST_SAMPLE_ENUM = {
12    0x01: 'one',
13    0x02: 'two',
14    0x03: 'three',
15    0x04: 'four',
16    0x05: 'five',
17    0x06: 'six',
18    0x07: 'seven'
19}
20
21class BitFieldUserExampleLE(Packet):
22
23    fields_desc = [
24        LEBitEnumField('a', 0, 2, TEST_SAMPLE_ENUM),
25        LEBitField('b', 0, 18),
26        LEBitField('c', 0, 5),
27        LEBitField('d', 0, 23),
28    ]
29
30class BitFieldUserExample(Packet):
31
32    fields_desc = [
33        BitEnumField('a', 0, 2, TEST_SAMPLE_ENUM),
34        BitField('b', 0, 18),
35        BitField('c', 0, 5),
36        BitField('d', 0, 23),
37    ]
38
39test_data = [
40    {
41        'a':0x01,
42        'b':0x00,
43        'c':0x00,
44        'd':0x123456
45    },
46    {
47        'a': 0x00,
48        'b': 0b111111111111111111,
49        'c': 0x00,
50        'd': 0x112233
51    },
52    {
53        'a': 0x00,
54        'b': 0x00,
55        'c': 0x01,
56        'd': 0x00
57    },
58]
59
60for data in test_data:
61    bf_le = BitFieldUserExampleLE(**data)
62    bf = BitFieldUserExample(**data)
63    # rebuild big-endian and little-endian bitfields from its own binary expressions
64    bf_le = BitFieldUserExampleLE(bf_le.do_build())
65    bf = BitFieldUserExample(bf.do_build())
66    ''' disabled as only required for 'visual debugging'
67    from scapy.compat import raw
68    # dump content for debugging
69    bitstr = ''
70    hexstr = ''
71    for i in bytearray(raw(bf)):
72        bitstr += '{:08b} '.format(i)
73        hexstr += '{:02x} '.format(i)
74    print('BE - BITS: {} HEX: {}  ({})'.format(bitstr, hexstr, data))
75    bitstr = ''
76    hexstr = ''
77    for i in bytearray(raw(bf_le)):
78        bitstr += '{:08b} '.format(i)
79        hexstr += '{:02x} '.format(i)
80    print('LE - BITS: {} HEX: {}  ({})'.format(bitstr, hexstr, data))
81    '''
82    # compare values
83    for key in data:
84        assert getattr(bf,key) == data[key]
85        assert (getattr(bf_le, key) == data[key])
86
87= Avoid mix of LEBitFields and BitFields
88
89TEST_SAMPLE_ENUM = {
90    0x01: 'one',
91    0x02: 'two',
92    0x03: 'three',
93    0x04: 'four',
94    0x05: 'five',
95    0x06: 'six',
96    0x07: 'seven'
97}
98
99class MissingFieldSameLEFieldTypes(Packet):
100
101    fields_desc = [
102        LEBitEnumField('a', 0, 2, TEST_SAMPLE_ENUM),
103        LEBitField('b', 0, 18),
104    ]
105
106try:
107    frm = MissingFieldSameLEFieldTypes().build()
108    assert False
109except LEBitFieldSequenceException:
110    pass
111
112
113class MissingFieldDifferentLEFieldTypes(Packet):
114
115    fields_desc = [
116        LEBitEnumField('a', 0, 2, TEST_SAMPLE_ENUM),
117        LEBitField('b', 0, 18),
118    ]
119
120try:
121    frm = MissingFieldDifferentLEFieldTypes().build()
122    assert False
123except LEBitFieldSequenceException:
124    pass
125
126
127class MixedBitFieldTypesLEBE(Packet):
128
129    fields_desc = [
130        LEBitField('a', 0, 12),
131        BitField('b', 0, 4),
132    ]
133
134try:
135    frm = MixedBitFieldTypesLEBE().build()
136    assert False
137except LEBitFieldSequenceException:
138    pass
139
140
141class MixedBitFieldTypesBELE(Packet):
142
143    fields_desc = [
144        BitField('b', 0, 4),
145        LEBitField('a', 0, 12),
146    ]
147
148try:
149    frm = MixedBitFieldTypesBELE().build()
150    assert False
151except LEBitFieldSequenceException:
152    pass
153
154################################################
155+ EtherCat header layer handling
156= EtherCat and padding
157
158frm = Ether() / EtherCat()
159# even with padding the length must be zero
160# the Ether(do_build()) forces the calculation of all (post_build generated) fields
161frm = Ether(frm.do_build())
162assert frm[EtherCat].length == 0
163assert len(frm) == 60
164frm = Ether()/Dot1Q()/Dot1Q()/EtherCat()
165frm = Ether()/EtherCat()
166assert len(frm) == 60
167frm = Ether(frm.do_build())
168assert frm[EtherCat].length == 0
169
170= EtherCat and RawPayload
171
172frm=Ether()/EtherCat()/Raw(b'0123456789')
173assert len(frm) == 60
174frm = Ether(frm.do_build())
175assert frm[EtherCat].length == 10
176frm = Ether()/EtherCat()/Raw(b'012345678901234567890123456789012345678901234567890123456789')
177frm = Ether(frm.do_build())
178assert len(frm) == 76
179assert frm[EtherCat].length == 60
180
181= EtherCat - test invalid length detection
182
183nums_11_bits = [random.randint(0, 65535) & 0b11111111111 for dummy in range(0, 23)]
184nums_4_bits = [random.randint(0, 16) & 0b1111 for dummy in range(0, 23)]
185
186old_max_list_count = conf.max_list_count
187conf.max_list_count = 3000
188
189frm = Ether()/EtherCat()/EtherCatAPRD(adp=0x1234, ado=0x5678, irq=0xbad0, wkc=0xbeef, data=[1]*2035, c=1)
190frm = Ether(frm.do_build())
191assert frm[EtherCat].length == 2047
192assert len(frm[EtherCatAPRD].data) == 2035
193assert frm[EtherCatAPRD].c == 1
194
195data_oversized = False
196try:
197    frm = Ether()/EtherCat()/EtherCatAPRD(adp=0x1234, ado=0x5678, irq=0xbad0, wkc=0xbeef, data=[2]*2048, c=1)
198    frm = Ether(frm.do_build())
199except ValueError as err:
200    data_oversized = True
201    assert 'data size' in str(err)
202
203assert data_oversized == True
204dlpdu_oversized = False
205try:
206    frm = Ether()/EtherCat()/EtherCatAPRD(adp=0x1234, ado=0x5678, irq=0xbad0, wkc=0xbeef, data=[2]*2036, c=1)
207    frm = Ether(frm.do_build())
208except ValueError as err:
209    dlpdu_oversized = True
210    assert 'EtherCat message' in str(err)
211
212assert dlpdu_oversized == True
213
214frm = Ether()/EtherCat(_reserved=1)/EtherCatAPRD(adp=0x1234, ado=0x5678, irq=0xbad0, wkc=0xbeef, data=[3], c=0)
215frm = Ether(frm.do_build())
216assert frm[EtherCatAPRD].c == 0
217
218
219assert frm[EtherCat]._reserved == 0
220
221conf.max_list_count = old_max_list_count
222
223= EtherCat and Type12 DLPDU layers
224
225for type_id in EtherCat.ETHERCAT_TYPE12_DLPDU_TYPES:
226    data = [random.randint(0, 255) for dummy in range(random.randint(1, 10))]
227    frm = Ether() / EtherCat() / EtherCat.ETHERCAT_TYPE12_DLPDU_TYPES[type_id](data= data)
228    frm = Ether(frm.do_build())
229    # expect to have one layer of current Type12 DLPDU type
230    dlpdu_lyr = frm[EtherCat.ETHERCAT_TYPE12_DLPDU_TYPES[type_id]]
231    assert dlpdu_lyr.data == data
232
233= EtherCat and Type12 DLPDU layer using structure used for physical and broadcast addressing
234
235# the code is the same for all layer sharing this structure - no need to test em all
236test_data = [121,99,110,104,114,109,58,41]
237frm = Ether()/EtherCat()/EtherCatAPRD(adp=0x1234, ado=0x5678, irq=0xbad0, wkc=0xbeef, data=test_data)
238frm = Ether(frm.do_build())
239aprd_lyr = frm[EtherCatAPRD]
240assert aprd_lyr.adp == 0x1234
241assert aprd_lyr.ado == 0x5678
242assert aprd_lyr.irq == 0xbad0
243assert aprd_lyr.wkc == 0xbeef
244assert aprd_lyr.data == test_data
245
246= EtherCat and Type12 DLPDU layer using structure used for logical addressing
247
248test_data = [116,104,101,116,97,111,105,115,103,114,101,97,116]
249frm = Ether() / EtherCat() / EtherCatLRD(adr=0x11223344, irq=0xbad0, wkc=0xbeef, data=test_data)
250frm = Ether(frm.do_build())
251aprd_lyr = frm[EtherCatLRD]
252assert (aprd_lyr.adr == 0x11223344)
253assert (aprd_lyr.irq == 0xbad0)
254assert (aprd_lyr.wkc == 0xbeef)
255assert (aprd_lyr.data == test_data)
256
257= EtherCat and randomly stacked Type12 DLPDU layers
258
259for outer_dummy in range(10):
260    frm = Ether()/EtherCat()
261    layer_ids = []
262    for inner_dummy in range(random.randint(1, 20)):
263        layer_id = random.choice(list(EtherCat.ETHERCAT_TYPE12_DLPDU_TYPES))
264        layer_ids.append(layer_id)
265        frm = frm / EtherCat.ETHERCAT_TYPE12_DLPDU_TYPES[layer_id]()
266    # build frame and convert back
267    frm = Ether(frm.do_build())
268    idx = 0
269    for layer_id in layer_ids:
270        assert type(EtherCat.ETHERCAT_TYPE12_DLPDU_TYPES[layer_id]()) == type(frm[2 + idx])
271        idx += 1
272