blob: a952aa274fdffc9135fcd176cc49bfc5b2e70cb6 [file] [log] [blame]
Shad Ansari0d83c942017-07-05 21:30:38 -07001#
2# Copyright 2017 the original author or authors.
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15#
16import structlog
Shad Ansarida0f3a42017-07-19 09:51:06 -070017from scapy.layers.l2 import Ether, Dot1Q
18from voltha.registry import registry
Shad Ansari0d83c942017-07-05 21:30:38 -070019from voltha.protos.common_pb2 import OperStatus, ConnectStatus, AdminState
20
Shad Ansari1831fcc2017-08-11 16:41:44 -070021
Shad Ansari0d83c942017-07-05 21:30:38 -070022class DeviceHandler(object):
23 def __init__(self, adapter, device_id):
24 self.adapter = adapter
25 self.adapter_agent = adapter.adapter_agent
26 self.device_id = device_id
27 self.log = structlog.get_logger(device_id=device_id)
28 self.logical_device_id = None
29
30 def disable(self):
31 self.log.info('disabling', device_id=self.device_id)
32
33 # Get the latest device reference
34 device = self.adapter_agent.get_device(self.device_id)
35
36 # Disable all ports on that device
37 self.adapter_agent.disable_all_ports(self.device_id)
38
39 # Update the operational status to UNKNOWN
40 device.oper_status = OperStatus.UNKNOWN
41 device.connect_status = ConnectStatus.UNREACHABLE
42 self.adapter_agent.update_device(device)
43
Shad Ansari1831fcc2017-08-11 16:41:44 -070044
Shad Ansari0d83c942017-07-05 21:30:38 -070045class OltDeviceHandler(DeviceHandler):
46 def __init__(self, adapter, device_id):
47 super(OltDeviceHandler, self).__init__(adapter, device_id)
Shad Ansarida0f3a42017-07-19 09:51:06 -070048 self.filter = None
rshettye4bd2ed2017-07-19 16:38:11 +053049 self.io_port = None
rshettyc26a3c32017-07-27 11:06:38 +053050 self.interface = registry('main').get_args().interface
Shad Ansarida0f3a42017-07-19 09:51:06 -070051
52 def __del__(self):
53 if self.io_port is not None:
54 registry('frameio').close_port(self.io_port)
Shad Ansari0d83c942017-07-05 21:30:38 -070055
56 def disable(self):
57 super(OltDeviceHandler, self).disable()
58
59 # Remove the logical device
60 logical_device = self.adapter_agent.get_logical_device(
61 self.logical_device_id)
62 self.adapter_agent.delete_logical_device(logical_device)
63
64 # Disable all child devices first
65 self.adapter_agent.update_child_devices_state(self.device_id,
66 admin_state=AdminState.DISABLED)
67
68 # Remove the peer references from this device
69 self.adapter_agent.delete_all_peer_references(self.device_id)
70
71 # Update the logice device mapping
72 if self.logical_device_id in \
73 self.adapter.logical_device_id_to_root_device_id:
74 del self.adapter.logical_device_id_to_root_device_id[
75 self.logical_device_id]
76
77 # TODO:
78 # 1) Remove all flows from the device
79 # 2) Remove the device from ponsim
80
81 self.log.info('disabled', device_id=self.device_id)
82
83 def delete(self):
84 self.log.info('deleting', device_id=self.device_id)
85
86 # Remove all child devices
87 self.adapter_agent.delete_all_child_devices(self.device_id)
88
89 # TODO:
90 # 1) Remove all flows from the device
91 # 2) Remove the device from ponsim
92
93 self.log.info('deleted', device_id=self.device_id)
94
Shad Ansarida0f3a42017-07-19 09:51:06 -070095 def activate_io_port(self):
96 if self.io_port is None:
97 self.log.info('registering-frameio')
98 self.io_port = registry('frameio').open_port(
99 self.interface, self.rcv_io, self.filter)
100
101 def deactivate_io_port(self):
102 io, self.io_port = self.io_port, None
103
104 if io is not None:
105 registry('frameio').close_port(io)
106
107 def rcv_io(self, port, frame):
108 self.log.info('received', iface_name=port.iface_name,
109 frame_len=len(frame))
110 pkt = Ether(frame)
111 if pkt.haslayer(Dot1Q):
112 outer_shim = pkt.getlayer(Dot1Q)
113 if isinstance(outer_shim.payload, Dot1Q):
114 inner_shim = outer_shim.payload
115 cvid = inner_shim.vlan
116 logical_port = cvid
117 popped_frame = (
118 Ether(src=pkt.src, dst=pkt.dst, type=inner_shim.type) /
119 inner_shim.payload
120 )
121 kw = dict(
122 logical_device_id=self.logical_device_id,
123 logical_port_no=logical_port,
124 )
125 self.log.info('sending-packet-in', **kw)
126 self.adapter_agent.send_packet_in(
127 packet=str(popped_frame), **kw)
128 '''
129 # TODO: handle non dot1q pkts
130 elif pkt.haslayer(Raw):
131 raw_data = json.loads(pkt.getlayer(Raw).load)
132 self.alarms.send_alarm(self, raw_data)
133 '''
134
Shad Ansari1831fcc2017-08-11 16:41:44 -0700135 def packet_out(self, egress_port, msg):
136 raise NotImplementedError()
137
138
Shad Ansari0d83c942017-07-05 21:30:38 -0700139class OnuDeviceHandler(DeviceHandler):
140 pass