blob: 0c78297430a6c4b9afad7e579eaac7f80dda51ac [file] [log] [blame]
Shad Ansari4dade922017-12-13 19:06:49 +00001#
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
17from enum import Enum
18from scapy.fields import ByteField, StrFixedLenField, ConditionalField, Field
19from scapy.fields import ShortField
20from scapy.packet import Packet
21
Shad Ansarib7ee63e2017-12-14 22:23:59 +000022from voltha_omci.omci.omci_defs import AttributeAccess
23from voltha_omci.omci.omci_entities import entity_id_to_class_map
Shad Ansari4dade922017-12-13 19:06:49 +000024
25
26log = structlog.get_logger()
27
28
29class OmciData(Field):
30
31 __slots__ = Field.__slots__ + ['_entity_class']
32
33 def __init__(self, name, entity_class="entity_class"):
34 Field.__init__(self, name=name, default=None, fmt='s')
35 self._entity_class = entity_class
36
37 def addfield(self, pkt, s, val):
38 class_id = getattr(pkt, self._entity_class)
39 entity_class = entity_id_to_class_map.get(class_id)
40 for attribute in entity_class.attributes:
41 if AttributeAccess.SetByCreate not in attribute._access:
42 continue
43 if attribute._fld.name == 'managed_entity_id':
44 continue
45 fld = attribute._fld
46 s = fld.addfield(pkt, s, val.get(fld.name, fld.default))
47 return s
48
49 def getfield(self, pkt, s):
50 """Extract an internal value from a string"""
51 class_id = getattr(pkt, self._entity_class)
52 entity_class = entity_id_to_class_map.get(class_id)
53 data = {}
54 for attribute in entity_class.attributes:
55 if AttributeAccess.SetByCreate not in attribute._access:
56 continue
57 if attribute._fld.name == 'managed_entity_id':
58 continue
59 fld = attribute._fld
60 s, value = fld.getfield(pkt, s)
61 data[fld.name] = value
62 return s, data
63
64
65class OmciMaskedData(Field):
66
67 __slots__ = Field.__slots__ + ['_entity_class', '_attributes_mask']
68
69 def __init__(self, name, entity_class="entity_class",
70 attributes_mask="attributes_mask"):
71 Field.__init__(self, name=name, default=None, fmt='s')
72 self._entity_class = entity_class
73 self._attributes_mask = attributes_mask
74
75 def addfield(self, pkt, s, val):
76 class_id = getattr(pkt, self._entity_class)
77 attribute_mask = getattr(pkt, self._attributes_mask)
78 entity_class = entity_id_to_class_map.get(class_id)
79 indices = entity_class.attribute_indices_from_mask(attribute_mask)
80 for index in indices:
81 fld = entity_class.attributes[index]._fld
82 s = fld.addfield(pkt, s, val[fld.name])
83 return s
84
85 def getfield(self, pkt, s):
86 """Extract an internal value from a string"""
87 class_id = getattr(pkt, self._entity_class)
88 attribute_mask = getattr(pkt, self._attributes_mask)
89 entity_class = entity_id_to_class_map[class_id]
90 indices = entity_class.attribute_indices_from_mask(attribute_mask)
91 data = {}
92 for index in indices:
93 try:
94 fld = entity_class.attributes[index]._fld
95 except IndexError, e:
96 log.error("Cannot decode attribute {} for entity class {}".format(
97 index, entity_class))
98 continue
99 try:
100 s, value = fld.getfield(pkt, s)
101 except Exception, e:
102 raise
103 data[fld.name] = value
104 return s, data
105
106
107class OmciMessage(Packet):
108 name = "OmciMessage"
109 message_id = None # OMCI message_type value, filled by derived classes
110 fields_desc = []
111
112
113class OmciCreate(OmciMessage):
114 name = "OmciCreate"
115 message_id = 0x44
116 fields_desc = [
117 ShortField("entity_class", None),
118 ShortField("entity_id", 0),
119 OmciData("data")
120 ]
121
122
123class OmciCreateResponse(OmciMessage):
124 name = "OmciCreateResponse"
125 message_id = 0x24
126 fields_desc = [
127 ShortField("entity_class", None),
128 ShortField("entity_id", None),
129 ByteField("success_code", 0),
130 ShortField("parameter_error_attributes_mask", None),
131 ]
132
133
134class OmciDelete(OmciMessage):
135 name = "OmciDelete"
136 message_id = 0x46
137 fields_desc = [
138 ShortField("entity_class", None),
139 ShortField("entity_id", None),
140 ]
141
142
143class OmciDeleteResponse(OmciMessage):
144 name = "OmciDeleteResponse"
145 message_id = 0x26
146 fields_desc = [
147 ShortField("entity_class", None),
148 ShortField("entity_id", None),
149 ByteField("success_code", 0),
150 ]
151
152
153class OmciSet(OmciMessage):
154 name = "OmciSet"
155 message_id = 0x48
156 fields_desc = [
157 ShortField("entity_class", None),
158 ShortField("entity_id", 0),
159 ShortField("attributes_mask", None),
160 OmciMaskedData("data")
161 ]
162
163
164class OmciSetResponse(OmciMessage):
165 name = "OmciSetResponse"
166 message_id = 0x28
167 fields_desc = [
168 ShortField("entity_class", None),
169 ShortField("entity_id", None),
170 ByteField("success_code", 0),
171 ShortField("unsupported_attributes_mask", None),
172 ShortField("failed_attributes_mask", None),
173 ]
174
175
176class OmciGet(OmciMessage):
177 name = "OmciGet"
178 message_id = 0x49
179 fields_desc = [
180 ShortField("entity_class", None),
181 ShortField("entity_id", 0),
182 ShortField("attributes_mask", None)
183 ]
184
185
186class OmciGetResponse(OmciMessage):
187 name = "OmciGetResponse"
188 message_id = 0x29
189 fields_desc = [
190 ShortField("entity_class", None),
191 ShortField("entity_id", 0),
192 ByteField("success_code", 0),
193 ShortField("attributes_mask", None),
194 ConditionalField(
195 OmciMaskedData("data"), lambda pkt: pkt.success_code == 0)
196 ]
197
198
199class OmciGetAllAlarms(OmciMessage):
200 name = "OmciGetAllAlarms"
201 message_id = 0x4b
202 fields_desc = [
203 ShortField("entity_class", 2), # Always 2 (ONT data)
204 ShortField("entity_id", 0), # Always 0 (ONT instance)
205 ByteField("alarm_retrieval_mode", 0) # 0 or 1
206 ]
207
208
209class OmciGetAllAlarmsResponse(OmciMessage):
210 name = "OmciGetAllAlarmsResponse"
211 message_id = 0x2b
212 fields_desc = [
213 ShortField("entity_class", 2), # Always 2 (ONT data)
214 ShortField("entity_id", 0),
215 ShortField("number_of_commands", None)
216 ]
217
218
219class OmciGetAllAlarmsNext(OmciMessage):
220 name = "OmciGetAllAlarmsNext"
221 message_id = 0x4c
222 fields_desc = [
223 ShortField("entity_class", 2), # Always 2 (ONT data)
224 ShortField("entity_id", 0),
225 ShortField("command_sequence_number", None)
226 ]
227
228
229class OmciGetAllAlarmsNextResponse(OmciMessage):
230 name = "OmciGetAllAlarmsNextResponse"
231 message_id = 0x2c
232 fields_desc = [
233 ShortField("entity_class", 2), # Always 2 (ONT data)
234 ShortField("entity_id", 0),
235 ShortField("alarmed_entity_class", None),
236 ShortField("alarmed_entity_id", 0),
237 StrFixedLenField("alarm_bit_map", None, 27) # TODO better type?
238 ]
239
240
241class OmciMibUpload(OmciMessage):
242 name = "OmciMibUpload"
243 message_id = 0x4d
244 fields_desc = [
245 ShortField("entity_class", 2), # Always 2 (ONT data)
246 ShortField("entity_id", 0),
247 ]
248
249
250class OmciMibUploadResponse(OmciMessage):
251 name = "OmciMibUploadResponse"
252 message_id = 0x2d
253 fields_desc = [
254 ShortField("entity_class", 2), # Always 2 (ONT data)
255 ShortField("entity_id", 0),
256 ShortField("number_of_commands", None)
257 ]
258
259
260class OmciMibUploadNext(OmciMessage):
261 name = "OmciMibUploadNext"
262 message_id = 0x4e
263 fields_desc = [
264 ShortField("entity_class", 2), # Always 2 (ONT data)
265 ShortField("entity_id", 0),
266 ShortField("command_sequence_number", None)
267 ]
268
269
270class OmciMibUploadNextResponse(OmciMessage):
271 name = "OmciMibUploadNextResponse"
272 message_id = 0x2e
273 fields_desc = [
274 ShortField("entity_class", 2), # Always 2 (ONT data)
275 ShortField("entity_id", 0),
276 ShortField("object_entity_class", None),
277 ShortField("object_entity_id", 0),
278 ShortField("object_attributes_mask", None),
279 OmciMaskedData("object_data", entity_class='object_entity_class',
280 attributes_mask='object_attributes_mask')
281 ]
282
283
284class OmciMibReset(OmciMessage):
285 name = "OmciMibReset"
286 message_id = 0x4f
287 fields_desc = [
288 ShortField("entity_class", None),
289 ShortField("entity_id", 0)
290 ]
291
292
293class OmciMibResetResponse(OmciMessage):
294 name = "OmciMibResetResponse"
295 message_id = 0x2f
296 fields_desc = [
297 ShortField("entity_class", None),
298 ShortField("entity_id", 0),
299 ByteField("success_code", 0)
300 ]