1 | # -*- coding: utf-8 -*- |
---|
2 | """ |
---|
3 | ------------------------------------------------------------------------------ |
---|
4 | Mango 802.11 Reference Design Experiments Framework |
---|
5 | - Transport Broadcast Ethernet IP/UDP Python Socket Implementation |
---|
6 | ------------------------------------------------------------------------------ |
---|
7 | License: Copyright 2019 Mango Communications, Inc. All rights reserved. |
---|
8 | Use and distribution subject to terms in LICENSE.txt |
---|
9 | ------------------------------------------------------------------------------ |
---|
10 | |
---|
11 | This module provides the broadcast Ethernet IP/UDP transport based on the |
---|
12 | python socket class. |
---|
13 | |
---|
14 | Functions: |
---|
15 | TransportEthUdpPyBcast() -- Broadcast Ethernet UDP transport based on |
---|
16 | python sockets |
---|
17 | |
---|
18 | """ |
---|
19 | |
---|
20 | from . import transport_eth_ip_udp as tp |
---|
21 | |
---|
22 | |
---|
23 | __all__ = ['TransportEthIpUdpPyBroadcast'] |
---|
24 | |
---|
25 | |
---|
26 | class TransportEthIpUdpPyBroadcast(tp.TransportEthIpUdp): |
---|
27 | """Class for Ethernet IP/UDP Broadcast Transport class using Python libraries. |
---|
28 | |
---|
29 | Attributes: |
---|
30 | See TransportEthIpUdp for attributes |
---|
31 | network_config -- A NetworkConfiguration that describes the transport configuration. |
---|
32 | |
---|
33 | The transport will send packets to the first host interface as the subnet |
---|
34 | for the broadcast address. |
---|
35 | """ |
---|
36 | network_config = None |
---|
37 | |
---|
38 | def __init__(self, network_config=None): |
---|
39 | super(TransportEthIpUdpPyBroadcast, self).__init__() |
---|
40 | |
---|
41 | if network_config is not None: |
---|
42 | self.network_config = network_config |
---|
43 | else: |
---|
44 | from . import config |
---|
45 | |
---|
46 | self.network_config = config.NetworkConfiguration() |
---|
47 | |
---|
48 | self.set_default_config() |
---|
49 | |
---|
50 | |
---|
51 | def set_default_config(self): |
---|
52 | """Set the default configuration of a Broadcast transport.""" |
---|
53 | unicast_port = self.network_config.get_param('unicast_port') |
---|
54 | broadcast_port = self.network_config.get_param('broadcast_port') |
---|
55 | host_id = self.network_config.get_param('host_id') |
---|
56 | broadcast_addr = self.network_config.get_param('broadcast_address') |
---|
57 | |
---|
58 | # Set default values of the Transport |
---|
59 | self.set_ip_address(broadcast_addr) |
---|
60 | self.set_unicast_port(unicast_port) |
---|
61 | self.set_broadcast_port(broadcast_port) |
---|
62 | self.set_src_id(host_id) |
---|
63 | self.set_dest_id(0xFFFF) |
---|
64 | self.timeout = 1 |
---|
65 | |
---|
66 | |
---|
67 | def set_ip_address(self, ip_addr): |
---|
68 | """Sets the IP address of the Broadcast transport. |
---|
69 | |
---|
70 | This method will take an IP address of the form W.X.Y.Z and set the |
---|
71 | transport IP address to W.X.Y.255 so that it is a proper broadcast |
---|
72 | address. |
---|
73 | """ |
---|
74 | #expr = re.compile('\.') |
---|
75 | #tmp = [int(n) for n in expr.split(ip_addr)] |
---|
76 | tmp = [int(n) for n in ip_addr.split('.')] |
---|
77 | self.ip_address = "{0:d}.{1:d}.{2:d}.255".format(tmp[0], tmp[1], tmp[2]) |
---|
78 | |
---|
79 | |
---|
80 | def send(self, payload, robust=False): |
---|
81 | """Send a broadcast packet over the transport. |
---|
82 | |
---|
83 | Attributes: |
---|
84 | data -- Data to be sent over the socket |
---|
85 | """ |
---|
86 | if robust: |
---|
87 | print("WARNING: Not able to send broadcast robust packets.") |
---|
88 | |
---|
89 | self.hdr.response_not_required() |
---|
90 | self.hdr.set_length(len(payload)) |
---|
91 | self.hdr.increment() |
---|
92 | |
---|
93 | # Assemble the packet from the transport header and payload |
---|
94 | # The wlan_exp C assumes the bytes starting at 'payload' here are u32 aligned |
---|
95 | # in the full Ethernet packet. The transport header is 10 bytes by design, |
---|
96 | # which aligns the end of the transport header to a 4-byte boundary when |
---|
97 | # appended to a 14-byte Ethernet + 20-byte IP + 8-byte UDP header |
---|
98 | # Different padding would be required here if the sizes of the headers |
---|
99 | # before the transport header change |
---|
100 | data = bytes(self.hdr.serialize() + payload) |
---|
101 | |
---|
102 | size = self.sock.sendto(data, (self.ip_address, self.broadcast_port)) |
---|
103 | |
---|
104 | if size != len(data): |
---|
105 | print("Only {} of {} bytes of data sent".format(size, len(data))) |
---|
106 | |
---|
107 | |
---|
108 | def receive(self, timeout=None): |
---|
109 | """Not used on a broadcast transport""" |
---|
110 | super(TransportEthIpUdpPyBroadcast, self).receive() |
---|
111 | |
---|
112 | |
---|
113 | # End Class |
---|
114 | |
---|
115 | |
---|
116 | |
---|
117 | |
---|
118 | |
---|
119 | |
---|
120 | |
---|
121 | |
---|
122 | |
---|
123 | |
---|
124 | |
---|
125 | |
---|
126 | |
---|
127 | |
---|
128 | |
---|
129 | |
---|
130 | |
---|
131 | |
---|
132 | |
---|
133 | |
---|
134 | |
---|
135 | |
---|
136 | |
---|
137 | |
---|
138 | |
---|
139 | |
---|
140 | |
---|
141 | |
---|
142 | |
---|
143 | |
---|
144 | |
---|
145 | |
---|