1 | """Defines Hello message.""" |
||
2 | |||
3 | # System imports |
||
4 | |||
5 | 1 | from enum import IntEnum |
|
6 | |||
7 | 1 | from pyof.foundation.base import GenericMessage, GenericStruct |
|
8 | 1 | from pyof.foundation.basic_types import BinaryData, FixedTypeList, UBInt16 |
|
9 | 1 | from pyof.foundation.exceptions import PackException |
|
10 | 1 | from pyof.v0x04.common.header import Header, Type |
|
11 | |||
12 | # Third-party imports |
||
13 | |||
14 | 1 | __all__ = ('Hello', 'HelloElemHeader', 'HelloElemType', 'ListOfHelloElements') |
|
15 | |||
16 | # Enums |
||
17 | |||
18 | |||
19 | 1 | class HelloElemType(IntEnum): |
|
20 | """Hello element types.""" |
||
21 | |||
22 | #: Bitmap of version supported. |
||
23 | 1 | OFPHET_VERSIONBITMAP = 1 |
|
24 | |||
25 | |||
26 | # Classes |
||
27 | |||
28 | |||
29 | 1 | class HelloElemHeader(GenericStruct): |
|
30 | """Common header for all Hello Elements.""" |
||
31 | |||
32 | 1 | element_type = UBInt16() |
|
33 | 1 | length = UBInt16() |
|
34 | 1 | content = BinaryData() |
|
35 | |||
36 | 1 | def __init__(self, element_type=None, length=None, content=b''): |
|
37 | """Create a HelloElemHeader with the optional parameters below. |
||
38 | |||
39 | Args: |
||
40 | element_type: One of OFPHET_*. |
||
41 | length: Length in bytes of the element, including this header, |
||
42 | excluding padding. |
||
43 | """ |
||
44 | 1 | super().__init__() |
|
45 | 1 | self.element_type = element_type |
|
46 | 1 | self.length = length |
|
47 | 1 | self.content = content |
|
48 | |||
49 | 1 | View Code Duplication | def pack(self, value=None): |
0 ignored issues
–
show
Duplication
introduced
by
![]() |
|||
50 | """Update the length and pack the massege into binary data. |
||
51 | |||
52 | Returns: |
||
53 | bytes: A binary data that represents the Message. |
||
54 | |||
55 | Raises: |
||
56 | Exception: If there are validation errors. |
||
57 | |||
58 | """ |
||
59 | 1 | if value is None: |
|
60 | 1 | self.update_length() |
|
61 | 1 | return super().pack() |
|
62 | if isinstance(value, type(self)): |
||
63 | return value.pack() |
||
64 | msg = "{} is not an instance of {}".format(value, type(self).__name__) |
||
65 | raise PackException(msg) |
||
66 | |||
67 | 1 | def update_length(self): |
|
68 | """Update length attribute.""" |
||
69 | 1 | self.length = self.get_size() |
|
70 | |||
71 | 1 | def unpack(self, buff=None, offset=0): |
|
72 | """Unpack *buff* into this object. |
||
73 | |||
74 | This method will convert a binary data into a readable value according |
||
75 | to the attribute format. |
||
76 | |||
77 | Args: |
||
78 | buff (bytes): Binary buffer. |
||
79 | offset (int): Where to begin unpacking. |
||
80 | |||
81 | Raises: |
||
82 | :exc:`~.exceptions.UnpackException`: If unpack fails. |
||
83 | |||
84 | """ |
||
85 | 1 | length = UBInt16() |
|
86 | 1 | length.unpack(buff, offset=offset+2) |
|
87 | |||
88 | 1 | super().unpack(buff[:offset+length.value], offset) |
|
89 | |||
90 | |||
91 | 1 | class ListOfHelloElements(FixedTypeList): |
|
92 | """List of Hello elements. |
||
93 | |||
94 | Represented by instances of HelloElemHeader and used on Hello |
||
95 | objects. |
||
96 | """ |
||
97 | |||
98 | 1 | def __init__(self, items=None): |
|
99 | """Create a ListOfHelloElements with the optional parameters below. |
||
100 | |||
101 | Args: |
||
102 | items (HelloElemHeader): Instance or a list of instances. |
||
103 | """ |
||
104 | 1 | super().__init__(pyof_class=HelloElemHeader, items=items) |
|
105 | |||
106 | |||
107 | 1 | class Hello(GenericMessage): |
|
108 | """OpenFlow Hello Message OFPT_HELLO. |
||
109 | |||
110 | This message includes zero or more hello elements having variable size. |
||
111 | Unknown element types must be ignored/skipped, to allow for future |
||
112 | extensions. |
||
113 | """ |
||
114 | |||
115 | 1 | header = Header(message_type=Type.OFPT_HELLO) |
|
116 | #: Hello element list |
||
117 | 1 | elements = ListOfHelloElements() |
|
118 | |||
119 | 1 | def __init__(self, xid=None, elements=None): |
|
120 | """Create a Hello with the optional parameters below. |
||
121 | |||
122 | Args: |
||
123 | xid (int): xid to be used on the message header. |
||
124 | elements: List of elements - 0 or more |
||
125 | """ |
||
126 | 1 | super().__init__(xid) |
|
127 | self.elements = elements |
||
128 |