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