blob: 37f04a5289d5896c4a47db2712ce5c8a1c2e139a [file] [log] [blame]
Chip Boling6e27b352020-02-14 09:10:01 -06001/*
2 * Copyright (c) 2018 - present. Boling Consulting Solutions (bcsw.net)
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 * http://www.apache.org/licenses/LICENSE-2.0
8 * Unless required by applicable law or agreed to in writing, software
9 * distributed under the License is distributed on an "AS IS" BASIS,
10 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 * See the License for the specific language governing permissions and
12 * limitations under the License.
David K. Bainbridgeadf422d2021-04-09 16:06:41 +000013 */
14/*
Chip Boling6e27b352020-02-14 09:10:01 -060015 * NOTE: This file was generated, manual edits will be overwritten!
16 *
17 * Generated by 'goCodeGenerator.py':
Andrea Campanella7167ebb2020-02-24 09:56:38 +010018 * https://github.com/opencord/omci-lib-go/OMCI-parser/README.md
Chip Boling6e27b352020-02-14 09:10:01 -060019 */
20
21package omci
22
23import (
24 "errors"
25 "fmt"
Chip Boling6e27b352020-02-14 09:10:01 -060026 "github.com/deckarep/golang-set"
27 "github.com/google/gopacket"
David K. Bainbridgeadf422d2021-04-09 16:06:41 +000028 me "github.com/opencord/omci-lib-go/generated"
Chip Boling6e27b352020-02-14 09:10:01 -060029 "time"
30)
31
32var encoderMap map[MessageType]func(*me.ManagedEntity, options) (gopacket.SerializableLayer, error)
33
34func init() {
35 encoderMap = make(map[MessageType]func(*me.ManagedEntity, options) (gopacket.SerializableLayer, error))
36
37 encoderMap[CreateRequestType] = CreateRequestFrame
38 encoderMap[DeleteRequestType] = DeleteRequestFrame
39 encoderMap[SetRequestType] = SetRequestFrame
40 encoderMap[GetRequestType] = GetRequestFrame
41 encoderMap[GetAllAlarmsRequestType] = GetAllAlarmsRequestFrame
42 encoderMap[GetAllAlarmsNextRequestType] = GetAllAlarmsNextRequestFrame
43 encoderMap[MibUploadRequestType] = MibUploadRequestFrame
44 encoderMap[MibUploadNextRequestType] = MibUploadNextRequestFrame
45 encoderMap[MibResetRequestType] = MibResetRequestFrame
46 encoderMap[TestRequestType] = TestRequestFrame
47 encoderMap[StartSoftwareDownloadRequestType] = StartSoftwareDownloadRequestFrame
48 encoderMap[DownloadSectionRequestType] = DownloadSectionRequestFrame
49 encoderMap[EndSoftwareDownloadRequestType] = EndSoftwareDownloadRequestFrame
50 encoderMap[ActivateSoftwareRequestType] = ActivateSoftwareRequestFrame
51 encoderMap[CommitSoftwareRequestType] = CommitSoftwareRequestFrame
52 encoderMap[SynchronizeTimeRequestType] = SynchronizeTimeRequestFrame
53 encoderMap[RebootRequestType] = RebootRequestFrame
54 encoderMap[GetNextRequestType] = GetNextRequestFrame
55 encoderMap[GetCurrentDataRequestType] = GetCurrentDataRequestFrame
56 encoderMap[SetTableRequestType] = SetTableRequestFrame
57 encoderMap[CreateResponseType] = CreateResponseFrame
58 encoderMap[DeleteResponseType] = DeleteResponseFrame
59 encoderMap[SetResponseType] = SetResponseFrame
60 encoderMap[GetResponseType] = GetResponseFrame
61 encoderMap[GetAllAlarmsResponseType] = GetAllAlarmsResponseFrame
62 encoderMap[GetAllAlarmsNextResponseType] = GetAllAlarmsNextResponseFrame
63 encoderMap[MibUploadResponseType] = MibUploadResponseFrame
64 encoderMap[MibUploadNextResponseType] = MibUploadNextResponseFrame
65 encoderMap[MibResetResponseType] = MibResetResponseFrame
66 encoderMap[TestResponseType] = TestResponseFrame
67 encoderMap[StartSoftwareDownloadResponseType] = StartSoftwareDownloadResponseFrame
68 encoderMap[DownloadSectionResponseType] = DownloadSectionResponseFrame
69 encoderMap[EndSoftwareDownloadResponseType] = EndSoftwareDownloadResponseFrame
70 encoderMap[ActivateSoftwareResponseType] = ActivateSoftwareResponseFrame
71 encoderMap[CommitSoftwareResponseType] = CommitSoftwareResponseFrame
72 encoderMap[SynchronizeTimeResponseType] = SynchronizeTimeResponseFrame
73 encoderMap[RebootResponseType] = RebootResponseFrame
74 encoderMap[GetNextResponseType] = GetNextResponseFrame
75 encoderMap[GetCurrentDataResponseType] = GetCurrentDataResponseFrame
76 encoderMap[SetTableResponseType] = SetTableResponseFrame
77 encoderMap[AlarmNotificationType] = AlarmNotificationFrame
78 encoderMap[AttributeValueChangeType] = AttributeValueChangeFrame
79 encoderMap[TestResultType] = TestResultFrame
80}
81
82type options struct {
83 frameFormat DeviceIdent
84 failIfTruncated bool
85 attributeMask uint16
86 result me.Results // Common for many responses
87 attrExecutionMask uint16 // Create Response Only if results == 3 or Set Response only if results == 0
88 unsupportedMask uint16 // Set Response only if results == 9
89 sequenceNumberCountOrSize uint16 // For get-next request frames and for frames that return number of commands or length
90 transactionID uint16 // OMCI TID
91 mode uint8 // Get All Alarms retrieval mode
92 alarm AlarmOptions // Alarm related frames
93 software SoftwareOptions // Software image related frames
94 payload interface{} // ME or list of MEs, alarm bitmap, timestamp, ...
95 addDefaults bool // Add missing SetByCreate attributes for Create Requests
96}
97
98var defaultFrameOptions = options{
99 frameFormat: BaselineIdent,
100 failIfTruncated: false,
101 attributeMask: 0xFFFF,
102 result: me.Success,
103 attrExecutionMask: 0,
104 unsupportedMask: 0,
105 sequenceNumberCountOrSize: 0,
106 transactionID: 0,
107 mode: 0,
108 software: defaultSoftwareOptions,
109 alarm: defaultAlarmOptions,
110 payload: nil,
111 addDefaults: false,
112}
113
114// FrameOption sets options such as frame format, etc.
115type FrameOption func(*options)
116
117// FrameFormat determines determines the OMCI message format used on the fiber.
118// The default value is BaselineIdent
119func FrameFormat(ff DeviceIdent) FrameOption {
120 return func(o *options) {
121 o.frameFormat = ff
122 }
123}
124
125// FailIfTruncated determines whether a request to encode a frame that does
126// not have enough room for all requested options should fail and return an
127// error.
128//
129// If set to 'false', the behaviour depends on the message type/operation
130// requested. The table below provides more information:
131//
132// Request Type Behavour
133// ------------------------------------------------------------------------
134// CreateRequest A single CreateRequest struct is always returned as the
135// CreateRequest message does not have an attributes Mask
136// field and a Baseline OMCI message is large enough to
137// support all Set-By-Create attributes.
138//
139// GetResponse If multiple OMCI response frames are needed to return
140// all requested attributes, only the attributes that can
141// fit will be returned and the FailedAttributeMask field
142// set to the attributes that could not be returned
143//
144// If this is an ME with an attribute that is a table, the
145// first GetResponse struct will return the size of the
146// attribute and the following GetNextResponse structs will
147// contain the attribute data. The ONU application is
148// responsible for stashing these extra struct(s) away in
149// anticipation of possible GetNext Requests occurring for
150// the attribute. See the discussion on Table attributes
151// in the GetResponse section of ITU G.988 for more
152// information.
153//
154// If set to 'true', no struct(s) are returned and an error is provided.
155//
156// The default value is 'false'
157func FailIfTruncated(f bool) FrameOption {
158 return func(o *options) {
159 o.failIfTruncated = f
160 }
161}
162
163// attributeMask determines the attributes to encode into the frame.
164// The default value is 0xFFFF which specifies all available attributes
165// in the frame
166func AttributeMask(m uint16) FrameOption {
167 return func(o *options) {
168 o.attributeMask = m
169 }
170}
171
172// AttributeExecutionMask is used by the Create and Set Response frames to indicate
173// attributes that failed to be created/set.
174func AttributeExecutionMask(m uint16) FrameOption {
175 return func(o *options) {
176 o.attrExecutionMask = m
177 }
178}
179
180// UnsupportedAttributeMask is used by the Set Response frames to indicate
181// attributes are not supported on this ONU
182func UnsupportedAttributeMask(m uint16) FrameOption {
183 return func(o *options) {
184 o.unsupportedMask = m
185 }
186}
187
188// Result is used to set returned results in responses
189// that have that field
190func Result(r me.Results) FrameOption {
191 return func(o *options) {
192 o.result = r
193 }
194}
195
196// SequenceNumberCountOrSize is used by the GetNext and MibUploadGetNext request frames and for
197// frames that return number of commands or length such as Get (table attribute) or
198// MibUpload/GetAllAlarms/...
199func SequenceNumberCountOrSize(m uint16) FrameOption {
200 return func(o *options) {
201 o.sequenceNumberCountOrSize = m
202 }
203}
204
205// TransactionID is to specify the TID in the OMCI header. The default is
206// zero which requires the caller to set it to the appropriate value if this
207// is not an autonomous ONU notification frame
208func TransactionID(tid uint16) FrameOption {
209 return func(o *options) {
210 o.transactionID = tid
211 }
212}
213
214// RetrievalMode is to specify the the Alarm Retrieval Mode in a GetAllAlarms Request
215func RetrievalMode(m uint8) FrameOption {
216 return func(o *options) {
217 o.mode = m
218 }
219}
220
221// SuccessResult is to specify the the SuccessResult for a SynchronizeTime Response
222func SuccessResult(m uint8) FrameOption {
223 return func(o *options) {
224 o.mode = m
225 }
226}
227
228// RebootCondition is to specify the the Reboot Condition for a ONU Reboot request
229func RebootCondition(m uint8) FrameOption {
230 return func(o *options) {
231 o.mode = m
232 }
233}
234
235// Alarm is used to specify a collection of options related to Alarm notifications
236func Alarm(ao AlarmOptions) FrameOption {
237 return func(o *options) {
238 o.alarm = ao
239 }
240}
241
242// Software is used to specify a collection of options related to Software image
243// manipulation
244func Software(so SoftwareOptions) FrameOption {
245 return func(o *options) {
246 o.software = so
247 }
248}
249
250// Payload is used to specify ME payload options that are not simple types. This
251// include the ME (list of MEs) to encode into a GetNextMibUpload response, the
252// alarm bitmap for alarm relates responses/notifications, alarm bitmaps, and
253// for specifying the download section data when performing Software Download.
254func Payload(p interface{}) FrameOption {
255 return func(o *options) {
256 o.payload = p
257 }
258}
259
260// AddDefaults is used to specify that if a SetByCreate attribute is not
261// specified in the list of attributes for a Create Request, use the attribute
262// defined default
263func AddDefaults(add bool) FrameOption {
264 return func(o *options) {
265 o.addDefaults = add
266 }
267}
268
269// Alarm related frames have a wide variety of settable values. Placing them
270// in a separate struct is mainly to keep the base options simple
271type AlarmOptions struct {
272 AlarmClassID me.ClassID
273 AlarmInstance uint16
274 AlarmBitmap []byte // Should be up to 58 octets
275}
276
277var defaultAlarmOptions = AlarmOptions{
278 AlarmClassID: 0,
279 AlarmInstance: 0,
280 AlarmBitmap: nil,
281}
282
283// Software related frames have a wide variety of settable values. Placing them
284// in a separate struct is mainly to keep the base options simple
285type SoftwareOptions struct {
286 WindowSize uint8 // Window size - 1
287 ImageSize uint32
288 CircuitPacks []uint16 // slot (upper 8 bits) and instance (lower 8 bits)
Matteo Scandolo6eaa9a72021-03-10 09:18:38 -0800289 Results []DownloadResults
Chip Boling6e27b352020-02-14 09:10:01 -0600290}
291
292var defaultSoftwareOptions = SoftwareOptions{
293 WindowSize: 0,
294 ImageSize: 0,
295 CircuitPacks: nil,
296 Results: nil,
297}
298
299// EncodeFrame will encode the Managed Entity specific protocol struct and an
300// OMCILayer struct. This struct can be provided to the gopacket.SerializeLayers()
301// function to be serialized into a buffer for transmission.
302func EncodeFrame(m *me.ManagedEntity, messageType MessageType, opt ...FrameOption) (*OMCI, gopacket.SerializableLayer, error) {
303 // Check for message type support
304 msgType := me.MsgType(messageType & me.MsgTypeMask)
305 meDefinition := m.GetManagedEntityDefinition()
306
307 if !me.SupportsMsgType(meDefinition, msgType) {
308 msg := fmt.Sprintf("managed entity %v does not support %v Message-Type",
309 meDefinition.GetName(), msgType)
310 return nil, nil, errors.New(msg)
311 }
312 // Decode options
313 opts := defaultFrameOptions
314 for _, o := range opt {
315 o(&opts)
316 }
317 // TODO: If AttributesMask option passed in, check for deprecated options. Allow encoding option
318 // that will ignore deprecated option. Add additional in the get and set meframe_test,go
319 // test functions to test this. Also have it test attribute name(s) to see if the attribute
320 // is deprecated. The OMCI-Parser now supports detection of deprecated attributes and
321 // provides that to the code-generator (and currently available in generated golang code).
322 // Note: Transaction ID should be set before frame serialization
323 omci := &OMCI{
324 TransactionID: opts.transactionID,
325 MessageType: messageType,
326 DeviceIdentifier: opts.frameFormat,
327 }
328 var meInfo gopacket.SerializableLayer
329 var err error
330
331 if encoder, ok := encoderMap[messageType]; ok {
332 meInfo, err = encoder(m, opts)
333 } else {
334 err = fmt.Errorf("message-type: %v/%#x is not supported", messageType, messageType)
335 }
336 if err != nil {
337 return nil, nil, err
338 }
339 return omci, meInfo, err
340}
341
342// For most all create methods below, error checking for valid masks, attribute
343// values, and other fields is left to when the frame is actually serialized.
344
345func checkAttributeMask(m *me.ManagedEntity, mask uint16) (uint16, error) {
346 if mask == defaultFrameOptions.attributeMask {
347 // Scale back to just what is allowed
348 return m.GetAllowedAttributeMask(), nil
349 }
350 if mask&m.GetManagedEntityDefinition().GetAllowedAttributeMask() != mask {
351 return 0, errors.New("invalid attribute mask")
352 }
353 return mask & m.GetManagedEntityDefinition().GetAllowedAttributeMask(), nil
354}
355
356// return the maximum space that can be used by attributes
357func maxPacketAvailable(m *me.ManagedEntity, opt options) uint {
358 if opt.frameFormat == BaselineIdent {
359 // OMCI Header - 4 octets
360 // Class ID/Instance ID - 4 octets
361 // Length field - 4 octets
362 // MIC - 4 octets
363 return MaxBaselineLength - 16
364 }
365 // OMCI Header - 4 octets
366 // Class ID/Instance ID - 4 octets
367 // Length field - 4 octets
368 // MIC - 4 octets
369 return MaxExtendedLength - 16
370}
371
372func calculateAttributeMask(m *me.ManagedEntity, requestedMask uint16) (uint16, error) {
373 attrDefs := m.GetAttributeDefinitions()
374 var entityIDName string
375 if entry, ok := attrDefs[0]; ok {
376 entityIDName = entry.GetName()
377 } else {
378 panic("unexpected error") // All attribute definition maps have an entity ID
379 }
380 attributeNames := make([]interface{}, 0)
381 for attrName := range m.GetAttributeValueMap() {
382 if attrName == entityIDName {
383 continue // No mask for EntityID
384 }
385 attributeNames = append(attributeNames, attrName)
386 }
387 calculatedMask, err := me.GetAttributesBitmap(attrDefs, mapset.NewSetWith(attributeNames...))
388
389 if err != nil {
390 return 0, err
391 }
392 return calculatedMask & requestedMask, nil
393}
394
395// GenFrame is a helper function to make tests a little easier to read.
396// For a real application, use the .../omci/generated/class.go 'New'
397// functions to create your Managed Entity and then use it to call the
398// EncodeFrame method.
399func GenFrame(meInstance *me.ManagedEntity, messageType MessageType, options ...FrameOption) ([]byte, error) {
400 omciLayer, msgLayer, err := EncodeFrame(meInstance, messageType, options...)
401 if err != nil {
402 return nil, err
403 }
404 // Serialize the frame and send it
405 var serializeOptions gopacket.SerializeOptions
406 serializeOptions.FixLengths = true
407
408 buffer := gopacket.NewSerializeBuffer()
409 err = gopacket.SerializeLayers(buffer, serializeOptions, omciLayer, msgLayer)
410 if err != nil {
411 return nil, err
412 }
413 return buffer.Bytes(), nil
414}
415
416func CreateRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -0500417 if opt.frameFormat == ExtendedIdent {
418 return nil, errors.New("Extended message set for this message type is not supported")
419 }
Chip Boling6e27b352020-02-14 09:10:01 -0600420 // NOTE: The OMCI parser does not extract the default values of set-by-create attributes
421 // and are the zero 'default' (or nil) at this time. For this reason, make sure
422 // you specify all non-zero default values and pass them in appropriate
423 meLayer := &CreateRequest{
424 MeBasePacket: MeBasePacket{
425 EntityClass: m.GetClassID(),
426 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -0500427 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -0600428 },
429 Attributes: m.GetAttributeValueMap(),
430 }
431 // Add any missing SetByCreate options if requested
432 if opt.addDefaults {
433 if attrDefs, err := me.GetAttributesDefinitions(m.GetClassID()); err.StatusCode() == me.Success {
434 for index, attr := range attrDefs {
435 if me.SupportsAttributeAccess(attr, me.SetByCreate) {
436 if index == 0 {
437 continue // Skip Entity ID, if it is SetByCreate, they should always specify it
438 }
439 if _, found := meLayer.Attributes[attr.GetName()]; !found {
440 meLayer.Attributes[attr.GetName()] = attr.DefValue
441 }
442 }
443 }
444 }
445 }
446 return meLayer, nil
447}
448
449func CreateResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -0500450 if opt.frameFormat == ExtendedIdent {
451 return nil, errors.New("Extended message set for this message type is not supported")
452 }
Chip Boling6e27b352020-02-14 09:10:01 -0600453 meLayer := &CreateResponse{
454 MeBasePacket: MeBasePacket{
455 EntityClass: m.GetClassID(),
456 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -0500457 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -0600458 },
459 Result: opt.result,
460 }
461 if meLayer.Result == me.ParameterError {
462 meLayer.AttributeExecutionMask = opt.attrExecutionMask
463 }
464 return meLayer, nil
465}
466
467func DeleteRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -0500468 if opt.frameFormat == ExtendedIdent {
469 return nil, errors.New("Extended message set for this message type is not supported")
470 }
Chip Boling6e27b352020-02-14 09:10:01 -0600471 meLayer := &DeleteRequest{
472 MeBasePacket: MeBasePacket{
473 EntityClass: m.GetClassID(),
474 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -0500475 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -0600476 },
477 }
478 return meLayer, nil
479}
480
481func DeleteResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -0500482 if opt.frameFormat == ExtendedIdent {
483 return nil, errors.New("Extended message set for this message type is not supported")
484 }
Chip Boling6e27b352020-02-14 09:10:01 -0600485 meLayer := &DeleteResponse{
486 MeBasePacket: MeBasePacket{
487 EntityClass: m.GetClassID(),
488 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -0500489 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -0600490 },
491 Result: opt.result,
492 }
493 return meLayer, nil
494}
495
496func SetRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
497 mask, err := checkAttributeMask(m, opt.attributeMask)
498 if err != nil {
499 return nil, err
500 }
501 mask, err = calculateAttributeMask(m, mask)
502 if err != nil {
503 return nil, err
504 }
505 meDefinition := m.GetManagedEntityDefinition()
506 attrDefs := meDefinition.GetAttributeDefinitions()
507 attrMap := m.GetAttributeValueMap()
508
509 // Get payload space available
510 maxPayload := maxPacketAvailable(m, opt)
511 payloadAvailable := int(maxPayload) - 2 // Less attribute mask
Chip Boling157c9b92021-04-21 09:58:36 -0500512 if opt.frameFormat == ExtendedIdent {
513 return nil, errors.New("Extended message set for this message type is not supported")
514 // payloadAvailable -= 2 // Less length
515 }
Chip Boling6e27b352020-02-14 09:10:01 -0600516 meLayer := &SetRequest{
517 MeBasePacket: MeBasePacket{
518 EntityClass: m.GetClassID(),
519 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -0500520 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -0600521 },
522 AttributeMask: 0,
523 Attributes: make(me.AttributeValueMap),
524 }
525 for mask != 0 {
526 // Iterate down the attributes (Attribute 0 is the ManagedEntity ID)
527 var attrIndex uint
528 for attrIndex = 1; attrIndex <= 16; attrIndex++ {
529 // Is this attribute requested
530 if mask&(1<<(16-attrIndex)) != 0 {
531 // Get definitions since we need the name
532 attrDef, ok := attrDefs[attrIndex]
533 if !ok {
534 msg := fmt.Sprintf("Unexpected error, index %v not valued for ME %v",
535 attrIndex, meDefinition.GetName())
536 return nil, errors.New(msg)
537 }
538 var attrValue interface{}
539 attrValue, ok = attrMap[attrDef.Name]
540 if !ok {
541 msg := fmt.Sprintf("Unexpected error, attribute %v not provided in ME %v: %v",
542 attrDef.GetName(), meDefinition.GetName(), m)
543 return nil, errors.New(msg)
544 }
545 // Is space available?
546 if attrDef.Size <= payloadAvailable {
547 // Mark bit handled
548 mask &= ^attrDef.Mask
549 meLayer.AttributeMask |= attrDef.Mask
550 meLayer.Attributes[attrDef.Name] = attrValue
551 payloadAvailable -= attrDef.Size
552 } else {
553 // TODO: Should we set truncate?
554 msg := fmt.Sprintf("out-of-space. Cannot fit attribute %v into SetRequest message",
555 attrDef.GetName())
556 return nil, me.NewMessageTruncatedError(msg)
557 }
558 }
559 }
560 }
561 if err == nil && meLayer.AttributeMask == 0 {
562 // TODO: Is a set request with no attributes valid?
563 return nil, errors.New("no attributes encoded for SetRequest")
564 }
565 return meLayer, nil
566}
567
568func SetResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -0500569 if opt.frameFormat == ExtendedIdent {
570 return nil, errors.New("Extended message set for this message type is not supported")
571 }
Chip Boling6e27b352020-02-14 09:10:01 -0600572 meLayer := &SetResponse{
573 MeBasePacket: MeBasePacket{
574 EntityClass: m.GetClassID(),
575 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -0500576 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -0600577 },
578 Result: opt.result,
579 }
580 if meLayer.Result == me.AttributeFailure {
581 meLayer.UnsupportedAttributeMask = opt.unsupportedMask
582 meLayer.FailedAttributeMask = opt.attrExecutionMask
583 }
584 return meLayer, nil
585}
586
587func GetRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
588 // Given mask sent in (could be default of 0xFFFF) get what is allowable.
589 // This will be all allowed if 0xFFFF is passed in, or a subset if a fixed
590 // number of items.
591 maxMask, err := checkAttributeMask(m, opt.attributeMask)
592 if err != nil {
593 return nil, err
594 }
595 // Now scan attributes and reduce mask to only those requested
596 var mask uint16
597 mask, err = calculateAttributeMask(m, maxMask)
598 if err != nil {
599 return nil, err
600 }
601 if mask == 0 {
602 // TODO: Is a Get request with no attributes valid?
603 return nil, errors.New("no attributes requested for GetRequest")
604 }
605 meLayer := &GetRequest{
606 MeBasePacket: MeBasePacket{
607 EntityClass: m.GetClassID(),
608 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -0500609 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -0600610 },
611 AttributeMask: mask,
612 }
613 return meLayer, nil
614}
615
616func GetResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
617 mask, err := checkAttributeMask(m, opt.attributeMask)
618 if err != nil {
619 return nil, err
620 }
621 mask, err = calculateAttributeMask(m, mask)
622 if err != nil {
623 return nil, err
624 }
625 meLayer := &GetResponse{
626 MeBasePacket: MeBasePacket{
627 EntityClass: m.GetClassID(),
628 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -0500629 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -0600630 },
631 Result: opt.result,
632 AttributeMask: 0,
633 Attributes: make(me.AttributeValueMap),
634 }
635 if meLayer.Result == me.AttributeFailure {
636 meLayer.UnsupportedAttributeMask = opt.unsupportedMask
637 meLayer.FailedAttributeMask = opt.attrExecutionMask
638 }
639 // Encode whatever we can
640 if meLayer.Result == me.Success || meLayer.Result == me.AttributeFailure {
641 // Encode results
642 // Get payload space available
643 maxPayload := maxPacketAvailable(m, opt)
644 payloadAvailable := int(maxPayload) - 2 - 4 // Less attribute mask and attribute error encoding
645 meDefinition := m.GetManagedEntityDefinition()
646 attrDefs := meDefinition.GetAttributeDefinitions()
647 attrMap := m.GetAttributeValueMap()
648
649 if mask != 0 {
650 // Iterate down the attributes (Attribute 0 is the ManagedEntity ID)
651 var attrIndex uint
652 for attrIndex = 1; attrIndex <= 16; attrIndex++ {
653 // Is this attribute requested
654 if mask&(1<<(16-attrIndex)) != 0 {
655 // Get definitions since we need the name
656 attrDef, ok := attrDefs[attrIndex]
657 if !ok {
658 msg := fmt.Sprintf("Unexpected error, index %v not valued for ME %v",
659 attrIndex, meDefinition.GetName())
660 return nil, errors.New(msg)
661 }
662 var attrValue interface{}
663 attrValue, ok = attrMap[attrDef.Name]
664 if !ok {
665 msg := fmt.Sprintf("Unexpected error, attribute %v not provided in ME %v: %v",
666 attrDef.GetName(), meDefinition.GetName(), m)
667 return nil, errors.New(msg)
668 }
669 // Is space available?
670 if attrDef.Size <= payloadAvailable {
671 // Mark bit handled
672 mask &= ^attrDef.Mask
673 meLayer.AttributeMask |= attrDef.Mask
674 meLayer.Attributes[attrDef.Name] = attrValue
675 payloadAvailable -= attrDef.Size
676
677 } else if opt.failIfTruncated {
678 // TODO: Should we set truncate?
679 msg := fmt.Sprintf("out-of-space. Cannot fit attribute %v into GetResponse message",
680 attrDef.GetName())
681 return nil, me.NewMessageTruncatedError(msg)
682 } else {
683 // Add to existing 'failed' mask and update result
684 meLayer.FailedAttributeMask |= attrDef.Mask
685 meLayer.Result = me.AttributeFailure
686 }
687 }
688 }
689 }
690 }
691 return meLayer, nil
692}
693
694func GetAllAlarmsRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -0500695 if opt.frameFormat == ExtendedIdent {
696 return nil, errors.New("Extended message set for this message type is not supported")
697 }
Chip Boling6e27b352020-02-14 09:10:01 -0600698 // Common for all MEs
699 meLayer := &GetAllAlarmsRequest{
700 MeBasePacket: MeBasePacket{
701 EntityClass: m.GetClassID(),
702 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -0500703 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -0600704 },
705 AlarmRetrievalMode: opt.mode,
706 }
707 return meLayer, nil
708}
709
710func GetAllAlarmsResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -0500711 if opt.frameFormat == ExtendedIdent {
712 return nil, errors.New("Extended message set for this message type is not supported")
713 }
Chip Boling6e27b352020-02-14 09:10:01 -0600714 // Common for all MEs
715 meLayer := &GetAllAlarmsResponse{
716 MeBasePacket: MeBasePacket{
717 EntityClass: m.GetClassID(),
718 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -0500719 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -0600720 },
721 NumberOfCommands: opt.sequenceNumberCountOrSize,
722 }
723 return meLayer, nil
724}
725
726func GetAllAlarmsNextRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -0500727 if opt.frameFormat == ExtendedIdent {
728 return nil, errors.New("Extended message set for this message type is not supported")
729 }
Chip Boling6e27b352020-02-14 09:10:01 -0600730 // Common for all MEs
731 meLayer := &GetAllAlarmsNextRequest{
732 MeBasePacket: MeBasePacket{
733 EntityClass: m.GetClassID(),
734 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -0500735 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -0600736 },
737 CommandSequenceNumber: opt.sequenceNumberCountOrSize,
738 }
739 return meLayer, nil
740}
741
742func GetAllAlarmsNextResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -0500743 if opt.frameFormat == ExtendedIdent {
744 return nil, errors.New("Extended message set for this message type is not supported")
745 }
Chip Boling6e27b352020-02-14 09:10:01 -0600746 // Common for all MEs
747 meLayer := &GetAllAlarmsNextResponse{
748 MeBasePacket: MeBasePacket{
749 EntityClass: m.GetClassID(),
750 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -0500751 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -0600752 },
753 AlarmEntityClass: opt.alarm.AlarmClassID,
754 AlarmEntityInstance: opt.alarm.AlarmInstance,
755 }
756 if len(opt.alarm.AlarmBitmap) > 28 {
757 return nil, errors.New("invalid Alarm Bitmap Size. Must be [0..27]")
758 }
759 for octet := 0; octet < len(opt.alarm.AlarmBitmap); octet++ {
760 meLayer.AlarmBitMap[octet] = opt.alarm.AlarmBitmap[octet]
761 }
762 for octet := len(opt.alarm.AlarmBitmap); octet < 28; octet++ {
763 meLayer.AlarmBitMap[octet] = 0
764 }
765 return meLayer, nil
766}
767
768func MibUploadRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -0500769 if opt.frameFormat == ExtendedIdent {
770 return nil, errors.New("Extended message set for this message type is not supported")
771 }
Chip Boling6e27b352020-02-14 09:10:01 -0600772 // Common for all MEs
773 meLayer := &MibUploadRequest{
774 MeBasePacket: MeBasePacket{
775 EntityClass: m.GetClassID(),
776 EntityInstance: 0,
Chip Boling157c9b92021-04-21 09:58:36 -0500777 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -0600778 },
779 }
780 return meLayer, nil
781}
782
783func MibUploadResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -0500784 if opt.frameFormat == ExtendedIdent {
785 return nil, errors.New("Extended message set for this message type is not supported")
786 }
Chip Boling6e27b352020-02-14 09:10:01 -0600787 // Common for all MEs
788 meLayer := &MibUploadResponse{
789 MeBasePacket: MeBasePacket{
790 EntityClass: m.GetClassID(),
791 EntityInstance: 0,
Chip Boling157c9b92021-04-21 09:58:36 -0500792 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -0600793 },
794 NumberOfCommands: opt.sequenceNumberCountOrSize,
795 }
796 return meLayer, nil
797}
798
799func MibUploadNextRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -0500800 if opt.frameFormat == ExtendedIdent {
801 return nil, errors.New("Extended message set for this message type is not supported")
802 }
Chip Boling6e27b352020-02-14 09:10:01 -0600803 // Common for all MEs
804 meLayer := &MibUploadNextRequest{
805 MeBasePacket: MeBasePacket{
806 EntityClass: m.GetClassID(),
807 EntityInstance: 0,
Chip Boling157c9b92021-04-21 09:58:36 -0500808 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -0600809 },
810 CommandSequenceNumber: opt.sequenceNumberCountOrSize,
811 }
812 return meLayer, nil
813}
814
815func MibUploadNextResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -0500816 if opt.frameFormat == ExtendedIdent {
817 return nil, errors.New("Extended message set for this message type is not supported")
818 }
Chip Boling6e27b352020-02-14 09:10:01 -0600819 // Common for all MEs
820 meLayer := &MibUploadNextResponse{
821 MeBasePacket: MeBasePacket{
822 EntityClass: m.GetClassID(),
823 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -0500824 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -0600825 },
826 }
827 if opt.payload == nil {
828 // Shortcut used to specify the request sequence number is out of range, encode
829 // a ME instance with class ID of zero to specify this per ITU G.988
830 meDef := me.ManagedEntityDefinition{
831 Name: "InvalidSequenceNumberManagedEntity",
832 ClassID: me.ClassID(0),
833 MessageTypes: nil,
834 AttributeDefinitions: make(me.AttributeDefinitionMap),
835 }
836 opt.payload, _ = me.NewManagedEntity(meDef)
837 }
838 if _, ok := opt.payload.(*[]me.ManagedEntity); ok {
839 if opt.frameFormat == BaselineIdent {
840 return nil, errors.New("invalid payload for Baseline message")
841 }
842 // TODO: List of MEs. valid for extended messages only
843 } else if managedEntity, ok := opt.payload.(*me.ManagedEntity); ok {
844 // Single ME
845 meLayer.ReportedME = *managedEntity
846 } else {
847 return nil, errors.New("invalid payload for MibUploadNextResponse frame")
848 }
849 return meLayer, nil
850}
851
852func MibResetRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -0500853 if opt.frameFormat == ExtendedIdent {
854 return nil, errors.New("Extended message set for this message type is not supported")
855 }
Chip Boling6e27b352020-02-14 09:10:01 -0600856 // Common for all MEs
857 meLayer := &MibResetRequest{
858 MeBasePacket: MeBasePacket{
859 EntityClass: m.GetClassID(),
860 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -0500861 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -0600862 },
863 }
864 return meLayer, nil
865}
866
867func MibResetResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -0500868 if opt.frameFormat == ExtendedIdent {
869 return nil, errors.New("Extended message set for this message type is not supported")
870 }
Chip Boling6e27b352020-02-14 09:10:01 -0600871 // Common for all MEs
872 meLayer := &MibResetResponse{
873 MeBasePacket: MeBasePacket{
874 EntityClass: m.GetClassID(),
875 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -0500876 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -0600877 },
878 Result: opt.result,
879 }
880 return meLayer, nil
881}
882
883func AlarmNotificationFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -0500884 if opt.frameFormat == ExtendedIdent {
885 return nil, errors.New("Extended message set for this message type is not supported")
886 }
Chip Boling6e27b352020-02-14 09:10:01 -0600887 mask, err := checkAttributeMask(m, opt.attributeMask)
888 if err != nil {
889 return nil, err
890 }
891 // Common for all MEs
892 meLayer := &AlarmNotificationMsg{
893 MeBasePacket: MeBasePacket{
894 EntityClass: m.GetClassID(),
895 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -0500896 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -0600897 },
898 }
899 // Get payload space available
900 maxPayload := maxPacketAvailable(m, opt)
901 payloadAvailable := int(maxPayload) - 1 // Less alarm sequence number
902
903 // TODO: Lots of work to do
904 fmt.Println(mask, maxPayload, payloadAvailable)
905
906 return meLayer, errors.New("todo: Not implemented")
907}
908
909func AttributeValueChangeFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -0500910 if opt.frameFormat == ExtendedIdent {
911 return nil, errors.New("Extended message set for this message type is not supported")
912 }
Chip Boling6e27b352020-02-14 09:10:01 -0600913 mask, err := checkAttributeMask(m, opt.attributeMask)
914 if err != nil {
915 return nil, err
916 }
917 // Common for all MEs
918 meLayer := &AttributeValueChangeMsg{
919 MeBasePacket: MeBasePacket{
920 EntityClass: m.GetClassID(),
921 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -0500922 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -0600923 },
924 AttributeMask: 0,
925 Attributes: make(me.AttributeValueMap),
926 }
927 // Get payload space available
928 maxPayload := maxPacketAvailable(m, opt)
929 payloadAvailable := int(maxPayload) - 2 // Less attribute mask
930
931 // TODO: Lots of work to do
932
933 fmt.Println(mask, maxPayload, payloadAvailable)
934 return meLayer, errors.New("todo: Not implemented")
935}
936
937func TestRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -0500938 if opt.frameFormat == ExtendedIdent {
939 return nil, errors.New("Extended message set for this message type is not supported")
940 }
Chip Boling6e27b352020-02-14 09:10:01 -0600941 mask, err := checkAttributeMask(m, opt.attributeMask)
942 if err != nil {
943 return nil, err
944 }
945 // Common for all MEs
946 meLayer := &TestRequest{
947 MeBasePacket: MeBasePacket{
948 EntityClass: m.GetClassID(),
949 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -0500950 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -0600951 },
952 }
953 // Get payload space available
954 maxPayload := maxPacketAvailable(m, opt)
955
956 // TODO: Lots of work to do
957
958 fmt.Println(mask, maxPayload)
959 return meLayer, errors.New("todo: Not implemented")
960}
961
962func TestResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -0500963 if opt.frameFormat == ExtendedIdent {
964 return nil, errors.New("Extended message set for this message type is not supported")
965 }
Chip Boling6e27b352020-02-14 09:10:01 -0600966 mask, err := checkAttributeMask(m, opt.attributeMask)
967 if err != nil {
968 return nil, err
969 }
970 // Common for all MEs
971 meLayer := &TestResponse{
972 MeBasePacket: MeBasePacket{
973 EntityClass: m.GetClassID(),
974 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -0500975 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -0600976 },
977 }
978 // Get payload space available
979 maxPayload := maxPacketAvailable(m, opt)
980
981 // TODO: Lots of work to do
982
983 fmt.Println(mask, maxPayload)
984 return meLayer, errors.New("todo: Not implemented")
985}
986
987func StartSoftwareDownloadRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -0500988 if opt.frameFormat == ExtendedIdent {
989 return nil, errors.New("Extended message set for this message type is not supported")
990 }
Chip Boling6e27b352020-02-14 09:10:01 -0600991 // Common for all MEs
992 meLayer := &StartSoftwareDownloadRequest{
993 MeBasePacket: MeBasePacket{
994 EntityClass: m.GetClassID(),
995 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -0500996 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -0600997 },
998 WindowSize: opt.software.WindowSize,
999 ImageSize: opt.software.ImageSize,
1000 NumberOfCircuitPacks: byte(len(opt.software.CircuitPacks)),
1001 CircuitPacks: opt.software.CircuitPacks,
1002 }
1003 // TODO: Add length check to insure we do not exceed maximum packet size
1004 // payloadAvailable := int(maxPacketAvailable(m, opt))
1005 payloadAvailable := 2
1006 sizeNeeded := 1
1007 if sizeNeeded > payloadAvailable {
1008 // TODO: Should we set truncate?
1009 msg := "out-of-space. Cannot fit Circuit Pack instances into Start Software Download Request message"
1010 return nil, me.NewMessageTruncatedError(msg)
1011 }
1012 return meLayer, nil
1013}
1014
1015func StartSoftwareDownloadResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -05001016 if opt.frameFormat == ExtendedIdent {
1017 return nil, errors.New("Extended message set for this message type is not supported")
1018 }
Chip Boling6e27b352020-02-14 09:10:01 -06001019 // Common for all MEs
1020 meLayer := &StartSoftwareDownloadResponse{
1021 MeBasePacket: MeBasePacket{
1022 EntityClass: m.GetClassID(),
1023 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -05001024 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -06001025 },
1026 WindowSize: opt.software.WindowSize,
1027 NumberOfInstances: byte(len(opt.software.CircuitPacks)),
1028 MeResults: opt.software.Results,
1029 }
1030 // TODO: Add length check to insure we do not exceed maximum packet size
1031 // payloadAvailable := int(maxPacketAvailable(m, opt))
1032 payloadAvailable := 2
1033 sizeNeeded := 1
1034 if sizeNeeded > payloadAvailable {
1035 // TODO: Should we set truncate?
1036 msg := "out-of-space. Cannot fit Results into Start Software Download Response message"
1037 return nil, me.NewMessageTruncatedError(msg)
1038 }
1039 return meLayer, nil
1040}
1041
1042func DownloadSectionRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -05001043 if opt.frameFormat == ExtendedIdent {
1044 return nil, errors.New("Extended message set for this message type is not supported")
1045 }
Chip Boling6e27b352020-02-14 09:10:01 -06001046 mask, err := checkAttributeMask(m, opt.attributeMask)
1047 if err != nil {
1048 return nil, err
1049 }
1050 // Common for all MEs
1051 meLayer := &DownloadSectionRequest{
1052 MeBasePacket: MeBasePacket{
1053 EntityClass: m.GetClassID(),
1054 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -05001055 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -06001056 },
1057 }
1058 // Get payload space available
1059 maxPayload := maxPacketAvailable(m, opt)
1060
1061 // TODO: Lots of work to do
1062
1063 fmt.Println(mask, maxPayload)
1064 return meLayer, errors.New("todo: Not implemented")
1065}
1066
1067func DownloadSectionResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -05001068 if opt.frameFormat == ExtendedIdent {
1069 return nil, errors.New("Extended message set for this message type is not supported")
1070 }
Chip Boling6e27b352020-02-14 09:10:01 -06001071 mask, err := checkAttributeMask(m, opt.attributeMask)
1072 if err != nil {
1073 return nil, err
1074 }
1075 // Common for all MEs
1076 meLayer := &DownloadSectionResponse{
1077 MeBasePacket: MeBasePacket{
1078 EntityClass: m.GetClassID(),
1079 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -05001080 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -06001081 },
1082 }
1083 // Get payload space available
1084 maxPayload := maxPacketAvailable(m, opt)
1085
1086 // TODO: Lots of work to do
1087
1088 fmt.Println(mask, maxPayload)
1089 return meLayer, errors.New("todo: Not implemented")
1090}
1091
1092func EndSoftwareDownloadRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -05001093 if opt.frameFormat == ExtendedIdent {
1094 return nil, errors.New("Extended message set for this message type is not supported")
1095 }
Chip Boling6e27b352020-02-14 09:10:01 -06001096 mask, err := checkAttributeMask(m, opt.attributeMask)
1097 if err != nil {
1098 return nil, err
1099 }
1100 // Common for all MEs
1101 meLayer := &EndSoftwareDownloadRequest{
1102 MeBasePacket: MeBasePacket{
1103 EntityClass: m.GetClassID(),
1104 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -05001105 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -06001106 },
1107 }
1108 // Get payload space available
1109 maxPayload := maxPacketAvailable(m, opt)
1110
1111 // TODO: Lots of work to do
1112
1113 fmt.Println(mask, maxPayload)
1114 return meLayer, errors.New("todo: Not implemented")
1115}
1116
1117func EndSoftwareDownloadResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -05001118 if opt.frameFormat == ExtendedIdent {
1119 return nil, errors.New("Extended message set for this message type is not supported")
1120 }
Chip Boling6e27b352020-02-14 09:10:01 -06001121 mask, err := checkAttributeMask(m, opt.attributeMask)
1122 if err != nil {
1123 return nil, err
1124 }
1125 // Common for all MEs
1126 meLayer := &EndSoftwareDownloadResponse{
1127 MeBasePacket: MeBasePacket{
1128 EntityClass: m.GetClassID(),
1129 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -05001130 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -06001131 },
1132 }
1133 // Get payload space available
1134 maxPayload := maxPacketAvailable(m, opt)
1135
1136 // TODO: Lots of work to do
1137
1138 fmt.Println(mask, maxPayload)
1139 return meLayer, errors.New("todo: Not implemented")
1140}
1141
1142func ActivateSoftwareRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -05001143 if opt.frameFormat == ExtendedIdent {
1144 return nil, errors.New("Extended message set for this message type is not supported")
1145 }
Chip Boling6e27b352020-02-14 09:10:01 -06001146 mask, err := checkAttributeMask(m, opt.attributeMask)
1147 if err != nil {
1148 return nil, err
1149 }
1150 // Common for all MEs
1151 meLayer := &ActivateSoftwareRequest{
1152 MeBasePacket: MeBasePacket{
1153 EntityClass: m.GetClassID(),
1154 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -05001155 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -06001156 },
1157 }
1158 // Get payload space available
1159 maxPayload := maxPacketAvailable(m, opt)
1160
1161 // TODO: Lots of work to do
1162
1163 fmt.Println(mask, maxPayload)
1164 return meLayer, errors.New("todo: Not implemented")
1165}
1166
1167func ActivateSoftwareResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -05001168 if opt.frameFormat == ExtendedIdent {
1169 return nil, errors.New("Extended message set for this message type is not supported")
1170 }
Chip Boling6e27b352020-02-14 09:10:01 -06001171 mask, err := checkAttributeMask(m, opt.attributeMask)
1172 if err != nil {
1173 return nil, err
1174 }
1175 // Common for all MEs
1176 meLayer := &ActivateSoftwareResponse{
1177 MeBasePacket: MeBasePacket{
1178 EntityClass: m.GetClassID(),
1179 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -05001180 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -06001181 },
1182 }
1183 // Get payload space available
1184 maxPayload := maxPacketAvailable(m, opt)
1185
1186 // TODO: Lots of work to do
1187
1188 fmt.Println(mask, maxPayload)
1189 return meLayer, errors.New("todo: Not implemented")
1190}
1191
1192func CommitSoftwareRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -05001193 if opt.frameFormat == ExtendedIdent {
1194 return nil, errors.New("Extended message set for this message type is not supported")
1195 }
Chip Boling6e27b352020-02-14 09:10:01 -06001196 mask, err := checkAttributeMask(m, opt.attributeMask)
1197 if err != nil {
1198 return nil, err
1199 }
1200 // Common for all MEs
1201 meLayer := &CommitSoftwareRequest{
1202 MeBasePacket: MeBasePacket{
1203 EntityClass: m.GetClassID(),
1204 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -05001205 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -06001206 },
1207 }
1208 // Get payload space available
1209 maxPayload := maxPacketAvailable(m, opt)
1210
1211 // TODO: Lots of work to do
1212
1213 fmt.Println(mask, maxPayload)
1214 return meLayer, errors.New("todo: Not implemented")
1215}
1216
1217func CommitSoftwareResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -05001218 if opt.frameFormat == ExtendedIdent {
1219 return nil, errors.New("Extended message set for this message type is not supported")
1220 }
Chip Boling6e27b352020-02-14 09:10:01 -06001221 mask, err := checkAttributeMask(m, opt.attributeMask)
1222 if err != nil {
1223 return nil, err
1224 }
1225 // Common for all MEs
1226 meLayer := &CommitSoftwareResponse{
1227 MeBasePacket: MeBasePacket{
1228 EntityClass: m.GetClassID(),
1229 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -05001230 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -06001231 },
1232 }
1233 // Get payload space available
1234 maxPayload := maxPacketAvailable(m, opt)
1235
1236 // TODO: Lots of work to do
1237
1238 fmt.Println(mask, maxPayload)
1239 return meLayer, errors.New("todo: Not implemented")
1240}
1241
1242func SynchronizeTimeRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -05001243 if opt.frameFormat == ExtendedIdent {
1244 return nil, errors.New("Extended message set for this message type is not supported")
1245 }
Chip Boling6e27b352020-02-14 09:10:01 -06001246 // Common for all MEs
1247 meLayer := &SynchronizeTimeRequest{
1248 MeBasePacket: MeBasePacket{
1249 EntityClass: m.GetClassID(),
1250 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -05001251 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -06001252 },
1253 }
1254 // Decode payload option. If nil, no timestamp provided
1255 if timestamp, ok := opt.payload.(int64); ok {
1256 tm := time.Unix(timestamp, 0)
1257 meLayer.Year = uint16(tm.UTC().Year())
1258 meLayer.Month = uint8(tm.UTC().Month())
1259 meLayer.Day = uint8(tm.UTC().Day())
1260 meLayer.Hour = uint8(tm.UTC().Hour())
1261 meLayer.Minute = uint8(tm.UTC().Minute())
1262 meLayer.Second = uint8(tm.UTC().Second())
1263 }
1264 return meLayer, nil
1265}
1266
1267func SynchronizeTimeResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -05001268 if opt.frameFormat == ExtendedIdent {
1269 return nil, errors.New("Extended message set for this message type is not supported")
1270 }
Chip Boling6e27b352020-02-14 09:10:01 -06001271 // Common for all MEs
1272 meLayer := &SynchronizeTimeResponse{
1273 MeBasePacket: MeBasePacket{
1274 EntityClass: m.GetClassID(),
1275 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -05001276 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -06001277 },
1278 Result: opt.result,
1279 SuccessResults: opt.mode,
1280 }
1281 return meLayer, nil
1282}
1283
1284func RebootRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -05001285 if opt.frameFormat == ExtendedIdent {
1286 return nil, errors.New("Extended message set for this message type is not supported")
1287 }
Chip Boling6e27b352020-02-14 09:10:01 -06001288 // Common for all MEs
1289 meLayer := &RebootRequest{
1290 MeBasePacket: MeBasePacket{
1291 EntityClass: m.GetClassID(),
1292 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -05001293 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -06001294 },
1295 RebootCondition: opt.mode,
1296 }
1297 return meLayer, nil
1298}
1299
1300func RebootResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -05001301 if opt.frameFormat == ExtendedIdent {
1302 return nil, errors.New("Extended message set for this message type is not supported")
1303 }
Chip Boling6e27b352020-02-14 09:10:01 -06001304 // Common for all MEs
1305 meLayer := &RebootResponse{
1306 MeBasePacket: MeBasePacket{
1307 EntityClass: m.GetClassID(),
1308 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -05001309 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -06001310 },
1311 Result: opt.result,
1312 }
1313 return meLayer, nil
1314}
1315
1316func GetNextRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -05001317 if opt.frameFormat == ExtendedIdent {
1318 return nil, errors.New("Extended message set for this message type is not supported")
1319 }
Chip Boling6e27b352020-02-14 09:10:01 -06001320 // Validate attribute mask
1321 mask, err := checkAttributeMask(m, opt.attributeMask)
1322 if err != nil {
1323 return nil, err
1324 }
1325 // Now scan attributes and reduce mask to only those requested
1326 mask, err = calculateAttributeMask(m, mask)
1327 if err != nil {
1328 return nil, err
1329 }
1330 if mask == 0 {
1331 return nil, errors.New("no attributes requested for GetNextRequest")
1332 }
1333 // TODO: If more than one attribute or the attribute requested is not a table attribute, return an error
1334 // Common for all MEs
1335 meLayer := &GetNextRequest{
1336 MeBasePacket: MeBasePacket{
1337 EntityClass: m.GetClassID(),
1338 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -05001339 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -06001340 },
1341 AttributeMask: mask,
1342 SequenceNumber: opt.sequenceNumberCountOrSize,
1343 }
1344 return meLayer, nil
1345}
1346
1347func GetNextResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -05001348 if opt.frameFormat == ExtendedIdent {
1349 return nil, errors.New("Extended message set for this message type is not supported")
1350 }
Chip Boling6e27b352020-02-14 09:10:01 -06001351 // Validate attribute mask
1352 mask, err := checkAttributeMask(m, opt.attributeMask)
1353 if err != nil {
1354 return nil, err
1355 }
1356 mask, err = calculateAttributeMask(m, mask)
1357 if err != nil {
1358 return nil, err
1359 }
1360 //
1361 // Common for all MEs
1362 meLayer := &GetNextResponse{
1363 MeBasePacket: MeBasePacket{
1364 EntityClass: m.GetClassID(),
1365 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -05001366 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -06001367 },
1368 Result: opt.result,
1369 AttributeMask: 0,
1370 Attributes: make(me.AttributeValueMap),
1371 }
1372 if meLayer.Result == me.Success {
1373 // Get payload space available
1374 maxPayload := maxPacketAvailable(m, opt)
1375 payloadAvailable := int(maxPayload) - 3 // Less results and attribute mask
1376 meDefinition := m.GetManagedEntityDefinition()
1377 attrDefs := meDefinition.GetAttributeDefinitions()
1378 attrMap := m.GetAttributeValueMap()
1379
1380 if mask == 0 {
1381 return nil, errors.New("no attributes requested for GetNextResponse")
1382 }
1383 // TODO: If more than one attribute or the attribute requested is not a table attribute, return an error
1384 // Iterate down the attributes (Attribute 0 is the ManagedEntity ID)
1385 var attrIndex uint
1386 for attrIndex = 1; attrIndex <= 16; attrIndex++ {
1387 // Is this attribute requested
1388 if mask&(1<<(16-attrIndex)) != 0 {
1389 // Get definitions since we need the name
1390 attrDef, ok := attrDefs[attrIndex]
1391 if !ok {
1392 msg := fmt.Sprintf("Unexpected error, index %v not valued for ME %v",
1393 attrIndex, meDefinition.GetName())
1394 return nil, errors.New(msg)
1395 }
1396 var attrValue interface{}
1397 attrValue, ok = attrMap[attrDef.Name]
1398 if !ok || attrValue == nil {
1399 msg := fmt.Sprintf("Unexpected error, attribute %v not provided in ME %v: %v",
1400 attrDef.GetName(), meDefinition.GetName(), m)
1401 return nil, errors.New(msg)
1402 }
1403 // Is space available?
1404 if attrDef.Size <= payloadAvailable {
1405 // Mark bit handled
1406 mask &= ^attrDef.Mask
1407 meLayer.AttributeMask |= attrDef.Mask
1408 meLayer.Attributes[attrDef.Name] = attrValue
1409 payloadAvailable -= attrDef.Size
1410 } else {
1411 // TODO: Should we set truncate?
1412 msg := fmt.Sprintf("out-of-space. Cannot fit attribute %v into GetNextResponse message",
1413 attrDef.GetName())
1414 return nil, me.NewMessageTruncatedError(msg)
1415 }
1416 }
1417 }
1418 }
1419 return meLayer, nil
1420}
1421
1422func TestResultFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -05001423 if opt.frameFormat == ExtendedIdent {
1424 return nil, errors.New("Extended message set for this message type is not supported")
1425 }
Chip Boling6e27b352020-02-14 09:10:01 -06001426 mask, err := checkAttributeMask(m, opt.attributeMask)
1427 if err != nil {
1428 return nil, err
1429 }
1430 // Common for all MEs
1431 meLayer := &TestResultMsg{
1432 MeBasePacket: MeBasePacket{
1433 EntityClass: m.GetClassID(),
1434 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -05001435 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -06001436 },
1437 }
1438 // Get payload space available
1439 maxPayload := maxPacketAvailable(m, opt)
1440
1441 // TODO: Lots of work to do
1442
1443 fmt.Println(mask, maxPayload)
1444 return meLayer, errors.New("todo: Not implemented")
1445}
1446
1447func GetCurrentDataRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -05001448 if opt.frameFormat == ExtendedIdent {
1449 return nil, errors.New("Extended message set for this message type is not supported")
1450 }
Chip Boling6e27b352020-02-14 09:10:01 -06001451 mask, err := checkAttributeMask(m, opt.attributeMask)
1452 if err != nil {
1453 return nil, err
1454 }
1455 // Common for all MEs
1456 meLayer := &GetCurrentDataRequest{
1457 MeBasePacket: MeBasePacket{
1458 EntityClass: m.GetClassID(),
1459 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -05001460 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -06001461 },
1462 }
1463 // Get payload space available
1464 maxPayload := maxPacketAvailable(m, opt)
1465
1466 // TODO: Lots of work to do
1467
1468 fmt.Println(mask, maxPayload)
1469 return meLayer, errors.New("todo: Not implemented")
1470}
1471
1472func GetCurrentDataResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -05001473 if opt.frameFormat == ExtendedIdent {
1474 return nil, errors.New("Extended message set for this message type is not supported")
1475 }
Chip Boling6e27b352020-02-14 09:10:01 -06001476 mask, err := checkAttributeMask(m, opt.attributeMask)
1477 if err != nil {
1478 return nil, err
1479 }
1480 // Common for all MEs
1481 meLayer := &GetCurrentDataResponse{
1482 MeBasePacket: MeBasePacket{
1483 EntityClass: m.GetClassID(),
1484 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -05001485 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -06001486 },
1487 }
1488 // Get payload space available
1489 maxPayload := maxPacketAvailable(m, opt)
1490
1491 // TODO: Lots of work to do
1492
1493 fmt.Println(mask, maxPayload)
1494 return meLayer, errors.New("todo: Not implemented")
1495}
1496
1497func SetTableRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
1498 if opt.frameFormat != ExtendedIdent {
1499 return nil, errors.New("SetTable message type only supported with Extended OMCI Messaging")
1500 }
Chip Boling157c9b92021-04-21 09:58:36 -05001501 if opt.frameFormat == ExtendedIdent {
1502 return nil, errors.New("Extended message set for this message type is not supported")
1503 }
Chip Boling6e27b352020-02-14 09:10:01 -06001504 mask, err := checkAttributeMask(m, opt.attributeMask)
1505 if err != nil {
1506 return nil, err
1507 }
1508 // Common for all MEs
1509 meLayer := &SetTableRequest{
1510 MeBasePacket: MeBasePacket{
1511 EntityClass: m.GetClassID(),
1512 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -05001513 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -06001514 },
1515 }
1516 // Get payload space available
1517 maxPayload := maxPacketAvailable(m, opt)
1518
1519 // TODO: Lots of work to do
1520
1521 fmt.Println(mask, maxPayload)
1522 return meLayer, errors.New("todo: Not implemented")
1523}
1524
1525func SetTableResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
1526 if opt.frameFormat != ExtendedIdent {
Chip Boling157c9b92021-04-21 09:58:36 -05001527 return nil, errors.New("SetTable message type only supported with Extended OMCI Message Set")
1528 }
1529 if opt.frameFormat == ExtendedIdent {
1530 return nil, errors.New("Extended message set for this message type is not supported")
Chip Boling6e27b352020-02-14 09:10:01 -06001531 }
1532 mask, err := checkAttributeMask(m, opt.attributeMask)
1533 if err != nil {
1534 return nil, err
1535 }
1536 // Common for all MEs
1537 meLayer := &SetTableResponse{
1538 MeBasePacket: MeBasePacket{
1539 EntityClass: m.GetClassID(),
1540 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -05001541 Extended: true,
Chip Boling6e27b352020-02-14 09:10:01 -06001542 },
1543 }
1544 // Get payload space available
1545 maxPayload := maxPacketAvailable(m, opt)
1546
1547 // TODO: Lots of work to do
1548
1549 fmt.Println(mask, maxPayload)
1550 return meLayer, errors.New("todo: Not implemented")
1551}