blob: b8971883d544a5d4c1cdf9c39346c9b9fab8e75a [file] [log] [blame]
khenaidoob9203542018-09-17 22:56:37 -04001#
khenaidoo6fdf0ba2018-11-02 14:38:33 -04002# Copyright 2018 the original author or authors.
khenaidoob9203542018-09-17 22:56:37 -04003#
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#
16
17"""
khenaidoo6fdf0ba2018-11-02 14:38:33 -040018Agent to play gateway between CORE and an adapter.
khenaidoob9203542018-09-17 22:56:37 -040019"""
khenaidoob9203542018-09-17 22:56:37 -040020import structlog
khenaidoob9203542018-09-17 22:56:37 -040021from google.protobuf.message import Message
khenaidoo6fdf0ba2018-11-02 14:38:33 -040022from twisted.internet.defer import inlineCallbacks, returnValue
23
khenaidoofdbad6e2018-11-06 22:26:38 -050024from container_proxy import ContainerProxy
25from python.protos.common_pb2 import ID, ConnectStatus, OperStatus
khenaidoo79232702018-12-04 11:00:41 -050026from python.protos.inter_container_pb2 import StrType, BoolType, IntType, Packet
khenaidoofdbad6e2018-11-06 22:26:38 -050027from python.protos.device_pb2 import Device, Ports
28from python.protos.voltha_pb2 import CoreInstance
khenaidoob9203542018-09-17 22:56:37 -040029
30log = structlog.get_logger()
31
khenaidoob9203542018-09-17 22:56:37 -040032
khenaidoo43c82122018-11-22 18:38:28 -050033def createSubTopic(*args):
34 return '_'.join(args)
35
khenaidoo6fdf0ba2018-11-02 14:38:33 -040036class CoreProxy(ContainerProxy):
khenaidoob9203542018-09-17 22:56:37 -040037
38 def __init__(self, kafka_proxy, core_topic, my_listening_topic):
khenaidoo6fdf0ba2018-11-02 14:38:33 -040039 super(CoreProxy, self).__init__(kafka_proxy, core_topic,
40 my_listening_topic)
khenaidoob9203542018-09-17 22:56:37 -040041
khenaidoo6fdf0ba2018-11-02 14:38:33 -040042 @ContainerProxy.wrap_request(CoreInstance)
khenaidoob9203542018-09-17 22:56:37 -040043 @inlineCallbacks
khenaidoo91ecfd62018-11-04 17:13:42 -050044 def register(self, adapter, deviceTypes):
khenaidoob9203542018-09-17 22:56:37 -040045 log.debug("register")
46 try:
khenaidoo91ecfd62018-11-04 17:13:42 -050047 res = yield self.invoke(rpc="Register",
48 adapter=adapter,
49 deviceTypes=deviceTypes)
khenaidoob9203542018-09-17 22:56:37 -040050 log.info("registration-returned", res=res)
51 returnValue(res)
52 except Exception as e:
53 log.exception("registration-exception", e=e)
54 raise
55
khenaidoo6fdf0ba2018-11-02 14:38:33 -040056 @ContainerProxy.wrap_request(Device)
khenaidoob9203542018-09-17 22:56:37 -040057 @inlineCallbacks
58 def get_device(self, device_id):
59 log.debug("get-device")
60 id = ID()
61 id.id = device_id
khenaidoo43c82122018-11-22 18:38:28 -050062 # Once we have a device being managed, all communications between the
63 # the adapter and the core occurs over a topic associated with that
64 # device
65 to_topic = createSubTopic(self.core_topic, device_id)
66 reply_topic = createSubTopic(self.listening_topic, device_id)
67 res = yield self.invoke(rpc="GetDevice",
68 to_topic=to_topic,
69 reply_topic=reply_topic,
70 device_id=id)
khenaidoob9203542018-09-17 22:56:37 -040071 returnValue(res)
72
khenaidoo6fdf0ba2018-11-02 14:38:33 -040073 @ContainerProxy.wrap_request(Device)
khenaidoob9203542018-09-17 22:56:37 -040074 @inlineCallbacks
75 def get_child_device(self, parent_device_id, **kwargs):
76 raise NotImplementedError()
77
khenaidoo6fdf0ba2018-11-02 14:38:33 -040078 @ContainerProxy.wrap_request(Ports)
khenaidoo92e62c52018-10-03 14:02:54 -040079 @inlineCallbacks
khenaidoob9203542018-09-17 22:56:37 -040080 def get_ports(self, device_id, port_type):
khenaidoo92e62c52018-10-03 14:02:54 -040081 id = ID()
82 id.id = device_id
83 p_type = IntType()
84 p_type.val = port_type
khenaidoo43c82122018-11-22 18:38:28 -050085 to_topic = createSubTopic(self.core_topic, device_id)
86 reply_topic = createSubTopic(self.listening_topic, device_id)
khenaidoo92e62c52018-10-03 14:02:54 -040087 res = yield self.invoke(rpc="GetPorts",
khenaidoo43c82122018-11-22 18:38:28 -050088 to_topic=to_topic,
89 reply_topic=reply_topic,
khenaidoo92e62c52018-10-03 14:02:54 -040090 device_id=id,
91 port_type=p_type)
92 returnValue(res)
khenaidoob9203542018-09-17 22:56:37 -040093
94 def get_child_devices(self, parent_device_id):
95 raise NotImplementedError()
96
97 def get_child_device_with_proxy_address(self, proxy_address):
98 raise NotImplementedError()
99
100 def _to_proto(self, **kwargs):
101 encoded = {}
khenaidoo6fdf0ba2018-11-02 14:38:33 -0400102 for k, v in kwargs.iteritems():
khenaidoob9203542018-09-17 22:56:37 -0400103 if isinstance(v, Message):
104 encoded[k] = v
105 elif type(v) == int:
106 i_proto = IntType()
107 i_proto.val = v
108 encoded[k] = i_proto
109 elif type(v) == str:
110 s_proto = StrType()
111 s_proto.val = v
112 encoded[k] = s_proto
113 elif type(v) == bool:
114 b_proto = BoolType()
115 b_proto.val = v
116 encoded[k] = b_proto
117 return encoded
118
khenaidoo6fdf0ba2018-11-02 14:38:33 -0400119 @ContainerProxy.wrap_request(None)
khenaidoob9203542018-09-17 22:56:37 -0400120 @inlineCallbacks
121 def child_device_detected(self,
122 parent_device_id,
123 parent_port_no,
124 child_device_type,
125 channel_id,
126 **kw):
127 id = ID()
128 id.id = parent_device_id
129 ppn = IntType()
130 ppn.val = parent_port_no
131 cdt = StrType()
132 cdt.val = child_device_type
133 channel = IntType()
134 channel.val = channel_id
khenaidoo43c82122018-11-22 18:38:28 -0500135 to_topic = createSubTopic(self.core_topic, parent_device_id)
136 reply_topic = createSubTopic(self.listening_topic, parent_device_id)
khenaidoob9203542018-09-17 22:56:37 -0400137 args = self._to_proto(**kw)
138 res = yield self.invoke(rpc="ChildDeviceDetected",
khenaidoo43c82122018-11-22 18:38:28 -0500139 to_topic=to_topic,
140 reply_topic=reply_topic,
khenaidoob9203542018-09-17 22:56:37 -0400141 parent_device_id=id,
khenaidoo6fdf0ba2018-11-02 14:38:33 -0400142 parent_port_no=ppn,
143 child_device_type=cdt,
khenaidoob9203542018-09-17 22:56:37 -0400144 channel_id=channel,
145 **args)
146 returnValue(res)
147
khenaidoo6fdf0ba2018-11-02 14:38:33 -0400148 @ContainerProxy.wrap_request(None)
khenaidoob9203542018-09-17 22:56:37 -0400149 @inlineCallbacks
150 def device_update(self, device):
151 log.debug("device_update")
khenaidoo43c82122018-11-22 18:38:28 -0500152 to_topic = createSubTopic(self.core_topic, device.id)
153 reply_topic = createSubTopic(self.listening_topic, device.id)
154 res = yield self.invoke(rpc="DeviceUpdate",
155 to_topic=to_topic,
156 reply_topic=reply_topic,
157 device=device)
khenaidoob9203542018-09-17 22:56:37 -0400158 returnValue(res)
159
160 def child_device_removed(parent_device_id, child_device_id):
161 raise NotImplementedError()
162
khenaidoo6fdf0ba2018-11-02 14:38:33 -0400163 @ContainerProxy.wrap_request(None)
khenaidoob9203542018-09-17 22:56:37 -0400164 @inlineCallbacks
165 def device_state_update(self, device_id,
khenaidoo6fdf0ba2018-11-02 14:38:33 -0400166 oper_status=None,
167 connect_status=None):
khenaidoob9203542018-09-17 22:56:37 -0400168 id = ID()
169 id.id = device_id
170 o_status = IntType()
khenaidoo6fdf0ba2018-11-02 14:38:33 -0400171 if oper_status or oper_status == OperStatus.UNKNOWN:
khenaidoob9203542018-09-17 22:56:37 -0400172 o_status.val = oper_status
173 else:
174 o_status.val = -1
175 c_status = IntType()
khenaidoo6fdf0ba2018-11-02 14:38:33 -0400176 if connect_status or connect_status == ConnectStatus.UNKNOWN:
khenaidoob9203542018-09-17 22:56:37 -0400177 c_status.val = connect_status
178 else:
179 c_status.val = -1
khenaidoob9203542018-09-17 22:56:37 -0400180
khenaidoo43c82122018-11-22 18:38:28 -0500181 to_topic = createSubTopic(self.core_topic, device_id)
182 reply_topic = createSubTopic(self.listening_topic, device_id)
khenaidoob9203542018-09-17 22:56:37 -0400183 res = yield self.invoke(rpc="DeviceStateUpdate",
khenaidoo43c82122018-11-22 18:38:28 -0500184 to_topic=to_topic,
185 reply_topic=reply_topic,
khenaidoob9203542018-09-17 22:56:37 -0400186 device_id=id,
187 oper_status=o_status,
188 connect_status=c_status)
189 returnValue(res)
190
khenaidoo6fdf0ba2018-11-02 14:38:33 -0400191 @ContainerProxy.wrap_request(None)
khenaidoo4d4802d2018-10-04 21:59:49 -0400192 @inlineCallbacks
193 def children_state_update(self, device_id,
khenaidoo6fdf0ba2018-11-02 14:38:33 -0400194 oper_status=None,
195 connect_status=None):
khenaidoo4d4802d2018-10-04 21:59:49 -0400196 id = ID()
197 id.id = device_id
198 o_status = IntType()
khenaidoo6fdf0ba2018-11-02 14:38:33 -0400199 if oper_status or oper_status == OperStatus.UNKNOWN:
khenaidoo4d4802d2018-10-04 21:59:49 -0400200 o_status.val = oper_status
201 else:
202 o_status.val = -1
203 c_status = IntType()
khenaidoo6fdf0ba2018-11-02 14:38:33 -0400204 if connect_status or connect_status == ConnectStatus.UNKNOWN:
khenaidoo4d4802d2018-10-04 21:59:49 -0400205 c_status.val = connect_status
206 else:
207 c_status.val = -1
208
khenaidoo43c82122018-11-22 18:38:28 -0500209 to_topic = createSubTopic(self.core_topic, device_id)
210 reply_topic = createSubTopic(self.listening_topic, device_id)
khenaidoo4d4802d2018-10-04 21:59:49 -0400211 res = yield self.invoke(rpc="ChildrenStateUpdate",
khenaidoo43c82122018-11-22 18:38:28 -0500212 to_topic=to_topic,
213 reply_topic=reply_topic,
khenaidoo4d4802d2018-10-04 21:59:49 -0400214 device_id=id,
215 oper_status=o_status,
216 connect_status=c_status)
217 returnValue(res)
218
khenaidoo6fdf0ba2018-11-02 14:38:33 -0400219 @ContainerProxy.wrap_request(None)
khenaidoob9203542018-09-17 22:56:37 -0400220 @inlineCallbacks
khenaidoo92e62c52018-10-03 14:02:54 -0400221 def port_state_update(self,
222 device_id,
223 port_type,
224 port_no,
225 oper_status):
226 id = ID()
227 id.id = device_id
228 pt = IntType()
229 pt.val = port_type
230 pNo = IntType()
231 pNo.val = port_no
232 o_status = IntType()
233 o_status.val = oper_status
234
khenaidoo43c82122018-11-22 18:38:28 -0500235 to_topic = createSubTopic(self.core_topic, device_id)
236 reply_topic = createSubTopic(self.listening_topic, device_id)
khenaidoo92e62c52018-10-03 14:02:54 -0400237 res = yield self.invoke(rpc="PortStateUpdate",
khenaidoo43c82122018-11-22 18:38:28 -0500238 to_topic=to_topic,
239 reply_topic=reply_topic,
khenaidoo92e62c52018-10-03 14:02:54 -0400240 device_id=id,
241 port_type=pt,
242 port_no=pNo,
243 oper_status=o_status)
244 returnValue(res)
245
khenaidoo6fdf0ba2018-11-02 14:38:33 -0400246 @ContainerProxy.wrap_request(None)
khenaidoo92e62c52018-10-03 14:02:54 -0400247 @inlineCallbacks
khenaidoob9203542018-09-17 22:56:37 -0400248 def child_devices_state_update(self, parent_device_id,
249 oper_status=None,
khenaidoo92e62c52018-10-03 14:02:54 -0400250 connect_status=None):
khenaidoob9203542018-09-17 22:56:37 -0400251
252 id = ID()
253 id.id = parent_device_id
254 o_status = IntType()
khenaidoo6fdf0ba2018-11-02 14:38:33 -0400255 if oper_status or oper_status == OperStatus.UNKNOWN:
khenaidoob9203542018-09-17 22:56:37 -0400256 o_status.val = oper_status
257 else:
258 o_status.val = -1
259 c_status = IntType()
khenaidoo6fdf0ba2018-11-02 14:38:33 -0400260 if connect_status or connect_status == ConnectStatus.UNKNOWN:
khenaidoob9203542018-09-17 22:56:37 -0400261 c_status.val = connect_status
262 else:
263 c_status.val = -1
khenaidoob9203542018-09-17 22:56:37 -0400264
khenaidoo43c82122018-11-22 18:38:28 -0500265 to_topic = createSubTopic(self.core_topic, parent_device_id)
266 reply_topic = createSubTopic(self.listening_topic, parent_device_id)
khenaidoob9203542018-09-17 22:56:37 -0400267 res = yield self.invoke(rpc="child_devices_state_update",
khenaidoo43c82122018-11-22 18:38:28 -0500268 to_topic=to_topic,
269 reply_topic=reply_topic,
khenaidoob9203542018-09-17 22:56:37 -0400270 parent_device_id=id,
271 oper_status=o_status,
khenaidoo92e62c52018-10-03 14:02:54 -0400272 connect_status=c_status)
khenaidoob9203542018-09-17 22:56:37 -0400273 returnValue(res)
274
khenaidoob9203542018-09-17 22:56:37 -0400275 def child_devices_removed(parent_device_id):
276 raise NotImplementedError()
277
khenaidoo6fdf0ba2018-11-02 14:38:33 -0400278 @ContainerProxy.wrap_request(None)
khenaidoob9203542018-09-17 22:56:37 -0400279 @inlineCallbacks
280 def device_pm_config_update(self, device_pm_config, init=False):
281 log.debug("device_pm_config_update")
282 b = BoolType()
283 b.val = init
khenaidoo43c82122018-11-22 18:38:28 -0500284 to_topic = createSubTopic(self.core_topic, device_pm_config.id)
285 reply_topic = createSubTopic(self.listening_topic, device_pm_config.id)
khenaidoob9203542018-09-17 22:56:37 -0400286 res = yield self.invoke(rpc="DevicePMConfigUpdate",
khenaidoo43c82122018-11-22 18:38:28 -0500287 to_topic=to_topic,
288 reply_topic=reply_topic,
khenaidoofdbad6e2018-11-06 22:26:38 -0500289 device_pm_config=device_pm_config,
290 init=b)
khenaidoob9203542018-09-17 22:56:37 -0400291 returnValue(res)
292
khenaidoo6fdf0ba2018-11-02 14:38:33 -0400293 @ContainerProxy.wrap_request(None)
khenaidoob9203542018-09-17 22:56:37 -0400294 @inlineCallbacks
295 def port_created(self, device_id, port):
296 log.debug("port_created")
297 proto_id = ID()
298 proto_id.id = device_id
khenaidoo43c82122018-11-22 18:38:28 -0500299 to_topic = createSubTopic(self.core_topic, device_id)
300 reply_topic = createSubTopic(self.listening_topic, device_id)
khenaidoofdbad6e2018-11-06 22:26:38 -0500301 res = yield self.invoke(rpc="PortCreated",
khenaidoo43c82122018-11-22 18:38:28 -0500302 to_topic=to_topic,
303 reply_topic=reply_topic,
khenaidoofdbad6e2018-11-06 22:26:38 -0500304 device_id=proto_id,
khenaidoo6fdf0ba2018-11-02 14:38:33 -0400305 port=port)
khenaidoob9203542018-09-17 22:56:37 -0400306 returnValue(res)
307
khenaidoob9203542018-09-17 22:56:37 -0400308 def port_removed(device_id, port):
309 raise NotImplementedError()
310
311 def ports_enabled(device_id):
312 raise NotImplementedError()
313
314 def ports_disabled(device_id):
315 raise NotImplementedError()
316
317 def ports_oper_status_update(device_id, oper_status):
318 raise NotImplementedError()
319
320 def image_download_update(img_dnld):
321 raise NotImplementedError()
322
323 def image_download_deleted(img_dnld):
324 raise NotImplementedError()
325
khenaidoo7f9bb1a2018-11-29 17:15:01 -0500326 @ContainerProxy.wrap_request(None)
327 @inlineCallbacks
khenaidoofdbad6e2018-11-06 22:26:38 -0500328 def send_packet_in(self, device_id, port, packet):
khenaidoo7f9bb1a2018-11-29 17:15:01 -0500329 log.debug("send_packet_in", device_id=device_id)
khenaidoofdbad6e2018-11-06 22:26:38 -0500330 proto_id = ID()
331 proto_id.id = device_id
332 p = IntType()
333 p.val = port
334 pac = Packet()
335 pac.payload = packet
khenaidoo43c82122018-11-22 18:38:28 -0500336 to_topic = createSubTopic(self.core_topic, device_id)
337 reply_topic = createSubTopic(self.listening_topic, device_id)
khenaidoofdbad6e2018-11-06 22:26:38 -0500338 res = yield self.invoke(rpc="PacketIn",
khenaidoo43c82122018-11-22 18:38:28 -0500339 to_topic=to_topic,
340 reply_topic=reply_topic,
khenaidoofdbad6e2018-11-06 22:26:38 -0500341 device_id=proto_id,
342 port=p,
343 packet=pac)
344 returnValue(res)