blob: 472db3181d29c167567d989b569059c2c41f6e6d [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
Chip Bolingd8637b02021-04-29 08:36:38 -050046 //encoderMap[TestRequestType] = TestRequestFrame
Chip Boling6e27b352020-02-14 09:10:01 -060047 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
Chip Bolingd8637b02021-04-29 08:36:38 -050066 //encoderMap[TestResponseType] = TestResponseFrame
Chip Boling6e27b352020-02-14 09:10:01 -060067 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
Chip Bolingd8637b02021-04-29 08:36:38 -050079 //encoderMap[TestResultType] = TestResultFrame
Chip Boling6e27b352020-02-14 09:10:01 -060080}
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 {
Chip Boling00a30d22021-05-04 13:31:52 -0500286 WindowSize uint8 // Window size - 1
287 SectionNumber uint8 // [0..Window size - 1]
288 ImageSize uint32
289 CircuitPacks []uint16 // slot (upper 8 bits) and instance (lower 8 bits)
290 Results []DownloadResults
291 Data []byte
Chip Boling6e27b352020-02-14 09:10:01 -0600292}
293
294var defaultSoftwareOptions = SoftwareOptions{
Chip Boling00a30d22021-05-04 13:31:52 -0500295 WindowSize: 0,
296 SectionNumber: 0,
297 ImageSize: 0,
298 CircuitPacks: nil,
299 Results: nil,
300 Data: nil,
Chip Boling6e27b352020-02-14 09:10:01 -0600301}
302
303// EncodeFrame will encode the Managed Entity specific protocol struct and an
304// OMCILayer struct. This struct can be provided to the gopacket.SerializeLayers()
305// function to be serialized into a buffer for transmission.
306func EncodeFrame(m *me.ManagedEntity, messageType MessageType, opt ...FrameOption) (*OMCI, gopacket.SerializableLayer, error) {
307 // Check for message type support
308 msgType := me.MsgType(messageType & me.MsgTypeMask)
309 meDefinition := m.GetManagedEntityDefinition()
310
311 if !me.SupportsMsgType(meDefinition, msgType) {
312 msg := fmt.Sprintf("managed entity %v does not support %v Message-Type",
313 meDefinition.GetName(), msgType)
314 return nil, nil, errors.New(msg)
315 }
316 // Decode options
317 opts := defaultFrameOptions
318 for _, o := range opt {
319 o(&opts)
320 }
321 // TODO: If AttributesMask option passed in, check for deprecated options. Allow encoding option
322 // that will ignore deprecated option. Add additional in the get and set meframe_test,go
323 // test functions to test this. Also have it test attribute name(s) to see if the attribute
324 // is deprecated. The OMCI-Parser now supports detection of deprecated attributes and
325 // provides that to the code-generator (and currently available in generated golang code).
326 // Note: Transaction ID should be set before frame serialization
327 omci := &OMCI{
328 TransactionID: opts.transactionID,
329 MessageType: messageType,
330 DeviceIdentifier: opts.frameFormat,
331 }
332 var meInfo gopacket.SerializableLayer
333 var err error
334
335 if encoder, ok := encoderMap[messageType]; ok {
336 meInfo, err = encoder(m, opts)
337 } else {
338 err = fmt.Errorf("message-type: %v/%#x is not supported", messageType, messageType)
339 }
340 if err != nil {
341 return nil, nil, err
342 }
343 return omci, meInfo, err
344}
345
346// For most all create methods below, error checking for valid masks, attribute
347// values, and other fields is left to when the frame is actually serialized.
348
349func checkAttributeMask(m *me.ManagedEntity, mask uint16) (uint16, error) {
350 if mask == defaultFrameOptions.attributeMask {
351 // Scale back to just what is allowed
352 return m.GetAllowedAttributeMask(), nil
353 }
354 if mask&m.GetManagedEntityDefinition().GetAllowedAttributeMask() != mask {
355 return 0, errors.New("invalid attribute mask")
356 }
357 return mask & m.GetManagedEntityDefinition().GetAllowedAttributeMask(), nil
358}
359
360// return the maximum space that can be used by attributes
361func maxPacketAvailable(m *me.ManagedEntity, opt options) uint {
362 if opt.frameFormat == BaselineIdent {
363 // OMCI Header - 4 octets
364 // Class ID/Instance ID - 4 octets
365 // Length field - 4 octets
366 // MIC - 4 octets
367 return MaxBaselineLength - 16
368 }
369 // OMCI Header - 4 octets
370 // Class ID/Instance ID - 4 octets
Chip Boling00a30d22021-05-04 13:31:52 -0500371 // Length field - 2 octets
Chip Boling6e27b352020-02-14 09:10:01 -0600372 // MIC - 4 octets
Chip Boling00a30d22021-05-04 13:31:52 -0500373 return MaxExtendedLength - 14
Chip Boling6e27b352020-02-14 09:10:01 -0600374}
375
376func calculateAttributeMask(m *me.ManagedEntity, requestedMask uint16) (uint16, error) {
377 attrDefs := m.GetAttributeDefinitions()
378 var entityIDName string
379 if entry, ok := attrDefs[0]; ok {
380 entityIDName = entry.GetName()
381 } else {
382 panic("unexpected error") // All attribute definition maps have an entity ID
383 }
384 attributeNames := make([]interface{}, 0)
385 for attrName := range m.GetAttributeValueMap() {
386 if attrName == entityIDName {
387 continue // No mask for EntityID
388 }
389 attributeNames = append(attributeNames, attrName)
390 }
391 calculatedMask, err := me.GetAttributesBitmap(attrDefs, mapset.NewSetWith(attributeNames...))
392
393 if err != nil {
394 return 0, err
395 }
396 return calculatedMask & requestedMask, nil
397}
398
399// GenFrame is a helper function to make tests a little easier to read.
400// For a real application, use the .../omci/generated/class.go 'New'
401// functions to create your Managed Entity and then use it to call the
402// EncodeFrame method.
403func GenFrame(meInstance *me.ManagedEntity, messageType MessageType, options ...FrameOption) ([]byte, error) {
404 omciLayer, msgLayer, err := EncodeFrame(meInstance, messageType, options...)
405 if err != nil {
406 return nil, err
407 }
408 // Serialize the frame and send it
409 var serializeOptions gopacket.SerializeOptions
410 serializeOptions.FixLengths = true
411
412 buffer := gopacket.NewSerializeBuffer()
413 err = gopacket.SerializeLayers(buffer, serializeOptions, omciLayer, msgLayer)
414 if err != nil {
415 return nil, err
416 }
417 return buffer.Bytes(), nil
418}
419
420func CreateRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -0500421 if opt.frameFormat == ExtendedIdent {
422 return nil, errors.New("Extended message set for this message type is not supported")
423 }
Chip Boling6e27b352020-02-14 09:10:01 -0600424 // NOTE: The OMCI parser does not extract the default values of set-by-create attributes
425 // and are the zero 'default' (or nil) at this time. For this reason, make sure
426 // you specify all non-zero default values and pass them in appropriate
427 meLayer := &CreateRequest{
428 MeBasePacket: MeBasePacket{
429 EntityClass: m.GetClassID(),
430 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -0500431 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -0600432 },
433 Attributes: m.GetAttributeValueMap(),
434 }
435 // Add any missing SetByCreate options if requested
436 if opt.addDefaults {
437 if attrDefs, err := me.GetAttributesDefinitions(m.GetClassID()); err.StatusCode() == me.Success {
438 for index, attr := range attrDefs {
439 if me.SupportsAttributeAccess(attr, me.SetByCreate) {
440 if index == 0 {
441 continue // Skip Entity ID, if it is SetByCreate, they should always specify it
442 }
443 if _, found := meLayer.Attributes[attr.GetName()]; !found {
444 meLayer.Attributes[attr.GetName()] = attr.DefValue
445 }
446 }
447 }
448 }
449 }
450 return meLayer, nil
451}
452
453func CreateResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -0500454 if opt.frameFormat == ExtendedIdent {
455 return nil, errors.New("Extended message set for this message type is not supported")
456 }
Chip Boling6e27b352020-02-14 09:10:01 -0600457 meLayer := &CreateResponse{
458 MeBasePacket: MeBasePacket{
459 EntityClass: m.GetClassID(),
460 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -0500461 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -0600462 },
463 Result: opt.result,
464 }
465 if meLayer.Result == me.ParameterError {
466 meLayer.AttributeExecutionMask = opt.attrExecutionMask
467 }
468 return meLayer, nil
469}
470
471func DeleteRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -0500472 if opt.frameFormat == ExtendedIdent {
473 return nil, errors.New("Extended message set for this message type is not supported")
474 }
Chip Boling6e27b352020-02-14 09:10:01 -0600475 meLayer := &DeleteRequest{
476 MeBasePacket: MeBasePacket{
477 EntityClass: m.GetClassID(),
478 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -0500479 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -0600480 },
481 }
482 return meLayer, nil
483}
484
485func DeleteResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -0500486 if opt.frameFormat == ExtendedIdent {
487 return nil, errors.New("Extended message set for this message type is not supported")
488 }
Chip Boling6e27b352020-02-14 09:10:01 -0600489 meLayer := &DeleteResponse{
490 MeBasePacket: MeBasePacket{
491 EntityClass: m.GetClassID(),
492 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -0500493 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -0600494 },
495 Result: opt.result,
496 }
497 return meLayer, nil
498}
499
500func SetRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
501 mask, err := checkAttributeMask(m, opt.attributeMask)
502 if err != nil {
503 return nil, err
504 }
505 mask, err = calculateAttributeMask(m, mask)
506 if err != nil {
507 return nil, err
508 }
509 meDefinition := m.GetManagedEntityDefinition()
510 attrDefs := meDefinition.GetAttributeDefinitions()
511 attrMap := m.GetAttributeValueMap()
512
513 // Get payload space available
514 maxPayload := maxPacketAvailable(m, opt)
515 payloadAvailable := int(maxPayload) - 2 // Less attribute mask
Chip Boling157c9b92021-04-21 09:58:36 -0500516 if opt.frameFormat == ExtendedIdent {
517 return nil, errors.New("Extended message set for this message type is not supported")
518 // payloadAvailable -= 2 // Less length
519 }
Chip Boling6e27b352020-02-14 09:10:01 -0600520 meLayer := &SetRequest{
521 MeBasePacket: MeBasePacket{
522 EntityClass: m.GetClassID(),
523 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -0500524 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -0600525 },
526 AttributeMask: 0,
527 Attributes: make(me.AttributeValueMap),
528 }
529 for mask != 0 {
530 // Iterate down the attributes (Attribute 0 is the ManagedEntity ID)
531 var attrIndex uint
532 for attrIndex = 1; attrIndex <= 16; attrIndex++ {
533 // Is this attribute requested
534 if mask&(1<<(16-attrIndex)) != 0 {
535 // Get definitions since we need the name
536 attrDef, ok := attrDefs[attrIndex]
537 if !ok {
538 msg := fmt.Sprintf("Unexpected error, index %v not valued for ME %v",
539 attrIndex, meDefinition.GetName())
540 return nil, errors.New(msg)
541 }
542 var attrValue interface{}
543 attrValue, ok = attrMap[attrDef.Name]
544 if !ok {
545 msg := fmt.Sprintf("Unexpected error, attribute %v not provided in ME %v: %v",
546 attrDef.GetName(), meDefinition.GetName(), m)
547 return nil, errors.New(msg)
548 }
549 // Is space available?
550 if attrDef.Size <= payloadAvailable {
551 // Mark bit handled
552 mask &= ^attrDef.Mask
553 meLayer.AttributeMask |= attrDef.Mask
554 meLayer.Attributes[attrDef.Name] = attrValue
555 payloadAvailable -= attrDef.Size
556 } else {
557 // TODO: Should we set truncate?
558 msg := fmt.Sprintf("out-of-space. Cannot fit attribute %v into SetRequest message",
559 attrDef.GetName())
560 return nil, me.NewMessageTruncatedError(msg)
561 }
562 }
563 }
564 }
565 if err == nil && meLayer.AttributeMask == 0 {
566 // TODO: Is a set request with no attributes valid?
567 return nil, errors.New("no attributes encoded for SetRequest")
568 }
569 return meLayer, nil
570}
571
572func SetResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -0500573 if opt.frameFormat == ExtendedIdent {
574 return nil, errors.New("Extended message set for this message type is not supported")
575 }
Chip Boling6e27b352020-02-14 09:10:01 -0600576 meLayer := &SetResponse{
577 MeBasePacket: MeBasePacket{
578 EntityClass: m.GetClassID(),
579 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -0500580 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -0600581 },
582 Result: opt.result,
583 }
584 if meLayer.Result == me.AttributeFailure {
585 meLayer.UnsupportedAttributeMask = opt.unsupportedMask
586 meLayer.FailedAttributeMask = opt.attrExecutionMask
587 }
588 return meLayer, nil
589}
590
591func GetRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
592 // Given mask sent in (could be default of 0xFFFF) get what is allowable.
593 // This will be all allowed if 0xFFFF is passed in, or a subset if a fixed
594 // number of items.
595 maxMask, err := checkAttributeMask(m, opt.attributeMask)
596 if err != nil {
597 return nil, err
598 }
599 // Now scan attributes and reduce mask to only those requested
600 var mask uint16
601 mask, err = calculateAttributeMask(m, maxMask)
602 if err != nil {
603 return nil, err
604 }
605 if mask == 0 {
606 // TODO: Is a Get request with no attributes valid?
607 return nil, errors.New("no attributes requested for GetRequest")
608 }
609 meLayer := &GetRequest{
610 MeBasePacket: MeBasePacket{
611 EntityClass: m.GetClassID(),
612 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -0500613 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -0600614 },
615 AttributeMask: mask,
616 }
617 return meLayer, nil
618}
619
620func GetResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
621 mask, err := checkAttributeMask(m, opt.attributeMask)
622 if err != nil {
623 return nil, err
624 }
625 mask, err = calculateAttributeMask(m, mask)
626 if err != nil {
627 return nil, err
628 }
629 meLayer := &GetResponse{
630 MeBasePacket: MeBasePacket{
631 EntityClass: m.GetClassID(),
632 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -0500633 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -0600634 },
635 Result: opt.result,
636 AttributeMask: 0,
637 Attributes: make(me.AttributeValueMap),
638 }
639 if meLayer.Result == me.AttributeFailure {
640 meLayer.UnsupportedAttributeMask = opt.unsupportedMask
641 meLayer.FailedAttributeMask = opt.attrExecutionMask
642 }
643 // Encode whatever we can
644 if meLayer.Result == me.Success || meLayer.Result == me.AttributeFailure {
645 // Encode results
646 // Get payload space available
647 maxPayload := maxPacketAvailable(m, opt)
648 payloadAvailable := int(maxPayload) - 2 - 4 // Less attribute mask and attribute error encoding
649 meDefinition := m.GetManagedEntityDefinition()
650 attrDefs := meDefinition.GetAttributeDefinitions()
651 attrMap := m.GetAttributeValueMap()
652
653 if mask != 0 {
654 // Iterate down the attributes (Attribute 0 is the ManagedEntity ID)
655 var attrIndex uint
656 for attrIndex = 1; attrIndex <= 16; attrIndex++ {
657 // Is this attribute requested
658 if mask&(1<<(16-attrIndex)) != 0 {
659 // Get definitions since we need the name
660 attrDef, ok := attrDefs[attrIndex]
661 if !ok {
662 msg := fmt.Sprintf("Unexpected error, index %v not valued for ME %v",
663 attrIndex, meDefinition.GetName())
664 return nil, errors.New(msg)
665 }
666 var attrValue interface{}
667 attrValue, ok = attrMap[attrDef.Name]
668 if !ok {
669 msg := fmt.Sprintf("Unexpected error, attribute %v not provided in ME %v: %v",
670 attrDef.GetName(), meDefinition.GetName(), m)
671 return nil, errors.New(msg)
672 }
673 // Is space available?
674 if attrDef.Size <= payloadAvailable {
675 // Mark bit handled
676 mask &= ^attrDef.Mask
677 meLayer.AttributeMask |= attrDef.Mask
678 meLayer.Attributes[attrDef.Name] = attrValue
679 payloadAvailable -= attrDef.Size
680
681 } else if opt.failIfTruncated {
682 // TODO: Should we set truncate?
683 msg := fmt.Sprintf("out-of-space. Cannot fit attribute %v into GetResponse message",
684 attrDef.GetName())
685 return nil, me.NewMessageTruncatedError(msg)
686 } else {
687 // Add to existing 'failed' mask and update result
688 meLayer.FailedAttributeMask |= attrDef.Mask
689 meLayer.Result = me.AttributeFailure
690 }
691 }
692 }
693 }
694 }
695 return meLayer, nil
696}
697
698func GetAllAlarmsRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -0500699 if opt.frameFormat == ExtendedIdent {
700 return nil, errors.New("Extended message set for this message type is not supported")
701 }
Chip Boling6e27b352020-02-14 09:10:01 -0600702 // Common for all MEs
703 meLayer := &GetAllAlarmsRequest{
704 MeBasePacket: MeBasePacket{
705 EntityClass: m.GetClassID(),
706 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -0500707 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -0600708 },
709 AlarmRetrievalMode: opt.mode,
710 }
711 return meLayer, nil
712}
713
714func GetAllAlarmsResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -0500715 if opt.frameFormat == ExtendedIdent {
716 return nil, errors.New("Extended message set for this message type is not supported")
717 }
Chip Boling6e27b352020-02-14 09:10:01 -0600718 // Common for all MEs
719 meLayer := &GetAllAlarmsResponse{
720 MeBasePacket: MeBasePacket{
721 EntityClass: m.GetClassID(),
722 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -0500723 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -0600724 },
725 NumberOfCommands: opt.sequenceNumberCountOrSize,
726 }
727 return meLayer, nil
728}
729
730func GetAllAlarmsNextRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -0500731 if opt.frameFormat == ExtendedIdent {
732 return nil, errors.New("Extended message set for this message type is not supported")
733 }
Chip Boling6e27b352020-02-14 09:10:01 -0600734 // Common for all MEs
735 meLayer := &GetAllAlarmsNextRequest{
736 MeBasePacket: MeBasePacket{
737 EntityClass: m.GetClassID(),
738 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -0500739 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -0600740 },
741 CommandSequenceNumber: opt.sequenceNumberCountOrSize,
742 }
743 return meLayer, nil
744}
745
746func GetAllAlarmsNextResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -0500747 if opt.frameFormat == ExtendedIdent {
748 return nil, errors.New("Extended message set for this message type is not supported")
749 }
Chip Boling6e27b352020-02-14 09:10:01 -0600750 // Common for all MEs
751 meLayer := &GetAllAlarmsNextResponse{
752 MeBasePacket: MeBasePacket{
753 EntityClass: m.GetClassID(),
754 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -0500755 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -0600756 },
757 AlarmEntityClass: opt.alarm.AlarmClassID,
758 AlarmEntityInstance: opt.alarm.AlarmInstance,
759 }
760 if len(opt.alarm.AlarmBitmap) > 28 {
761 return nil, errors.New("invalid Alarm Bitmap Size. Must be [0..27]")
762 }
763 for octet := 0; octet < len(opt.alarm.AlarmBitmap); octet++ {
764 meLayer.AlarmBitMap[octet] = opt.alarm.AlarmBitmap[octet]
765 }
766 for octet := len(opt.alarm.AlarmBitmap); octet < 28; octet++ {
767 meLayer.AlarmBitMap[octet] = 0
768 }
769 return meLayer, nil
770}
771
772func MibUploadRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -0500773 if opt.frameFormat == ExtendedIdent {
774 return nil, errors.New("Extended message set for this message type is not supported")
775 }
Chip Boling6e27b352020-02-14 09:10:01 -0600776 // Common for all MEs
777 meLayer := &MibUploadRequest{
778 MeBasePacket: MeBasePacket{
779 EntityClass: m.GetClassID(),
780 EntityInstance: 0,
Chip Boling157c9b92021-04-21 09:58:36 -0500781 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -0600782 },
783 }
784 return meLayer, nil
785}
786
787func MibUploadResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -0500788 if opt.frameFormat == ExtendedIdent {
789 return nil, errors.New("Extended message set for this message type is not supported")
790 }
Chip Boling6e27b352020-02-14 09:10:01 -0600791 // Common for all MEs
792 meLayer := &MibUploadResponse{
793 MeBasePacket: MeBasePacket{
794 EntityClass: m.GetClassID(),
795 EntityInstance: 0,
Chip Boling157c9b92021-04-21 09:58:36 -0500796 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -0600797 },
798 NumberOfCommands: opt.sequenceNumberCountOrSize,
799 }
800 return meLayer, nil
801}
802
803func MibUploadNextRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -0500804 if opt.frameFormat == ExtendedIdent {
805 return nil, errors.New("Extended message set for this message type is not supported")
806 }
Chip Boling6e27b352020-02-14 09:10:01 -0600807 // Common for all MEs
808 meLayer := &MibUploadNextRequest{
809 MeBasePacket: MeBasePacket{
810 EntityClass: m.GetClassID(),
811 EntityInstance: 0,
Chip Boling157c9b92021-04-21 09:58:36 -0500812 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -0600813 },
814 CommandSequenceNumber: opt.sequenceNumberCountOrSize,
815 }
816 return meLayer, nil
817}
818
819func MibUploadNextResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -0500820 if opt.frameFormat == ExtendedIdent {
821 return nil, errors.New("Extended message set for this message type is not supported")
822 }
Chip Boling6e27b352020-02-14 09:10:01 -0600823 // Common for all MEs
824 meLayer := &MibUploadNextResponse{
825 MeBasePacket: MeBasePacket{
826 EntityClass: m.GetClassID(),
827 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -0500828 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -0600829 },
830 }
831 if opt.payload == nil {
832 // Shortcut used to specify the request sequence number is out of range, encode
833 // a ME instance with class ID of zero to specify this per ITU G.988
834 meDef := me.ManagedEntityDefinition{
835 Name: "InvalidSequenceNumberManagedEntity",
836 ClassID: me.ClassID(0),
837 MessageTypes: nil,
838 AttributeDefinitions: make(me.AttributeDefinitionMap),
839 }
840 opt.payload, _ = me.NewManagedEntity(meDef)
841 }
842 if _, ok := opt.payload.(*[]me.ManagedEntity); ok {
843 if opt.frameFormat == BaselineIdent {
844 return nil, errors.New("invalid payload for Baseline message")
845 }
846 // TODO: List of MEs. valid for extended messages only
847 } else if managedEntity, ok := opt.payload.(*me.ManagedEntity); ok {
848 // Single ME
849 meLayer.ReportedME = *managedEntity
850 } else {
851 return nil, errors.New("invalid payload for MibUploadNextResponse frame")
852 }
853 return meLayer, nil
854}
855
856func MibResetRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -0500857 if opt.frameFormat == ExtendedIdent {
858 return nil, errors.New("Extended message set for this message type is not supported")
859 }
Chip Boling6e27b352020-02-14 09:10:01 -0600860 // Common for all MEs
861 meLayer := &MibResetRequest{
862 MeBasePacket: MeBasePacket{
863 EntityClass: m.GetClassID(),
864 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -0500865 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -0600866 },
867 }
868 return meLayer, nil
869}
870
871func MibResetResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -0500872 if opt.frameFormat == ExtendedIdent {
873 return nil, errors.New("Extended message set for this message type is not supported")
874 }
Chip Boling6e27b352020-02-14 09:10:01 -0600875 // Common for all MEs
876 meLayer := &MibResetResponse{
877 MeBasePacket: MeBasePacket{
878 EntityClass: m.GetClassID(),
879 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -0500880 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -0600881 },
882 Result: opt.result,
883 }
884 return meLayer, nil
885}
886
887func AlarmNotificationFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -0500888 if opt.frameFormat == ExtendedIdent {
889 return nil, errors.New("Extended message set for this message type is not supported")
890 }
Chip Boling6e27b352020-02-14 09:10:01 -0600891 mask, err := checkAttributeMask(m, opt.attributeMask)
892 if err != nil {
893 return nil, err
894 }
895 // Common for all MEs
896 meLayer := &AlarmNotificationMsg{
897 MeBasePacket: MeBasePacket{
898 EntityClass: m.GetClassID(),
899 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -0500900 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -0600901 },
902 }
903 // Get payload space available
904 maxPayload := maxPacketAvailable(m, opt)
905 payloadAvailable := int(maxPayload) - 1 // Less alarm sequence number
906
907 // TODO: Lots of work to do
908 fmt.Println(mask, maxPayload, payloadAvailable)
909
910 return meLayer, errors.New("todo: Not implemented")
911}
912
913func AttributeValueChangeFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -0500914 if opt.frameFormat == ExtendedIdent {
915 return nil, errors.New("Extended message set for this message type is not supported")
916 }
Chip Boling6e27b352020-02-14 09:10:01 -0600917 mask, err := checkAttributeMask(m, opt.attributeMask)
918 if err != nil {
919 return nil, err
920 }
921 // Common for all MEs
922 meLayer := &AttributeValueChangeMsg{
923 MeBasePacket: MeBasePacket{
924 EntityClass: m.GetClassID(),
925 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -0500926 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -0600927 },
928 AttributeMask: 0,
929 Attributes: make(me.AttributeValueMap),
930 }
931 // Get payload space available
932 maxPayload := maxPacketAvailable(m, opt)
933 payloadAvailable := int(maxPayload) - 2 // Less attribute mask
934
935 // TODO: Lots of work to do
936
937 fmt.Println(mask, maxPayload, payloadAvailable)
938 return meLayer, errors.New("todo: Not implemented")
939}
940
Chip Bolingd8637b02021-04-29 08:36:38 -0500941//func TestRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
942// if opt.frameFormat == ExtendedIdent {
943// return nil, errors.New("Extended message set for this message type is not supported")
944// }
945// mask, err := checkAttributeMask(m, opt.attributeMask)
946// if err != nil {
947// return nil, err
948// }
949// // Common for all MEs
950// meLayer := &TestRequest{
951// MeBasePacket: MeBasePacket{
952// EntityClass: m.GetClassID(),
953// EntityInstance: m.GetEntityID(),
954// Extended: opt.frameFormat == ExtendedIdent,
955// },
956// }
957// // Get payload space available
958// maxPayload := maxPacketAvailable(m, opt)
959//
960// // TODO: Lots of work to do
961//
962// fmt.Println(mask, maxPayload)
963// return meLayer, errors.New("todo: Not implemented")
964//}
Chip Boling6e27b352020-02-14 09:10:01 -0600965
Chip Bolingd8637b02021-04-29 08:36:38 -0500966//func TestResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
967// if opt.frameFormat == ExtendedIdent {
968// return nil, errors.New("Extended message set for this message type is not supported")
969// }
970// mask, err := checkAttributeMask(m, opt.attributeMask)
971// if err != nil {
972// return nil, err
973// }
974// // Common for all MEs
975// meLayer := &TestResponse{
976// MeBasePacket: MeBasePacket{
977// EntityClass: m.GetClassID(),
978// EntityInstance: m.GetEntityID(),
979// Extended: opt.frameFormat == ExtendedIdent,
980// },
981// }
982// // Get payload space available
983// maxPayload := maxPacketAvailable(m, opt)
984//
985// // TODO: Lots of work to do
986//
987// fmt.Println(mask, maxPayload)
988// return meLayer, errors.New("todo: Not implemented")
989//}
Chip Boling6e27b352020-02-14 09:10:01 -0600990
991func StartSoftwareDownloadRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -0500992 if opt.frameFormat == ExtendedIdent {
993 return nil, errors.New("Extended message set for this message type is not supported")
994 }
Chip Boling6e27b352020-02-14 09:10:01 -0600995 // Common for all MEs
996 meLayer := &StartSoftwareDownloadRequest{
997 MeBasePacket: MeBasePacket{
998 EntityClass: m.GetClassID(),
999 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -05001000 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -06001001 },
1002 WindowSize: opt.software.WindowSize,
1003 ImageSize: opt.software.ImageSize,
1004 NumberOfCircuitPacks: byte(len(opt.software.CircuitPacks)),
1005 CircuitPacks: opt.software.CircuitPacks,
1006 }
1007 // TODO: Add length check to insure we do not exceed maximum packet size
1008 // payloadAvailable := int(maxPacketAvailable(m, opt))
1009 payloadAvailable := 2
1010 sizeNeeded := 1
1011 if sizeNeeded > payloadAvailable {
1012 // TODO: Should we set truncate?
1013 msg := "out-of-space. Cannot fit Circuit Pack instances into Start Software Download Request message"
1014 return nil, me.NewMessageTruncatedError(msg)
1015 }
1016 return meLayer, nil
1017}
1018
1019func StartSoftwareDownloadResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -05001020 if opt.frameFormat == ExtendedIdent {
1021 return nil, errors.New("Extended message set for this message type is not supported")
1022 }
Chip Boling6e27b352020-02-14 09:10:01 -06001023 // Common for all MEs
1024 meLayer := &StartSoftwareDownloadResponse{
1025 MeBasePacket: MeBasePacket{
1026 EntityClass: m.GetClassID(),
1027 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -05001028 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -06001029 },
1030 WindowSize: opt.software.WindowSize,
1031 NumberOfInstances: byte(len(opt.software.CircuitPacks)),
1032 MeResults: opt.software.Results,
1033 }
1034 // TODO: Add length check to insure we do not exceed maximum packet size
1035 // payloadAvailable := int(maxPacketAvailable(m, opt))
1036 payloadAvailable := 2
1037 sizeNeeded := 1
1038 if sizeNeeded > payloadAvailable {
1039 // TODO: Should we set truncate?
1040 msg := "out-of-space. Cannot fit Results into Start Software Download Response message"
1041 return nil, me.NewMessageTruncatedError(msg)
1042 }
1043 return meLayer, nil
1044}
1045
1046func DownloadSectionRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling00a30d22021-05-04 13:31:52 -05001047 if opt.software.Data == nil {
1048 return nil, me.NewNonStatusError("Software image data missing")
Chip Boling6e27b352020-02-14 09:10:01 -06001049 }
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 },
Chip Boling00a30d22021-05-04 13:31:52 -05001057 SectionNumber: opt.software.SectionNumber,
1058 SectionData: opt.software.Data,
Chip Boling6e27b352020-02-14 09:10:01 -06001059 }
Chip Boling00a30d22021-05-04 13:31:52 -05001060 return meLayer, nil
Chip Boling6e27b352020-02-14 09:10:01 -06001061}
1062
1063func DownloadSectionResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling6e27b352020-02-14 09:10:01 -06001064 // Common for all MEs
1065 meLayer := &DownloadSectionResponse{
1066 MeBasePacket: MeBasePacket{
1067 EntityClass: m.GetClassID(),
1068 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -05001069 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -06001070 },
Chip Boling00a30d22021-05-04 13:31:52 -05001071 Result: opt.result,
1072 SectionNumber: opt.software.SectionNumber,
Chip Boling6e27b352020-02-14 09:10:01 -06001073 }
Chip Boling00a30d22021-05-04 13:31:52 -05001074 return meLayer, nil
Chip Boling6e27b352020-02-14 09:10:01 -06001075}
1076
1077func EndSoftwareDownloadRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -05001078 if opt.frameFormat == ExtendedIdent {
1079 return nil, errors.New("Extended message set for this message type is not supported")
1080 }
Chip Boling6e27b352020-02-14 09:10:01 -06001081 mask, err := checkAttributeMask(m, opt.attributeMask)
1082 if err != nil {
1083 return nil, err
1084 }
1085 // Common for all MEs
1086 meLayer := &EndSoftwareDownloadRequest{
1087 MeBasePacket: MeBasePacket{
1088 EntityClass: m.GetClassID(),
1089 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -05001090 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -06001091 },
1092 }
1093 // Get payload space available
1094 maxPayload := maxPacketAvailable(m, opt)
1095
1096 // TODO: Lots of work to do
1097
1098 fmt.Println(mask, maxPayload)
1099 return meLayer, errors.New("todo: Not implemented")
1100}
1101
1102func EndSoftwareDownloadResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -05001103 if opt.frameFormat == ExtendedIdent {
1104 return nil, errors.New("Extended message set for this message type is not supported")
1105 }
Chip Boling6e27b352020-02-14 09:10:01 -06001106 mask, err := checkAttributeMask(m, opt.attributeMask)
1107 if err != nil {
1108 return nil, err
1109 }
1110 // Common for all MEs
1111 meLayer := &EndSoftwareDownloadResponse{
1112 MeBasePacket: MeBasePacket{
1113 EntityClass: m.GetClassID(),
1114 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -05001115 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -06001116 },
1117 }
1118 // Get payload space available
1119 maxPayload := maxPacketAvailable(m, opt)
1120
1121 // TODO: Lots of work to do
1122
1123 fmt.Println(mask, maxPayload)
1124 return meLayer, errors.New("todo: Not implemented")
1125}
1126
1127func ActivateSoftwareRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -05001128 if opt.frameFormat == ExtendedIdent {
1129 return nil, errors.New("Extended message set for this message type is not supported")
1130 }
Chip Boling6e27b352020-02-14 09:10:01 -06001131 mask, err := checkAttributeMask(m, opt.attributeMask)
1132 if err != nil {
1133 return nil, err
1134 }
1135 // Common for all MEs
1136 meLayer := &ActivateSoftwareRequest{
1137 MeBasePacket: MeBasePacket{
1138 EntityClass: m.GetClassID(),
1139 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -05001140 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -06001141 },
1142 }
1143 // Get payload space available
1144 maxPayload := maxPacketAvailable(m, opt)
1145
1146 // TODO: Lots of work to do
1147
1148 fmt.Println(mask, maxPayload)
1149 return meLayer, errors.New("todo: Not implemented")
1150}
1151
1152func ActivateSoftwareResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -05001153 if opt.frameFormat == ExtendedIdent {
1154 return nil, errors.New("Extended message set for this message type is not supported")
1155 }
Chip Boling6e27b352020-02-14 09:10:01 -06001156 mask, err := checkAttributeMask(m, opt.attributeMask)
1157 if err != nil {
1158 return nil, err
1159 }
1160 // Common for all MEs
1161 meLayer := &ActivateSoftwareResponse{
1162 MeBasePacket: MeBasePacket{
1163 EntityClass: m.GetClassID(),
1164 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -05001165 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -06001166 },
1167 }
1168 // Get payload space available
1169 maxPayload := maxPacketAvailable(m, opt)
1170
1171 // TODO: Lots of work to do
1172
1173 fmt.Println(mask, maxPayload)
1174 return meLayer, errors.New("todo: Not implemented")
1175}
1176
1177func CommitSoftwareRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -05001178 if opt.frameFormat == ExtendedIdent {
1179 return nil, errors.New("Extended message set for this message type is not supported")
1180 }
Chip Boling6e27b352020-02-14 09:10:01 -06001181 mask, err := checkAttributeMask(m, opt.attributeMask)
1182 if err != nil {
1183 return nil, err
1184 }
1185 // Common for all MEs
1186 meLayer := &CommitSoftwareRequest{
1187 MeBasePacket: MeBasePacket{
1188 EntityClass: m.GetClassID(),
1189 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -05001190 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -06001191 },
1192 }
1193 // Get payload space available
1194 maxPayload := maxPacketAvailable(m, opt)
1195
1196 // TODO: Lots of work to do
1197
1198 fmt.Println(mask, maxPayload)
1199 return meLayer, errors.New("todo: Not implemented")
1200}
1201
1202func CommitSoftwareResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -05001203 if opt.frameFormat == ExtendedIdent {
1204 return nil, errors.New("Extended message set for this message type is not supported")
1205 }
Chip Boling6e27b352020-02-14 09:10:01 -06001206 mask, err := checkAttributeMask(m, opt.attributeMask)
1207 if err != nil {
1208 return nil, err
1209 }
1210 // Common for all MEs
1211 meLayer := &CommitSoftwareResponse{
1212 MeBasePacket: MeBasePacket{
1213 EntityClass: m.GetClassID(),
1214 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -05001215 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -06001216 },
1217 }
1218 // Get payload space available
1219 maxPayload := maxPacketAvailable(m, opt)
1220
1221 // TODO: Lots of work to do
1222
1223 fmt.Println(mask, maxPayload)
1224 return meLayer, errors.New("todo: Not implemented")
1225}
1226
1227func SynchronizeTimeRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -05001228 if opt.frameFormat == ExtendedIdent {
1229 return nil, errors.New("Extended message set for this message type is not supported")
1230 }
Chip Boling6e27b352020-02-14 09:10:01 -06001231 // Common for all MEs
1232 meLayer := &SynchronizeTimeRequest{
1233 MeBasePacket: MeBasePacket{
1234 EntityClass: m.GetClassID(),
1235 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -05001236 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -06001237 },
1238 }
1239 // Decode payload option. If nil, no timestamp provided
1240 if timestamp, ok := opt.payload.(int64); ok {
1241 tm := time.Unix(timestamp, 0)
1242 meLayer.Year = uint16(tm.UTC().Year())
1243 meLayer.Month = uint8(tm.UTC().Month())
1244 meLayer.Day = uint8(tm.UTC().Day())
1245 meLayer.Hour = uint8(tm.UTC().Hour())
1246 meLayer.Minute = uint8(tm.UTC().Minute())
1247 meLayer.Second = uint8(tm.UTC().Second())
1248 }
1249 return meLayer, nil
1250}
1251
1252func SynchronizeTimeResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -05001253 if opt.frameFormat == ExtendedIdent {
1254 return nil, errors.New("Extended message set for this message type is not supported")
1255 }
Chip Boling6e27b352020-02-14 09:10:01 -06001256 // Common for all MEs
1257 meLayer := &SynchronizeTimeResponse{
1258 MeBasePacket: MeBasePacket{
1259 EntityClass: m.GetClassID(),
1260 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -05001261 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -06001262 },
1263 Result: opt.result,
1264 SuccessResults: opt.mode,
1265 }
1266 return meLayer, nil
1267}
1268
1269func RebootRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -05001270 if opt.frameFormat == ExtendedIdent {
1271 return nil, errors.New("Extended message set for this message type is not supported")
1272 }
Chip Boling6e27b352020-02-14 09:10:01 -06001273 // Common for all MEs
1274 meLayer := &RebootRequest{
1275 MeBasePacket: MeBasePacket{
1276 EntityClass: m.GetClassID(),
1277 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -05001278 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -06001279 },
1280 RebootCondition: opt.mode,
1281 }
1282 return meLayer, nil
1283}
1284
1285func RebootResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -05001286 if opt.frameFormat == ExtendedIdent {
1287 return nil, errors.New("Extended message set for this message type is not supported")
1288 }
Chip Boling6e27b352020-02-14 09:10:01 -06001289 // Common for all MEs
1290 meLayer := &RebootResponse{
1291 MeBasePacket: MeBasePacket{
1292 EntityClass: m.GetClassID(),
1293 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -05001294 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -06001295 },
1296 Result: opt.result,
1297 }
1298 return meLayer, nil
1299}
1300
1301func GetNextRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -05001302 if opt.frameFormat == ExtendedIdent {
1303 return nil, errors.New("Extended message set for this message type is not supported")
1304 }
Chip Boling6e27b352020-02-14 09:10:01 -06001305 // Validate attribute mask
1306 mask, err := checkAttributeMask(m, opt.attributeMask)
1307 if err != nil {
1308 return nil, err
1309 }
1310 // Now scan attributes and reduce mask to only those requested
1311 mask, err = calculateAttributeMask(m, mask)
1312 if err != nil {
1313 return nil, err
1314 }
1315 if mask == 0 {
1316 return nil, errors.New("no attributes requested for GetNextRequest")
1317 }
1318 // TODO: If more than one attribute or the attribute requested is not a table attribute, return an error
1319 // Common for all MEs
1320 meLayer := &GetNextRequest{
1321 MeBasePacket: MeBasePacket{
1322 EntityClass: m.GetClassID(),
1323 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -05001324 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -06001325 },
1326 AttributeMask: mask,
1327 SequenceNumber: opt.sequenceNumberCountOrSize,
1328 }
1329 return meLayer, nil
1330}
1331
1332func GetNextResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -05001333 if opt.frameFormat == ExtendedIdent {
1334 return nil, errors.New("Extended message set for this message type is not supported")
1335 }
Chip Boling6e27b352020-02-14 09:10:01 -06001336 // Validate attribute mask
1337 mask, err := checkAttributeMask(m, opt.attributeMask)
1338 if err != nil {
1339 return nil, err
1340 }
1341 mask, err = calculateAttributeMask(m, mask)
1342 if err != nil {
1343 return nil, err
1344 }
1345 //
1346 // Common for all MEs
1347 meLayer := &GetNextResponse{
1348 MeBasePacket: MeBasePacket{
1349 EntityClass: m.GetClassID(),
1350 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -05001351 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -06001352 },
1353 Result: opt.result,
1354 AttributeMask: 0,
1355 Attributes: make(me.AttributeValueMap),
1356 }
1357 if meLayer.Result == me.Success {
1358 // Get payload space available
1359 maxPayload := maxPacketAvailable(m, opt)
1360 payloadAvailable := int(maxPayload) - 3 // Less results and attribute mask
1361 meDefinition := m.GetManagedEntityDefinition()
1362 attrDefs := meDefinition.GetAttributeDefinitions()
1363 attrMap := m.GetAttributeValueMap()
1364
1365 if mask == 0 {
1366 return nil, errors.New("no attributes requested for GetNextResponse")
1367 }
1368 // TODO: If more than one attribute or the attribute requested is not a table attribute, return an error
1369 // Iterate down the attributes (Attribute 0 is the ManagedEntity ID)
1370 var attrIndex uint
1371 for attrIndex = 1; attrIndex <= 16; attrIndex++ {
1372 // Is this attribute requested
1373 if mask&(1<<(16-attrIndex)) != 0 {
1374 // Get definitions since we need the name
1375 attrDef, ok := attrDefs[attrIndex]
1376 if !ok {
1377 msg := fmt.Sprintf("Unexpected error, index %v not valued for ME %v",
1378 attrIndex, meDefinition.GetName())
1379 return nil, errors.New(msg)
1380 }
1381 var attrValue interface{}
1382 attrValue, ok = attrMap[attrDef.Name]
1383 if !ok || attrValue == nil {
1384 msg := fmt.Sprintf("Unexpected error, attribute %v not provided in ME %v: %v",
1385 attrDef.GetName(), meDefinition.GetName(), m)
1386 return nil, errors.New(msg)
1387 }
1388 // Is space available?
1389 if attrDef.Size <= payloadAvailable {
1390 // Mark bit handled
1391 mask &= ^attrDef.Mask
1392 meLayer.AttributeMask |= attrDef.Mask
1393 meLayer.Attributes[attrDef.Name] = attrValue
1394 payloadAvailable -= attrDef.Size
1395 } else {
1396 // TODO: Should we set truncate?
1397 msg := fmt.Sprintf("out-of-space. Cannot fit attribute %v into GetNextResponse message",
1398 attrDef.GetName())
1399 return nil, me.NewMessageTruncatedError(msg)
1400 }
1401 }
1402 }
1403 }
1404 return meLayer, nil
1405}
1406
Chip Bolingd8637b02021-04-29 08:36:38 -05001407//func TestResultFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
1408// if opt.frameFormat == ExtendedIdent {
1409// return nil, errors.New("Extended message set for this message type is not supported")
1410// }
1411// mask, err := checkAttributeMask(m, opt.attributeMask)
1412// if err != nil {
1413// return nil, err
1414// }
1415// // Common for all MEs
1416// meLayer := &TestResultNotification{
1417// MeBasePacket: MeBasePacket{
1418// EntityClass: m.GetClassID(),
1419// EntityInstance: m.GetEntityID(),
1420// Extended: opt.frameFormat == ExtendedIdent,
1421// },
1422// }
1423// // Get payload space available
1424// maxPayload := maxPacketAvailable(m, opt)
1425//
1426// // TODO: Lots of work to do
1427//
1428// fmt.Println(mask, maxPayload)
1429// return meLayer, errors.New("todo: Not implemented")
1430//}
Chip Boling6e27b352020-02-14 09:10:01 -06001431
1432func GetCurrentDataRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -05001433 if opt.frameFormat == ExtendedIdent {
1434 return nil, errors.New("Extended message set for this message type is not supported")
1435 }
Chip Boling6e27b352020-02-14 09:10:01 -06001436 mask, err := checkAttributeMask(m, opt.attributeMask)
1437 if err != nil {
1438 return nil, err
1439 }
1440 // Common for all MEs
1441 meLayer := &GetCurrentDataRequest{
1442 MeBasePacket: MeBasePacket{
1443 EntityClass: m.GetClassID(),
1444 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -05001445 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -06001446 },
1447 }
1448 // Get payload space available
1449 maxPayload := maxPacketAvailable(m, opt)
1450
1451 // TODO: Lots of work to do
1452
1453 fmt.Println(mask, maxPayload)
1454 return meLayer, errors.New("todo: Not implemented")
1455}
1456
1457func GetCurrentDataResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
Chip Boling157c9b92021-04-21 09:58:36 -05001458 if opt.frameFormat == ExtendedIdent {
1459 return nil, errors.New("Extended message set for this message type is not supported")
1460 }
Chip Boling6e27b352020-02-14 09:10:01 -06001461 mask, err := checkAttributeMask(m, opt.attributeMask)
1462 if err != nil {
1463 return nil, err
1464 }
1465 // Common for all MEs
1466 meLayer := &GetCurrentDataResponse{
1467 MeBasePacket: MeBasePacket{
1468 EntityClass: m.GetClassID(),
1469 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -05001470 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -06001471 },
1472 }
1473 // Get payload space available
1474 maxPayload := maxPacketAvailable(m, opt)
1475
1476 // TODO: Lots of work to do
1477
1478 fmt.Println(mask, maxPayload)
1479 return meLayer, errors.New("todo: Not implemented")
1480}
1481
1482func SetTableRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
1483 if opt.frameFormat != ExtendedIdent {
1484 return nil, errors.New("SetTable message type only supported with Extended OMCI Messaging")
1485 }
Chip Boling157c9b92021-04-21 09:58:36 -05001486 if opt.frameFormat == ExtendedIdent {
1487 return nil, errors.New("Extended message set for this message type is not supported")
1488 }
Chip Boling6e27b352020-02-14 09:10:01 -06001489 mask, err := checkAttributeMask(m, opt.attributeMask)
1490 if err != nil {
1491 return nil, err
1492 }
1493 // Common for all MEs
1494 meLayer := &SetTableRequest{
1495 MeBasePacket: MeBasePacket{
1496 EntityClass: m.GetClassID(),
1497 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -05001498 Extended: opt.frameFormat == ExtendedIdent,
Chip Boling6e27b352020-02-14 09:10:01 -06001499 },
1500 }
1501 // Get payload space available
1502 maxPayload := maxPacketAvailable(m, opt)
1503
1504 // TODO: Lots of work to do
1505
1506 fmt.Println(mask, maxPayload)
1507 return meLayer, errors.New("todo: Not implemented")
1508}
1509
1510func SetTableResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
1511 if opt.frameFormat != ExtendedIdent {
Chip Boling157c9b92021-04-21 09:58:36 -05001512 return nil, errors.New("SetTable message type only supported with Extended OMCI Message Set")
1513 }
1514 if opt.frameFormat == ExtendedIdent {
1515 return nil, errors.New("Extended message set for this message type is not supported")
Chip Boling6e27b352020-02-14 09:10:01 -06001516 }
1517 mask, err := checkAttributeMask(m, opt.attributeMask)
1518 if err != nil {
1519 return nil, err
1520 }
1521 // Common for all MEs
1522 meLayer := &SetTableResponse{
1523 MeBasePacket: MeBasePacket{
1524 EntityClass: m.GetClassID(),
1525 EntityInstance: m.GetEntityID(),
Chip Boling157c9b92021-04-21 09:58:36 -05001526 Extended: true,
Chip Boling6e27b352020-02-14 09:10:01 -06001527 },
1528 }
1529 // Get payload space available
1530 maxPayload := maxPacketAvailable(m, opt)
1531
1532 // TODO: Lots of work to do
1533
1534 fmt.Println(mask, maxPayload)
1535 return meLayer, errors.New("todo: Not implemented")
1536}