blob: da7bff5b5a6ca36b0522f987bc8baa2cec218d18 [file] [log] [blame]
Chip Boling32aab302019-01-23 10:50:18 -06001#
2# Copyright 2018 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#
16from task import Task
17from twisted.internet import reactor
18from twisted.internet.defer import inlineCallbacks, failure, returnValue
19from voltha.extensions.omci.omci_defs import ReasonCodes, EntityOperations
20from voltha.extensions.omci.omci_me import MEFrame
21from voltha.extensions.omci.omci_frame import OmciFrame
22from voltha.extensions.omci.omci_messages import OmciCreate, OmciSet, OmciDelete
23from voltha.extensions.omci.omci_entities import EntityClass
24
25RC = ReasonCodes
26OP = EntityOperations
27
28
29class ModifyException(Exception):
30 pass
31
32
33class OmciModifyRequest(Task):
34 """
35 OpenOMCI Generic Create, Set, or Delete Frame support Task.
36
37 This task allows an ONU to send a Create, Set, or Delete request from any point in their
38 code while properly using the OMCI-CC channel. Direct access to the OMCI-CC object
39 to send requests by an ONU is highly discouraged.
40 """
41 task_priority = 128
42 name = "ONU OMCI Modify Task"
43
44 def __init__(self, omci_agent, device_id, frame, priority=task_priority, exclusive=False):
45 """
46 Class initialization
47
48 :param omci_agent: (OmciAdapterAgent) OMCI Adapter agent
49 :param device_id: (str) ONU Device ID
50 :param frame: (OmciFrame) Frame to send
51 :param priority: (int) OpenOMCI Task priority (0..255) 255 is the highest
52 :param exclusive: (bool) True if this GET request Task exclusively own the
53 OMCI-CC while running. Default: False
54 """
55 super(OmciModifyRequest, self).__init__(OmciModifyRequest.name,
56 omci_agent,
57 device_id,
58 priority=priority,
59 exclusive=exclusive)
60 self._device = omci_agent.get_device(device_id)
61 self._frame = frame
62 self._results = None
63 self._local_deferred = None
64
65 # Validate message type
66 self._msg_type = frame.fields['message_type']
67 if self._msg_type not in (OmciCreate.message_id, OmciSet.message_id, OmciDelete.message_id):
68 raise TypeError('Invalid Message type: {}, must be Create, Set, or Delete'.
69 format(self._msg_type))
70
71 def cancel_deferred(self):
72 super(OmciModifyRequest, self).cancel_deferred()
73
74 d, self._local_deferred = self._local_deferred, None
75 try:
76 if d is not None and not d.called:
77 d.cancel()
78 except:
79 pass
80
81 @property
82 def success_code(self):
83 """
84 Return the OMCI success/reason code for the Get Response.
85 """
86 if self._results is None:
87 return None
88
89 return self._results.fields['omci_message'].fields['success_code']
90
91 @property
92 def illegal_attributes_mask(self):
93 """
94 For Create & Set requests, a failure may indicate that one or more
95 attributes have an illegal value. This property returns any illegal
96 attributes
97
98 :return: None if not a create/set request, otherwise the attribute mask
99 of illegal attributes
100 """
101 if self._results is None:
102 return None
103
104 omci_msg = self._results.fields['omci_message'].fields
105
106 if self._msg_type == OmciCreate.message_id:
107 if self.success_code != RC.ParameterError:
108 return 0
109 return omci_msg['parameter_error_attributes_mask']
110
111 elif self._msg_type == OmciSet.message_id:
112 if self.success_code != RC.AttributeFailure:
113 return 0
114 return omci_msg['failed_attributes_mask']
115
116 return None
117
118 @property
119 def unsupported_attributes_mask(self):
120 """
121 For Set requests, a failure may indicate that one or more attributes
122 are not supported by this ONU. This property returns any those unsupported attributes
123
124 :return: None if not a set request, otherwise the attribute mask of any illegal
125 parameters
126 """
127 if self._msg_type != OmciSet.message_id or self._results is None:
128 return None
129
130 if self.success_code != RC.AttributeFailure:
131 return 0
132
133 return self._results.fields['omci_message'].fields['unsupported_attributes_mask']
134
135 @property
136 def raw_results(self):
137 """
138 Return the raw Response OMCIFrame
139 """
140 return self._results
141
142 def start(self):
143 """
144 Start MIB Capabilities task
145 """
146 super(OmciModifyRequest, self).start()
147 self._local_deferred = reactor.callLater(0, self.perform_omci)
148
149 @inlineCallbacks
150 def perform_omci(self):
151 """
152 Perform the request
153 """
154 self.log.debug('perform-request')
155
156 try:
157 self.strobe_watchdog()
158 self._results = yield self._device.omci_cc.send(self._frame)
159
160 status = self._results.fields['omci_message'].fields['success_code']
161 self.log.debug('response-status', status=status)
162
163 # Success?
164 if status in (RC.Success.value, RC.InstanceExists):
165 self.deferred.callback(self)
166 else:
167 raise ModifyException('Failed with status {}'.format(status))
168
169 except Exception as e:
170 self.log.exception('perform-modify', e=e)
171 self.deferred.errback(failure.Failure(e))