Passed
Pull Request — master (#425)
by Carlos Eduardo
02:30
created

MeterStats.pack()   A

Complexity

Conditions 1

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1.2963

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 8
ccs 1
cts 3
cp 0.3333
rs 9.4285
cc 1
crap 1.2963
1
"""Controller replying state from datapath."""
2
3
# System imports
4 1
from enum import Enum
5
6
# Local source tree imports
7 1
from pyof.foundation.base import GenericBitMask, GenericMessage, GenericStruct
8 1
from pyof.foundation.basic_types import (
9
    BinaryData, Char, FixedTypeList, Pad, UBInt8, UBInt16, UBInt32, UBInt64)
10 1
from pyof.foundation.constants import DESC_STR_LEN, SERIAL_NUM_LEN
11 1
from pyof.v0x04.common.flow_match import Match
12 1
from pyof.v0x04.common.header import Header, Type
13 1
from pyof.v0x04.common.port import Port
14 1
from pyof.v0x04.controller2switch.common import (
15
    Bucket, BucketCounter, ExperimenterMultipartHeader, MultipartTypes,
16
    TableFeatures)
17 1
from pyof.v0x04.controller2switch.meter_mod import (
18
    ListOfMeterBandHeader, MeterBandType, MeterFlags)
19
20
# Third-party imports
21
22
23 1
__all__ = ('MultipartReply', 'MultipartReplyFlags', 'AggregateStatsReply',
24
           'Desc', 'FlowStats', 'PortStats', 'QueueStats', 'GroupDescStats',
25
           'GroupFeatures', 'GroupStats', 'MeterConfig', 'MeterFeatures',
26
           'BandStats', 'ListOfBandStats', 'MeterStats', 'GroupCapabilities',
27
           'TableStats')
28
29
# Enum
30
31
32 1
class MultipartReplyFlags(Enum):
33
    """Flags for MultipartReply."""
34
35
    #: More replies to follow.
36 1
    OFPMPF_REPLY_MORE = 1 << 0
37
38
39 1
class GroupCapabilities(GenericBitMask):
40
    """Group configuration flags."""
41
42
    #: Support weight for select groups.
43 1
    OFPGFC_SELECT_WEIGHT = 1 << 0
44
    #: Support liveness for select groups.
45 1
    OFPGFC_SELECT_LIVENESS = 1 << 1
46
    #: Support chaining groups.
47 1
    OFPGFC_CHAINING = 1 << 2
48
    #: Chack chaining for loops and delete.
49 1
    OFPGFC_CHAINING_CHECKS = 1 << 3
50
51
# Classes
52
53
54 1
class MultipartReply(GenericMessage):
55
    """Reply datapath state.
56
57
    While the system is running, the controller may reply state from the
58
    datapath using the OFPT_MULTIPART_REPLY message.
59
    """
60
61
    #: Openflow :class:`~pyof.v0x04.common.header.Header`
62 1
    header = Header(message_type=Type.OFPT_MULTIPART_REPLY)
63
    #: One of the OFPMP_* constants.
64 1
    multipart_type = UBInt16(enum_ref=MultipartTypes)
65
    #: OFPMPF_REPLY_* flags.
66 1
    flags = UBInt16(enum_ref=MultipartReplyFlags)
67
    #: Padding
68 1
    pad = Pad(4)
69
    #: Body of the reply
70 1
    body = BinaryData()
71
72 1
    def __init__(self, xid=None, multipart_type=None, flags=None, body=b''):
73
        """The constructor just assigns parameters to object attributes.
74
75
        Args:
76
            xid (int): xid to the header.
77
            multipart_type (int): One of the OFPMP_* constants.
78
            flags (int): OFPMPF_REPLY_* flags.
79
            body (bytes): Body of the reply.
80
        """
81 1
        super().__init__(xid)
82 1
        self.multipart_type = multipart_type
83 1
        self.flags = flags
84 1
        self.body = body
85
86 1 View Code Duplication
    def pack(self, value=None):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
87
        """Pack a StatsReply using the object's attributes.
88
89
        This method will pack the attribute body and multipart_type before pack
90
        the StatsReply object, then will return this struct as a binary data.
91
92
        Returns:
93
            stats_reply_packed (bytes): Binary data with StatsReply packed.
94
        """
95 1
        buff = self.body
96 1
        if not value:
97 1
            value = self.body
98
99 1
        if value:
100 1
            if isinstance(value, (list, FixedTypeList)):
101
                obj = self._get_body_instance()
102
                obj.extend(value)
103 1
            elif hasattr(value, 'pack'):
104 1
                obj = value
105
106 1
            self.body = obj.pack()
107
108 1
        multiparty_packed = super().pack()
109 1
        self.body = buff
110
111 1
        return multiparty_packed
112
113 1
    def unpack(self, buff, offset=0):
114
        """Unpack a binary message into this object's attributes.
115
116
        Unpack the binary value *buff* and update this object attributes based
117
        on the results. It is an inplace method and it receives the binary data
118
        of the message **without the header**.
119
120
        This class' unpack method is like the :meth:`.GenericMessage.unpack`
121
        one, except for the ``body`` attribute which has its type determined
122
        by the ``multipart_type`` attribute.
123
124
        Args:
125
            buff (bytes): Binary data package to be unpacked, without the
126
                header.
127
        """
128 1
        super().unpack(buff[offset:])
129 1
        self._unpack_body()
130
131 1
    def _unpack_body(self):
132
        """Unpack `body` replace it by the result."""
133 1
        obj = self._get_body_instance()
134 1
        obj.unpack(self.body.value)
135 1
        self.body = obj
136
137 1
    def _get_body_instance(self):
138
        """Method used to return the body instance."""
139 1
        exp_header = ExperimenterMultipartHeader
140 1
        simple_body = {MultipartTypes.OFPMP_DESC: Desc,
141
                       MultipartTypes.OFPMP_GROUP_FEATURES: GroupFeatures,
142
                       MultipartTypes.OFPMP_METER_FEATURES: MeterFeatures,
143
                       MultipartTypes.OFPMP_EXPERIMENTER: exp_header}
144
145 1
        array_of_bodies = {MultipartTypes.OFPMP_FLOW: FlowStats,
146
                           MultipartTypes.OFPMP_AGGREGATE: AggregateStatsReply,
147
                           MultipartTypes.OFPMP_TABLE: TableStats,
148
                           MultipartTypes.OFPMP_PORT_STATS: PortStats,
149
                           MultipartTypes.OFPMP_QUEUE: QueueStats,
150
                           MultipartTypes.OFPMP_GROUP: GroupStats,
151
                           MultipartTypes.OFPMP_GROUP_DESC: GroupDescStats,
152
                           MultipartTypes.OFPMP_METER: MeterStats,
153
                           MultipartTypes.OFPMP_METER_CONFIG: MeterConfig,
154
                           MultipartTypes.OFPMP_TABLE_FEATURES: TableFeatures,
155
                           MultipartTypes.OFPMP_PORT_DESC: Port}
156
157 1
        if isinstance(self.multipart_type, (int, UBInt16)):
158 1
            self.multipart_type = self.multipart_type.enum_ref(
159
                self.multipart_type.value)
160
161 1
        pyof_class = simple_body.get(self.multipart_type, None)
162 1
        if pyof_class:
163 1
            return pyof_class()
164
165 1
        array_of_class = array_of_bodies.get(self.multipart_type, None)
166 1
        if array_of_class:
167 1
            return FixedTypeList(pyof_class=pyof_class)
168
169
        return BinaryData(b'')
170
171
172
# MultipartReply Body
173
174 1
class AggregateStatsReply(GenericStruct):
175
    """Body of reply to OFPMP_AGGREGATE request."""
176
177
    #: Number of packets in flows.
178 1
    packet_count = UBInt64()
179
    #: Number of bytes in flows.
180 1
    byte_count = UBInt64()
181
    #: Number of flows.
182 1
    flow_count = UBInt32()
183
    #: Align to 64 bits
184 1
    pad = Pad(4)
185
186 1
    def __init__(self, packet_count=None, byte_count=None, flow_count=None):
187
        """The constructor just assigns parameters to object attributes.
188
189
        Args:
190
            packet_count (int): Number of packets in flows
191
            byte_count (int):   Number of bytes in flows
192
            flow_count (int):   Number of flows
193
        """
194
        super().__init__()
195
        self.packet_count = packet_count
196
        self.byte_count = byte_count
197
        self.flow_count = flow_count
198
199
200 1 View Code Duplication
class Desc(GenericStruct):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
201
    """Information available from the OFPST_DESC stats request.
202
203
    Information about the switch manufacturer, hardware revision, software
204
    revision, serial number and a description field.
205
    """
206
207
    #: Manufacturer description
208 1
    mfr_desc = Char(length=DESC_STR_LEN)
209
    #: Hardware description
210 1
    hw_desc = Char(length=DESC_STR_LEN)
211
    #: Software description
212 1
    sw_desc = Char(length=DESC_STR_LEN)
213
    #: Serial number
214 1
    serial_num = Char(length=SERIAL_NUM_LEN)
215
    #: Datapath description
216 1
    dp_desc = Char(length=DESC_STR_LEN)
217
218 1
    def __init__(self, mfr_desc=None, hw_desc=None, sw_desc=None,
219
                 serial_num=None, dp_desc=None):
220
        """The constructor just assigns parameters to object attributes.
221
222
        Args:
223
            mfr_desc (str): Manufacturer description
224
            hw_desc (str): Hardware description
225
            sw_desc (str): Software description
226
            serial_num (str): Serial number
227
            dp_desc (str): Datapath description
228
        """
229 1
        super().__init__()
230 1
        self.mfr_desc = mfr_desc
231 1
        self.hw_desc = hw_desc
232 1
        self.sw_desc = sw_desc
233 1
        self.serial_num = serial_num
234 1
        self.dp_desc = dp_desc
235
236
237 1
class FlowStats(GenericStruct):
238
    """Body of reply to OFPST_FLOW request."""
239
240 1
    length = UBInt16()
241 1
    table_id = UBInt8()
242
    #: Align to 32 bits.
243 1
    pad = Pad(1)
244 1
    duration_sec = UBInt32()
245 1
    duration_nsec = UBInt32()
246 1
    priority = UBInt16()
247 1
    idle_timeout = UBInt16()
248 1
    hard_timeout = UBInt16()
249 1
    flags = UBInt16()
250
    #: Align to 64-bits
251 1
    pad2 = Pad(4)
252 1
    cookie = UBInt64()
253 1
    packet_count = UBInt64()
254 1
    byte_count = UBInt64()
255 1
    match = Match()
256
257 1 View Code Duplication
    def __init__(self, length=None, table_id=None, duration_sec=None,
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
258
                 duration_nsec=None, priority=None, idle_timeout=None,
259
                 hard_timeout=None, flags=None, cookie=None, packet_count=None,
260
                 byte_count=None, match=None):
0 ignored issues
show
Unused Code introduced by
The argument match seems to be unused.
Loading history...
261
        """The constructor just assigns parameters to object attributes.
262
263
        Args:
264
            length (int): Length of this entry.
265
            table_id (int): ID of table flow came from.
266
            duration_sec (int): Time flow has been alive in seconds.
267
            duration_nsec (int): Time flow has been alive in nanoseconds in
268
                addition to duration_sec.
269
            priority (int): Priority of the entry. Only meaningful when this
270
                is not an exact-match entry.
271
            idle_timeout (int): Number of seconds idle before expiration.
272
            hard_timeout (int): Number of seconds before expiration.
273
            cookie (int): Opaque controller-issued identifier.
274
            packet_count (int): Number of packets in flow.
275
            byte_count (int): Number of bytes in flow.
276
            match (~pyof.v0x04.common.flow_match.Match): Description of fields.
277
        """
278 1
        super().__init__()
279 1
        self.length = length
280 1
        self.table_id = table_id
281 1
        self.duration_sec = duration_sec
282 1
        self.duration_nsec = duration_nsec
283 1
        self.priority = priority
284 1
        self.idle_timeout = idle_timeout
285 1
        self.hard_timeout = hard_timeout
286 1
        self.flags = flags
287 1
        self.cookie = cookie
288 1
        self.packet_count = packet_count
289 1
        self.byte_count = byte_count
290
291
292 1
class PortStats(GenericStruct):
293
    """Body of reply to OFPST_PORT request.
294
295
    If a counter is unsupported, set the field to all ones.
296
    """
297
298 1
    port_no = UBInt32()
299
    #: Align to 64-bits.
300 1
    pad = Pad(4)
301 1
    rx_packets = UBInt64()
302 1
    tx_packets = UBInt64()
303 1
    rx_bytes = UBInt64()
304 1
    tx_bytes = UBInt64()
305 1
    rx_dropped = UBInt64()
306 1
    tx_dropped = UBInt64()
307 1
    rx_errors = UBInt64()
308 1
    tx_errors = UBInt64()
309 1
    rx_frame_err = UBInt64()
310 1
    rx_over_err = UBInt64()
311 1
    rx_crc_err = UBInt64()
312 1
    collisions = UBInt64()
313 1
    duration_sec = UBInt32()
314 1
    duration_nsec = UBInt32()
315
316
    # Can't avoid "too many local variables" (R0914) in this struct.
317
    # pylint: disable=R0914
318 1 View Code Duplication
    def __init__(self, port_no=None, rx_packets=None,
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
319
                 tx_packets=None, rx_bytes=None, tx_bytes=None,
320
                 rx_dropped=None, tx_dropped=None, rx_errors=None,
321
                 tx_errors=None, rx_frame_err=None, rx_over_err=None,
322
                 rx_crc_err=None, collisions=None, duration_sec=None,
323
                 duration_nsec=None):
324
        """The constructor assigns parameters to object attributes.
325
326
        Args:
327
            port_no (:class:`int`, :class:`~pyof.v0x04.common.port.Port`):
328
                Port number.
329
            rx_packets (int): Number of received packets.
330
            tx_packets (int): Number of transmitted packets.
331
            rx_bytes (int): Number of received bytes.
332
            tx_bytes (int): Number of transmitted bytes.
333
            rx_dropped (int): Number of packets dropped by RX.
334
            tx_dropped (int): Number of packets dropped by TX.
335
            rx_errors (int): Number of receive errors. This is a super-set of
336
                more specific receive errors and should be greater than or
337
                equal to the sum of all rx_*_err values.
338
            tx_errors (int): Number of transmit errors.  This is a super-set of
339
                more specific transmit errors and should be greater than or
340
                equal to the sum of all tx_*_err values (none currently
341
                defined).
342
            rx_frame_err (int): Number of frame alignment errors.
343
            rx_over_err (int): Number of packets with RX overrun.
344
            rx_crc_err (int): Number of CRC errors.
345
            collisions (int): Number of collisions.
346
            duration_sec (int): Time port has been alive in seconds
347
            duration_nsec (int): Time port has been alive in nanoseconds beyond
348
                duration_sec
349
        """
350 1
        super().__init__()
351 1
        self.port_no = port_no
352 1
        self.rx_packets = rx_packets
353 1
        self.tx_packets = tx_packets
354 1
        self.rx_bytes = rx_bytes
355 1
        self.tx_bytes = tx_bytes
356 1
        self.rx_dropped = rx_dropped
357 1
        self.tx_dropped = tx_dropped
358 1
        self.rx_errors = rx_errors
359 1
        self.tx_errors = tx_errors
360 1
        self.rx_frame_err = rx_frame_err
361 1
        self.rx_over_err = rx_over_err
362 1
        self.rx_crc_err = rx_crc_err
363 1
        self.collisions = collisions
364 1
        self.duration_sec = duration_sec
365 1
        self.duration_nsec = duration_nsec
366
367
368 1
class QueueStats(GenericStruct):
369
    """Implements the reply body of a port_no."""
370
371 1
    port_no = UBInt32()
372 1
    queue_id = UBInt32()
373 1
    tx_bytes = UBInt64()
374 1
    tx_packets = UBInt64()
375 1
    tx_errors = UBInt64()
376 1
    duration_sec = UBInt32()
377 1
    duration_nsec = UBInt32()
378
379 1
    def __init__(self, port_no=None, queue_id=None, tx_bytes=None,
380
                 tx_packets=None, tx_errors=None, duration_sec=None,
381
                 duration_nsec=None):
382
        """The constructor just assigns parameters to object attributes.
383
384
        Args:
385
            port_no (:class:`int`, :class:`~pyof.v0x04.common.port.Port`):
386
                Port Number.
387
            queue_id (int): Queue ID.
388
            tx_bytes (int): Number of transmitted bytes.
389
            tx_packets (int): Number of transmitted packets.
390
            tx_errors (int): Number of packets dropped due to overrun.
391
            duration_sec (int): Time queue has been alive in seconds.
392
            duration_nsec (int): Time queue has been alive in nanoseconds
393
                beyond duration_sec.
394
        """
395 1
        super().__init__()
396 1
        self.port_no = port_no
397 1
        self.queue_id = queue_id
398 1
        self.tx_bytes = tx_bytes
399 1
        self.tx_packets = tx_packets
400 1
        self.tx_errors = tx_errors
401 1
        self.duration_sec = duration_sec
402 1
        self.duration_nsec = duration_nsec
403 View Code Duplication
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
404
405 1
class GroupDescStats(GenericStruct):
406
    """Body of reply to OFPMP_GROUP_DESC request."""
407
408 1
    length = UBInt16()
409 1
    group_type = UBInt8()
410
    #: Pad to 64 bits.
411 1
    pad = Pad(1)
412 1
    group_id = UBInt32()
413 1
    buckets = FixedTypeList(Bucket)
414
415 1
    def __init__(self, length=None, group_type=None, group_id=None,
416
                 buckets=None):
417
        """The constructor just assigns parameters to object attributes.
418
419
        Args:
420
            length (int): Length of this entry.
421
            group_type (|GroupType_v0x04|): One of OFPGT_*.
422
            group_id (int): Group identifier.
423
            buckets (|ListOfBuckets_v0x04|): List of buckets in group.
424
        """
425
        super().__init__()
426
        self.length = length
427
        self.group_type = group_type
428
        self.group_id = group_id
429
        self.buckets = buckets
430
431
432 1
class GroupFeatures(GenericStruct):
433
    """Body of reply to OFPMP_GROUP_FEATURES request.Group features."""
434
435 1
    types = UBInt32()
436 1
    capabilities = UBInt32(enum_ref=GroupCapabilities)
437 1
    max_groups1 = UBInt32()
438 1
    max_groups2 = UBInt32()
439 1
    max_groups3 = UBInt32()
440 1
    max_groups4 = UBInt32()
441 1
    actions1 = UBInt32()
442 1
    actions2 = UBInt32()
443 1
    actions3 = UBInt32()
444 1
    actions4 = UBInt32()
445
446 1
    def __init__(self, types=None, capabilities=None, max_groups1=None,
447
                 max_groups2=None, max_groups3=None, max_groups4=None,
448
                 actions1=None, actions2=None, actions3=None, actions4=None):
449
        """The constructor just assigns parameters to object attributes.
450
451
        Args:
452
            types: Bitmap of OFPGT_* values supported.
453
            capabilities: Bitmap of OFPGFC_* capability supported.
454
            max_groups: 4-position array; Maximum number of groups for each
455
                type.
456
            actions: 4-position array; Bitmaps of OFPAT_* that are supported.
457
        """
458
        super().__init__()
459
        self.types = types
460
        self.capabilities = capabilities
461
        self.max_groups1 = max_groups1
462
        self.max_groups2 = max_groups2
463
        self.max_groups3 = max_groups3
464
        self.max_groups4 = max_groups4
465
        self.actions1 = actions1
466
        self.actions2 = actions2
467
        self.actions3 = actions3
468
        self.actions4 = actions4
469
470
471 1
class GroupStats(GenericStruct):
472
    """Body of reply to OFPMP_GROUP request."""
473
474 1
    length = UBInt16()
475
    #: Align to 64 bits.
476 1
    pad = Pad(2)
477 1
    group_id = UBInt32()
478 1
    ref_count = UBInt32()
479
    #: Align to 64 bits.
480 1
    pad2 = Pad(4)
481 1
    packet_count = UBInt64()
482 1
    byte_count = UBInt64()
483 1
    duration_sec = UBInt32()
484 1
    duration_nsec = UBInt32()
485 1
    bucket_stats = FixedTypeList(BucketCounter)
486
487 1
    def __init__(self, length=None, group_id=None, ref_count=None,
488
                 packet_count=None, byte_count=None, duration_sec=None,
489
                 duration_nsec=None, bucket_stats=None):
490
        """The constructor just assigns parameters to object attributes.
491
492
        Args:
493
            length: Length of this entry
494
            group_id: Group identifier
495
            ref_count: Number of flows or groups that directly forward
496
                to this group.
497
            packet_count: Number of packets processed by group
498
            byte_count: Number of bytes processed by group
499
            duration_sec: Time group has been alive in seconds
500
            duration_nsec: Time group has been alive in nanoseconds
501
            bucket_stats: List of stats of group buckets
502
        """
503
        super().__init__()
504
        self.length = length
505
        self.group_id = group_id
506
        self.ref_count = ref_count
507
        self.packet_count = packet_count
508
        self.byte_count = byte_count
509
        self.duration_sec = duration_sec
510
        self.duration_nsec = duration_nsec
511
        self.bucket_stats = bucket_stats
512
513
514 1
class MeterConfig(GenericStruct):
515
    """MeterConfig is a class to represent ofp_meter_config structure.
516
517
    Body of reply to OFPMP_METER_CONFIG request.
518
    """
519
520
    # Length of this entry.
521 1
    length = UBInt16()
522
    # All OFPMC_* that apply.
523 1
    flags = UBInt16(enum_ref=MeterFlags)
524
    # Meter instance or OFPM_ALL .
525 1
    meter_id = UBInt32()
526
    # The bands length is inferred from the length field.
527 1
    bands = ListOfMeterBandHeader()
528
529 1
    def __init__(self, flags=MeterFlags.OFPMF_STATS, meter_id=None,
530
                 bands=None):
531
        """The Constructor of MeterConfig receives the parameters below.
532
533
        Args:
534
            flags (|MeterFlags_v0x04|):
535
                Meter configuration flags.The default value is
536
                MeterFlags.OFPMF_STATS
537
            meter_id (|Meter_v0x04|):
538
                Meter Indentify.The value Meter.OFPM_ALL is used to
539
                refer to all Meters on the switch.
540
            bands(list): List of MeterBandHeader instances.
541
        """
542
        super().__init__()
543
        self.flags = flags
544
        self.meter_id = meter_id
545
        self.bands = bands if bands else []
546
547
548 1
class MeterFeatures(GenericStruct):
549
    """Body of reply to OFPMP_METER_FEATURES request. Meter features."""
550
551 1
    max_meter = UBInt32()
552 1
    band_types = UBInt32(enum_ref=MeterBandType)
553 1
    capabilities = UBInt32(enum_ref=MeterFlags)
554 1
    max_bands = UBInt8()
555 1
    max_color = UBInt8()
556 1
    pad = Pad(2)
557
558 1
    def __init__(self, max_meter=None, band_types=None, capabilities=None,
559
                 max_bands=None, max_color=None):
560
        """The Constructor of MeterFeatures receives the parameters below.
561
562
        Args:
563
            max_meter(int): Maximum number of meters.
564
            band_types (|MeterBandType_v0x04|):
565
                Bitmaps of OFPMBT_* values supported.
566
            capabilities (|MeterFlags_v0x04|): Bitmaps of "ofp_meter_flags".
567
            max_bands(int): Maximum bands per meters
568
            max_color(int): Maximum color value
569
        """
570
        super().__init__()
571
        self.max_meter = max_meter
572
        self.band_types = band_types
573
        self.capabilities = capabilities
574
        self.max_bands = max_bands
575
        self.max_color = max_color
576
577
578 1
class BandStats(GenericStruct):
579
    """Band  Statistics.
580
581
    Statistics for each meter band.
582
    """
583
584 1
    packet_band_count = UBInt64()
585 1
    byte_band_count = UBInt64()
586
587 1
    def __init__(self, packet_band_count=None, byte_band_count=None):
588
        """The constructor just assigns parameters to object attributes.
589
590
        Args:
591
            packet_band_count(int): Number of packets in band.
592
            byte_band_count(int):   Number of bytes in band.
593
        """
594
        super().__init__()
595
        self.packet_band_count = packet_band_count
596
        self.byte_band_count = byte_band_count
597
598
599 1
class ListOfBandStats(FixedTypeList):
600
    """List of BandStats.
601
602
    Represented by instances of BandStats.
603
    """
604
605 1
    def __init__(self, items=None):
606
        """The constructor just assigns parameters to object attributes.
607
608
        Args:
609
            items (|BandStats_v0x04|): Instance or a list of instances.
610
        """
611 1
        super().__init__(pyof_class=BandStats, items=items)
612
613
614 1
class MeterStats(GenericStruct):
615
    """Meter Statistics.
616
617
    Body of reply to OFPMP_METER request.
618
    """
619
620 1
    meter_id = UBInt32()
621 1
    length = UBInt16()
622 1
    pad = Pad(6)
623 1
    flow_count = UBInt32()
624 1
    packet_in_count = UBInt64()
625 1
    byte_in_count = UBInt64()
626 1
    duration_sec = UBInt32()
627 1
    duration_nsec = UBInt32()
628 1
    band_stats = ListOfBandStats()
629
630 1
    def __init__(self, meter_id=None, flow_count=None,
631
                 packet_in_count=None, byte_in_count=None, duration_sec=None,
632
                 duration_nsec=None, band_stats=None):
633
        """The constructor just assigns parameters to object attributes.
634
635
        Args:
636
            meter_id (|Meter_v0x04|):  Meter instance.
637
            flow_count(int):      Number of flows bound to meter.
638
            packet_in_count(int): Number of packets in input.
639
            byte_in_count(int):   Number of bytes in input.
640
            duration_sec(int):    Time meter has been alive in seconds.
641
            duration_nsec(int):   Time meter has been alive in
642
                                  nanoseconds beyond duration_sec.
643
            band_stats(list):     Instances of BandStats
644
        """
645
        super().__init__()
646
        self.meter_id = meter_id
647
        self.flow_count = flow_count
648
        self.packet_in_count = packet_in_count
649
        self.byte_in_count = byte_in_count
650
        self.duration_sec = duration_sec
651
        self.duration_nsec = duration_nsec
652
        self.band_stats = band_stats if band_stats else []
653
        self.update_length()
654
655 1
    def update_length(self):
656
        """Update length attribute with current struct length."""
657
        self.length = self.get_size()
658
659 1
    def pack(self, value=None):
660
        """Pack method used to update the length of instance and packing.
661
662
        Args:
663
            value: Structure to be packed.
664
        """
665
        self.update_length()
666
        return super().pack(value)
667
668 1
    def unpack(self, buff=None, offset=0):
669
        """Unpack *buff* into this object.
670
671
        This method will convert a binary data into a readable value according
672
        to the attribute format.
673
674
        Args:
675
            buff (bytes): Binary buffer.
676
            offset (int): Where to begin unpacking.
677
678
        Raises:
679
            :exc:`~.exceptions.UnpackException`: If unpack fails.
680
        """
681
        length = UBInt16()
682
        length.unpack(buff, offset)
683
684
        length.unpack(buff, offset=offset+MeterStats.meter_id.get_size())
685
        super().unpack(buff[:offset+length.value], offset=offset)
686
687
688 1
class TableStats(GenericStruct):
689
    """Body of reply to OFPST_TABLE request."""
690
691 1
    table_id = UBInt8()
692
    #: Align to 32-bits.
693 1
    pad = Pad(3)
694 1
    active_count = UBInt32()
695 1
    lookup_count = UBInt64()
696 1
    matched_count = UBInt64()
697
698 1
    def __init__(self, table_id=None, name=None, max_entries=None,
0 ignored issues
show
Unused Code introduced by
The argument name seems to be unused.
Loading history...
Unused Code introduced by
The argument max_entries seems to be unused.
Loading history...
699
                 active_count=None, lookup_count=None,
700
                 matched_count=None):
701
        """The constructor just assigns parameters to object attributes.
702
703
        Args:
704
            table_id (int): Identifier of table.  Lower numbered tables are
705
                consulted first.
706
            active_count (int): Number of active entries.
707
            lookup_count (int): Number of packets looked up in table.
708
            matched_count (int): Number of packets that hit table.
709
        """
710 1
        super().__init__()
711 1
        self.table_id = table_id
712 1
        self.active_count = active_count
713 1
        self.lookup_count = lookup_count
714
        self.matched_count = matched_count
715