[VOL-4396] OMCI lib update to be incorporated into ONU adapter, make use of relaxed decoding
Signed-off-by: mpagenko <michael.pagenkopf@adtran.com>
Change-Id: Ic8bc15ae061af8e27d73879f27bb5b80637a8dea
diff --git a/vendor/github.com/opencord/omci-lib-go/v2/meframe/me_alarms.go b/vendor/github.com/opencord/omci-lib-go/v2/meframe/me_alarms.go
new file mode 100644
index 0000000..7958b91
--- /dev/null
+++ b/vendor/github.com/opencord/omci-lib-go/v2/meframe/me_alarms.go
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2018 - present. Boling Consulting Solutions (bcsw.net)
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package meframe
+
+import (
+ "errors"
+ "fmt"
+ "github.com/google/gopacket"
+ . "github.com/opencord/omci-lib-go/v2"
+ me "github.com/opencord/omci-lib-go/v2/generated"
+)
+
+func GetAllAlarmsRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
+ if opt.frameFormat == ExtendedIdent {
+ return nil, errors.New("extended message set for this message type is not supported")
+ }
+ // Common for all MEs
+ meLayer := &GetAllAlarmsRequest{
+ MeBasePacket: MeBasePacket{
+ EntityClass: m.GetClassID(),
+ EntityInstance: m.GetEntityID(),
+ Extended: opt.frameFormat == ExtendedIdent,
+ },
+ AlarmRetrievalMode: opt.mode,
+ }
+ return meLayer, nil
+}
+
+func GetAllAlarmsResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
+ if opt.frameFormat == ExtendedIdent {
+ return nil, errors.New("extended message set for this message type is not supported")
+ }
+ // Common for all MEs
+ meLayer := &GetAllAlarmsResponse{
+ MeBasePacket: MeBasePacket{
+ EntityClass: m.GetClassID(),
+ EntityInstance: m.GetEntityID(),
+ Extended: opt.frameFormat == ExtendedIdent,
+ },
+ NumberOfCommands: opt.sequenceNumberCountOrSize,
+ }
+ return meLayer, nil
+}
+
+func GetAllAlarmsNextRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
+ if opt.frameFormat == ExtendedIdent {
+ return nil, errors.New("extended message set for this message type is not supported")
+ }
+ // Common for all MEs
+ meLayer := &GetAllAlarmsNextRequest{
+ MeBasePacket: MeBasePacket{
+ EntityClass: m.GetClassID(),
+ EntityInstance: m.GetEntityID(),
+ Extended: opt.frameFormat == ExtendedIdent,
+ },
+ CommandSequenceNumber: opt.sequenceNumberCountOrSize,
+ }
+ return meLayer, nil
+}
+
+func GetAllAlarmsNextResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
+ if opt.frameFormat == ExtendedIdent {
+ return nil, errors.New("extended message set for this message type is not supported")
+ }
+ // Common for all MEs
+ meLayer := &GetAllAlarmsNextResponse{
+ MeBasePacket: MeBasePacket{
+ EntityClass: m.GetClassID(),
+ EntityInstance: m.GetEntityID(),
+ Extended: opt.frameFormat == ExtendedIdent,
+ },
+ AlarmEntityClass: opt.alarm.AlarmClassID,
+ AlarmEntityInstance: opt.alarm.AlarmInstance,
+ }
+ if len(opt.alarm.AlarmBitmap) > 28 {
+ return nil, errors.New("invalid Alarm Bitmap Size. Must be [0..27]")
+ }
+ for octet := 0; octet < len(opt.alarm.AlarmBitmap); octet++ {
+ meLayer.AlarmBitMap[octet] = opt.alarm.AlarmBitmap[octet]
+ }
+ for octet := len(opt.alarm.AlarmBitmap); octet < 28; octet++ {
+ meLayer.AlarmBitMap[octet] = 0
+ }
+ return meLayer, nil
+}
+
+func AlarmNotificationFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
+ if opt.frameFormat == ExtendedIdent {
+ return nil, errors.New("extended message set for this message type is not supported")
+ }
+ mask, err := checkAttributeMask(m, opt.attributeMask)
+ if err != nil {
+ return nil, err
+ }
+ // Common for all MEs
+ meLayer := &AlarmNotificationMsg{
+ MeBasePacket: MeBasePacket{
+ EntityClass: m.GetClassID(),
+ EntityInstance: m.GetEntityID(),
+ Extended: opt.frameFormat == ExtendedIdent,
+ },
+ }
+ // Get payload space available
+ maxPayload := maxPacketAvailable(m, opt)
+ payloadAvailable := int(maxPayload) - 1 // Less alarm sequence number
+
+ // TODO: Lots of work to do
+ fmt.Println(mask, maxPayload, payloadAvailable)
+
+ return meLayer, errors.New("todo: Not implemented")
+}
diff --git a/vendor/github.com/opencord/omci-lib-go/v2/meframe/me_avc.go b/vendor/github.com/opencord/omci-lib-go/v2/meframe/me_avc.go
new file mode 100644
index 0000000..3d075fc
--- /dev/null
+++ b/vendor/github.com/opencord/omci-lib-go/v2/meframe/me_avc.go
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2018 - present. Boling Consulting Solutions (bcsw.net)
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package meframe
+
+import (
+ "errors"
+ "fmt"
+ "github.com/google/gopacket"
+ . "github.com/opencord/omci-lib-go/v2"
+ me "github.com/opencord/omci-lib-go/v2/generated"
+)
+
+func AttributeValueChangeFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
+ if opt.frameFormat == ExtendedIdent {
+ return nil, errors.New("extended message set for this message type is not supported")
+ }
+ mask, err := checkAttributeMask(m, opt.attributeMask)
+ if err != nil {
+ return nil, err
+ }
+ // Common for all MEs
+ meLayer := &AttributeValueChangeMsg{
+ MeBasePacket: MeBasePacket{
+ EntityClass: m.GetClassID(),
+ EntityInstance: m.GetEntityID(),
+ Extended: opt.frameFormat == ExtendedIdent,
+ },
+ AttributeMask: 0,
+ Attributes: make(me.AttributeValueMap),
+ }
+ // Get payload space available
+ maxPayload := maxPacketAvailable(m, opt)
+ payloadAvailable := int(maxPayload) - 2 // Less attribute mask
+
+ // TODO: Lots of work to do
+
+ fmt.Println(mask, maxPayload, payloadAvailable)
+ return meLayer, errors.New("todo: Not implemented")
+}
diff --git a/vendor/github.com/opencord/omci-lib-go/v2/meframe/me_create.go b/vendor/github.com/opencord/omci-lib-go/v2/meframe/me_create.go
new file mode 100644
index 0000000..42ba2de
--- /dev/null
+++ b/vendor/github.com/opencord/omci-lib-go/v2/meframe/me_create.go
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2018 - present. Boling Consulting Solutions (bcsw.net)
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package meframe
+
+import (
+ "errors"
+ "github.com/google/gopacket"
+ . "github.com/opencord/omci-lib-go/v2"
+ me "github.com/opencord/omci-lib-go/v2/generated"
+)
+
+func CreateRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
+ if opt.frameFormat == ExtendedIdent {
+ return nil, errors.New("extended message set for this message type is not supported")
+ }
+ // NOTE: The OMCI parser does not extract the default values of set-by-create attributes
+ // and are the zero 'default' (or nil) at this time. For this reason, make sure
+ // you specify all non-zero default values and pass them in appropriate
+ meLayer := &CreateRequest{
+ MeBasePacket: MeBasePacket{
+ EntityClass: m.GetClassID(),
+ EntityInstance: m.GetEntityID(),
+ Extended: opt.frameFormat == ExtendedIdent,
+ },
+ Attributes: m.GetAttributeValueMap(),
+ }
+ // Add any missing SetByCreate options if requested
+ if opt.addDefaults {
+ if attrDefs, err := me.GetAttributesDefinitions(m.GetClassID()); err.StatusCode() == me.Success {
+ for index, attr := range attrDefs {
+ if me.SupportsAttributeAccess(attr, me.SetByCreate) {
+ if index == 0 {
+ continue // Skip Entity ID, if it is SetByCreate, they should always specify it
+ }
+ if _, found := meLayer.Attributes[attr.GetName()]; !found {
+ meLayer.Attributes[attr.GetName()] = attr.DefValue
+ }
+ }
+ }
+ }
+ }
+ return meLayer, nil
+}
+
+func CreateResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
+ if opt.frameFormat == ExtendedIdent {
+ return nil, errors.New("extended message set for this message type is not supported")
+ }
+ meLayer := &CreateResponse{
+ MeBasePacket: MeBasePacket{
+ EntityClass: m.GetClassID(),
+ EntityInstance: m.GetEntityID(),
+ Extended: opt.frameFormat == ExtendedIdent,
+ },
+ Result: opt.result,
+ }
+ if meLayer.Result == me.ParameterError {
+ meLayer.AttributeExecutionMask = opt.attrExecutionMask
+ }
+ return meLayer, nil
+}
diff --git a/vendor/github.com/opencord/omci-lib-go/v2/meframe/me_delete.go b/vendor/github.com/opencord/omci-lib-go/v2/meframe/me_delete.go
new file mode 100644
index 0000000..7d3dec6
--- /dev/null
+++ b/vendor/github.com/opencord/omci-lib-go/v2/meframe/me_delete.go
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2018 - present. Boling Consulting Solutions (bcsw.net)
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package meframe
+
+import (
+ "errors"
+ "github.com/google/gopacket"
+ . "github.com/opencord/omci-lib-go/v2"
+ me "github.com/opencord/omci-lib-go/v2/generated"
+)
+
+func DeleteRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
+ if opt.frameFormat == ExtendedIdent {
+ return nil, errors.New("extended message set for this message type is not supported")
+ }
+ meLayer := &DeleteRequest{
+ MeBasePacket: MeBasePacket{
+ EntityClass: m.GetClassID(),
+ EntityInstance: m.GetEntityID(),
+ Extended: opt.frameFormat == ExtendedIdent,
+ },
+ }
+ return meLayer, nil
+}
+
+func DeleteResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
+ if opt.frameFormat == ExtendedIdent {
+ return nil, errors.New("extended message set for this message type is not supported")
+ }
+ meLayer := &DeleteResponse{
+ MeBasePacket: MeBasePacket{
+ EntityClass: m.GetClassID(),
+ EntityInstance: m.GetEntityID(),
+ Extended: opt.frameFormat == ExtendedIdent,
+ },
+ Result: opt.result,
+ }
+ return meLayer, nil
+}
diff --git a/vendor/github.com/opencord/omci-lib-go/v2/meframe/me_get.go b/vendor/github.com/opencord/omci-lib-go/v2/meframe/me_get.go
new file mode 100644
index 0000000..c3fe8a5
--- /dev/null
+++ b/vendor/github.com/opencord/omci-lib-go/v2/meframe/me_get.go
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2018 - present. Boling Consulting Solutions (bcsw.net)
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package meframe
+
+import (
+ "errors"
+ "fmt"
+ "github.com/google/gopacket"
+ . "github.com/opencord/omci-lib-go/v2"
+ me "github.com/opencord/omci-lib-go/v2/generated"
+)
+
+func GetRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
+ // Given mask sent in (could be default of 0xFFFF) get what is allowable.
+ // This will be all allowed if 0xFFFF is passed in, or a subset if a fixed
+ // number of items.
+ maxMask, err := checkAttributeMask(m, opt.attributeMask)
+ if err != nil {
+ return nil, err
+ }
+ // Now scan attributes and reduce mask to only those requested
+ var mask uint16
+ mask, err = calculateAttributeMask(m, maxMask)
+ if err != nil {
+ return nil, err
+ }
+ if mask == 0 {
+ // TODO: Is a Get request with no attributes valid?
+ return nil, errors.New("no attributes requested for GetRequest")
+ }
+ meLayer := &GetRequest{
+ MeBasePacket: MeBasePacket{
+ EntityClass: m.GetClassID(),
+ EntityInstance: m.GetEntityID(),
+ Extended: opt.frameFormat == ExtendedIdent,
+ },
+ AttributeMask: mask,
+ }
+ return meLayer, nil
+}
+
+func GetResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
+ mask, err := checkAttributeMask(m, opt.attributeMask)
+ if err != nil {
+ return nil, err
+ }
+ mask, err = calculateAttributeMask(m, mask)
+ if err != nil {
+ return nil, err
+ }
+ meLayer := &GetResponse{
+ MeBasePacket: MeBasePacket{
+ EntityClass: m.GetClassID(),
+ EntityInstance: m.GetEntityID(),
+ Extended: opt.frameFormat == ExtendedIdent,
+ },
+ Result: opt.result,
+ AttributeMask: 0,
+ Attributes: make(me.AttributeValueMap),
+ }
+ if meLayer.Result == me.AttributeFailure {
+ meLayer.UnsupportedAttributeMask = opt.unsupportedMask
+ meLayer.FailedAttributeMask = opt.attrExecutionMask
+ }
+ // Encode whatever we can
+ if meLayer.Result == me.Success || meLayer.Result == me.AttributeFailure {
+ // Encode results
+ // Get payload space available
+ maxPayload := maxPacketAvailable(m, opt)
+ payloadAvailable := int(maxPayload) - 2 - 4 // Less attribute mask and attribute error encoding
+ meDefinition := m.GetManagedEntityDefinition()
+ attrDefs := meDefinition.GetAttributeDefinitions()
+ attrMap := m.GetAttributeValueMap()
+
+ if mask != 0 {
+ // Iterate down the attributes (Attribute 0 is the ManagedEntity ID)
+ var attrIndex uint
+ for attrIndex = 1; attrIndex <= 16; attrIndex++ {
+ // Is this attribute requested
+ if mask&(1<<(16-attrIndex)) != 0 {
+ // Get definitions since we need the name
+ attrDef, ok := attrDefs[attrIndex]
+ if !ok {
+ msg := fmt.Sprintf("Unexpected error, index %v not valued for ME %v",
+ attrIndex, meDefinition.GetName())
+ return nil, errors.New(msg)
+ }
+ var attrValue interface{}
+ attrValue, ok = attrMap[attrDef.Name]
+ if !ok {
+ msg := fmt.Sprintf("Unexpected error, attribute %v not provided in ME %v: %v",
+ attrDef.GetName(), meDefinition.GetName(), m)
+ return nil, errors.New(msg)
+ }
+ // Is space available?
+ if attrDef.Size <= payloadAvailable {
+ // Mark bit handled
+ mask &= ^attrDef.Mask
+ meLayer.AttributeMask |= attrDef.Mask
+ meLayer.Attributes[attrDef.Name] = attrValue
+ payloadAvailable -= attrDef.Size
+
+ } else if opt.failIfTruncated {
+ // TODO: Should we set truncate?
+ msg := fmt.Sprintf("out-of-space. Cannot fit attribute %v into GetResponse message",
+ attrDef.GetName())
+ return nil, me.NewMessageTruncatedError(msg)
+ } else {
+ // Add to existing 'failed' mask and update result
+ meLayer.FailedAttributeMask |= attrDef.Mask
+ meLayer.Result = me.AttributeFailure
+ }
+ }
+ }
+ }
+ }
+ return meLayer, nil
+}
diff --git a/vendor/github.com/opencord/omci-lib-go/v2/meframe/me_getcurrent.go b/vendor/github.com/opencord/omci-lib-go/v2/meframe/me_getcurrent.go
new file mode 100644
index 0000000..2589bbb
--- /dev/null
+++ b/vendor/github.com/opencord/omci-lib-go/v2/meframe/me_getcurrent.go
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2018 - present. Boling Consulting Solutions (bcsw.net)
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package meframe
+
+import (
+ "errors"
+ "fmt"
+ "github.com/google/gopacket"
+ . "github.com/opencord/omci-lib-go/v2"
+ me "github.com/opencord/omci-lib-go/v2/generated"
+)
+
+func GetCurrentDataRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
+ if opt.frameFormat == ExtendedIdent {
+ return nil, errors.New("extended message set for this message type is not supported")
+ }
+ mask, err := checkAttributeMask(m, opt.attributeMask)
+ if err != nil {
+ return nil, err
+ }
+ // Common for all MEs
+ meLayer := &GetCurrentDataRequest{
+ MeBasePacket: MeBasePacket{
+ EntityClass: m.GetClassID(),
+ EntityInstance: m.GetEntityID(),
+ Extended: opt.frameFormat == ExtendedIdent,
+ },
+ }
+ // Get payload space available
+ maxPayload := maxPacketAvailable(m, opt)
+
+ // TODO: Lots of work to do
+
+ fmt.Println(mask, maxPayload)
+ return meLayer, errors.New("todo: Not implemented")
+}
+
+func GetCurrentDataResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
+ if opt.frameFormat == ExtendedIdent {
+ return nil, errors.New("extended message set for this message type is not supported")
+ }
+ mask, err := checkAttributeMask(m, opt.attributeMask)
+ if err != nil {
+ return nil, err
+ }
+ // Common for all MEs
+ meLayer := &GetCurrentDataResponse{
+ MeBasePacket: MeBasePacket{
+ EntityClass: m.GetClassID(),
+ EntityInstance: m.GetEntityID(),
+ Extended: opt.frameFormat == ExtendedIdent,
+ },
+ }
+ // Get payload space available
+ maxPayload := maxPacketAvailable(m, opt)
+
+ // TODO: Lots of work to do
+
+ fmt.Println(mask, maxPayload)
+ return meLayer, errors.New("todo: Not implemented")
+}
diff --git a/vendor/github.com/opencord/omci-lib-go/v2/meframe/me_getnext.go b/vendor/github.com/opencord/omci-lib-go/v2/meframe/me_getnext.go
new file mode 100644
index 0000000..b4b2a5a
--- /dev/null
+++ b/vendor/github.com/opencord/omci-lib-go/v2/meframe/me_getnext.go
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2018 - present. Boling Consulting Solutions (bcsw.net)
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package meframe
+
+import (
+ "errors"
+ "fmt"
+ "github.com/google/gopacket"
+ . "github.com/opencord/omci-lib-go/v2"
+ me "github.com/opencord/omci-lib-go/v2/generated"
+)
+
+func GetNextRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
+ if opt.frameFormat == ExtendedIdent {
+ return nil, errors.New("extended message set for this message type is not supported")
+ }
+ // Validate attribute mask
+ mask, err := checkAttributeMask(m, opt.attributeMask)
+ if err != nil {
+ return nil, err
+ }
+ // Now scan attributes and reduce mask to only those requested
+ mask, err = calculateAttributeMask(m, mask)
+ if err != nil {
+ return nil, err
+ }
+ if mask == 0 {
+ return nil, errors.New("no attributes requested for GetNextRequest")
+ }
+ // TODO: If more than one attribute or the attribute requested is not a table attribute, return an error
+ // Common for all MEs
+ meLayer := &GetNextRequest{
+ MeBasePacket: MeBasePacket{
+ EntityClass: m.GetClassID(),
+ EntityInstance: m.GetEntityID(),
+ Extended: opt.frameFormat == ExtendedIdent,
+ },
+ AttributeMask: mask,
+ SequenceNumber: opt.sequenceNumberCountOrSize,
+ }
+ return meLayer, nil
+}
+
+func GetNextResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
+ if opt.frameFormat == ExtendedIdent {
+ return nil, errors.New("extended message set for this message type is not supported")
+ }
+ // Validate attribute mask
+ mask, err := checkAttributeMask(m, opt.attributeMask)
+ if err != nil {
+ return nil, err
+ }
+ mask, err = calculateAttributeMask(m, mask)
+ if err != nil {
+ return nil, err
+ }
+ //
+ // Common for all MEs
+ meLayer := &GetNextResponse{
+ MeBasePacket: MeBasePacket{
+ EntityClass: m.GetClassID(),
+ EntityInstance: m.GetEntityID(),
+ Extended: opt.frameFormat == ExtendedIdent,
+ },
+ Result: opt.result,
+ AttributeMask: 0,
+ Attributes: make(me.AttributeValueMap),
+ }
+ if meLayer.Result == me.Success {
+ // Get payload space available
+ maxPayload := maxPacketAvailable(m, opt)
+ payloadAvailable := int(maxPayload) - 3 // Less results and attribute mask
+ meDefinition := m.GetManagedEntityDefinition()
+ attrDefs := meDefinition.GetAttributeDefinitions()
+ attrMap := m.GetAttributeValueMap()
+
+ if mask == 0 {
+ return nil, errors.New("no attributes requested for GetNextResponse")
+ }
+ // TODO: If more than one attribute or the attribute requested is not a table attribute, return an error
+ // Iterate down the attributes (Attribute 0 is the ManagedEntity ID)
+ var attrIndex uint
+ for attrIndex = 1; attrIndex <= 16; attrIndex++ {
+ // Is this attribute requested
+ if mask&(1<<(16-attrIndex)) != 0 {
+ // Get definitions since we need the name
+ attrDef, ok := attrDefs[attrIndex]
+ if !ok {
+ msg := fmt.Sprintf("Unexpected error, index %v not valued for ME %v",
+ attrIndex, meDefinition.GetName())
+ return nil, errors.New(msg)
+ }
+ var attrValue interface{}
+ attrValue, ok = attrMap[attrDef.Name]
+ if !ok || attrValue == nil {
+ msg := fmt.Sprintf("Unexpected error, attribute %v not provided in ME %v: %v",
+ attrDef.GetName(), meDefinition.GetName(), m)
+ return nil, errors.New(msg)
+ }
+ // Is space available?
+ if attrDef.Size <= payloadAvailable {
+ // Mark bit handled
+ mask &= ^attrDef.Mask
+ meLayer.AttributeMask |= attrDef.Mask
+ meLayer.Attributes[attrDef.Name] = attrValue
+ payloadAvailable -= attrDef.Size
+ } else {
+ // TODO: Should we set truncate?
+ msg := fmt.Sprintf("out-of-space. Cannot fit attribute %v into GetNextResponse message",
+ attrDef.GetName())
+ return nil, me.NewMessageTruncatedError(msg)
+ }
+ }
+ }
+ }
+ return meLayer, nil
+}
diff --git a/vendor/github.com/opencord/omci-lib-go/v2/meframe/me_mibreset.go b/vendor/github.com/opencord/omci-lib-go/v2/meframe/me_mibreset.go
new file mode 100644
index 0000000..1a431ac
--- /dev/null
+++ b/vendor/github.com/opencord/omci-lib-go/v2/meframe/me_mibreset.go
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2018 - present. Boling Consulting Solutions (bcsw.net)
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package meframe
+
+import (
+ "errors"
+ "github.com/google/gopacket"
+ . "github.com/opencord/omci-lib-go/v2"
+ me "github.com/opencord/omci-lib-go/v2/generated"
+)
+
+func MibResetRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
+ if opt.frameFormat == ExtendedIdent {
+ return nil, errors.New("extended message set for this message type is not supported")
+ }
+ // Common for all MEs
+ meLayer := &MibResetRequest{
+ MeBasePacket: MeBasePacket{
+ EntityClass: m.GetClassID(),
+ EntityInstance: m.GetEntityID(),
+ Extended: opt.frameFormat == ExtendedIdent,
+ },
+ }
+ return meLayer, nil
+}
+
+func MibResetResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
+ if opt.frameFormat == ExtendedIdent {
+ return nil, errors.New("extended message set for this message type is not supported")
+ }
+ // Common for all MEs
+ meLayer := &MibResetResponse{
+ MeBasePacket: MeBasePacket{
+ EntityClass: m.GetClassID(),
+ EntityInstance: m.GetEntityID(),
+ Extended: opt.frameFormat == ExtendedIdent,
+ },
+ Result: opt.result,
+ }
+ return meLayer, nil
+}
diff --git a/vendor/github.com/opencord/omci-lib-go/v2/meframe/me_mibupload.go b/vendor/github.com/opencord/omci-lib-go/v2/meframe/me_mibupload.go
new file mode 100644
index 0000000..81eb2ce
--- /dev/null
+++ b/vendor/github.com/opencord/omci-lib-go/v2/meframe/me_mibupload.go
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2018 - present. Boling Consulting Solutions (bcsw.net)
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package meframe
+
+import (
+ "errors"
+ "github.com/google/gopacket"
+ . "github.com/opencord/omci-lib-go/v2"
+ me "github.com/opencord/omci-lib-go/v2/generated"
+)
+
+func MibUploadRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
+ if opt.frameFormat == ExtendedIdent {
+ return nil, errors.New("extended message set for this message type is not supported")
+ }
+ // Common for all MEs
+ meLayer := &MibUploadRequest{
+ MeBasePacket: MeBasePacket{
+ EntityClass: m.GetClassID(),
+ EntityInstance: 0,
+ Extended: opt.frameFormat == ExtendedIdent,
+ },
+ }
+ return meLayer, nil
+}
+
+func MibUploadResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
+ if opt.frameFormat == ExtendedIdent {
+ return nil, errors.New("extended message set for this message type is not supported")
+ }
+ // Common for all MEs
+ meLayer := &MibUploadResponse{
+ MeBasePacket: MeBasePacket{
+ EntityClass: m.GetClassID(),
+ EntityInstance: 0,
+ Extended: opt.frameFormat == ExtendedIdent,
+ },
+ NumberOfCommands: opt.sequenceNumberCountOrSize,
+ }
+ return meLayer, nil
+}
+
+func MibUploadNextRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
+ if opt.frameFormat == ExtendedIdent {
+ return nil, errors.New("extended message set for this message type is not supported")
+ }
+ // Common for all MEs
+ meLayer := &MibUploadNextRequest{
+ MeBasePacket: MeBasePacket{
+ EntityClass: m.GetClassID(),
+ EntityInstance: 0,
+ Extended: opt.frameFormat == ExtendedIdent,
+ },
+ CommandSequenceNumber: opt.sequenceNumberCountOrSize,
+ }
+ return meLayer, nil
+}
+
+func MibUploadNextResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
+ if opt.frameFormat == ExtendedIdent {
+ return nil, errors.New("extended message set for this message type is not supported")
+ }
+ // Common for all MEs
+ meLayer := &MibUploadNextResponse{
+ MeBasePacket: MeBasePacket{
+ EntityClass: m.GetClassID(),
+ EntityInstance: m.GetEntityID(),
+ Extended: opt.frameFormat == ExtendedIdent,
+ },
+ }
+ if opt.payload == nil {
+ // Shortcut used to specify the request sequence number is out of range, encode
+ // a ME instance with class ID of zero to specify this per ITU G.988
+ meDef := me.ManagedEntityDefinition{
+ Name: "InvalidSequenceNumberManagedEntity",
+ ClassID: me.ClassID(0),
+ MessageTypes: nil,
+ AttributeDefinitions: make(me.AttributeDefinitionMap),
+ }
+ opt.payload, _ = me.NewManagedEntity(meDef)
+ }
+ if _, ok := opt.payload.(*[]me.ManagedEntity); ok {
+ if opt.frameFormat == BaselineIdent {
+ return nil, errors.New("invalid payload for Baseline message")
+ }
+ // TODO: List of MEs. valid for extended messages only
+ } else if managedEntity, ok := opt.payload.(*me.ManagedEntity); ok {
+ // Single ME
+ meLayer.ReportedME = *managedEntity
+ } else {
+ return nil, errors.New("invalid payload for MibUploadNextResponse frame")
+ }
+ return meLayer, nil
+}
diff --git a/vendor/github.com/opencord/omci-lib-go/v2/meframe/me_reboot.go b/vendor/github.com/opencord/omci-lib-go/v2/meframe/me_reboot.go
new file mode 100644
index 0000000..f98a3a6
--- /dev/null
+++ b/vendor/github.com/opencord/omci-lib-go/v2/meframe/me_reboot.go
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2018 - present. Boling Consulting Solutions (bcsw.net)
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package meframe
+
+import (
+ "errors"
+ "github.com/google/gopacket"
+ . "github.com/opencord/omci-lib-go/v2"
+ me "github.com/opencord/omci-lib-go/v2/generated"
+)
+
+func RebootRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
+ if opt.frameFormat == ExtendedIdent {
+ return nil, errors.New("extended message set for this message type is not supported")
+ }
+ // Common for all MEs
+ meLayer := &RebootRequest{
+ MeBasePacket: MeBasePacket{
+ EntityClass: m.GetClassID(),
+ EntityInstance: m.GetEntityID(),
+ Extended: opt.frameFormat == ExtendedIdent,
+ },
+ RebootCondition: opt.mode,
+ }
+ return meLayer, nil
+}
+
+func RebootResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
+ if opt.frameFormat == ExtendedIdent {
+ return nil, errors.New("extended message set for this message type is not supported")
+ }
+ // Common for all MEs
+ meLayer := &RebootResponse{
+ MeBasePacket: MeBasePacket{
+ EntityClass: m.GetClassID(),
+ EntityInstance: m.GetEntityID(),
+ Extended: opt.frameFormat == ExtendedIdent,
+ },
+ Result: opt.result,
+ }
+ return meLayer, nil
+}
diff --git a/vendor/github.com/opencord/omci-lib-go/v2/meframe/me_set.go b/vendor/github.com/opencord/omci-lib-go/v2/meframe/me_set.go
new file mode 100644
index 0000000..1f126fa
--- /dev/null
+++ b/vendor/github.com/opencord/omci-lib-go/v2/meframe/me_set.go
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2018 - present. Boling Consulting Solutions (bcsw.net)
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package meframe
+
+import (
+ "errors"
+ "fmt"
+ "github.com/google/gopacket"
+ . "github.com/opencord/omci-lib-go/v2"
+ me "github.com/opencord/omci-lib-go/v2/generated"
+)
+
+func SetRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
+ mask, err := checkAttributeMask(m, opt.attributeMask)
+ if err != nil {
+ return nil, err
+ }
+ mask, err = calculateAttributeMask(m, mask)
+ if err != nil {
+ return nil, err
+ }
+ meDefinition := m.GetManagedEntityDefinition()
+ attrDefs := meDefinition.GetAttributeDefinitions()
+ attrMap := m.GetAttributeValueMap()
+
+ // Get payload space available
+ maxPayload := maxPacketAvailable(m, opt)
+ payloadAvailable := int(maxPayload) - 2 // Less attribute mask
+ if opt.frameFormat == ExtendedIdent {
+ return nil, errors.New("extended message set for this message type is not supported")
+ // payloadAvailable -= 2 // Less length
+ }
+ meLayer := &SetRequest{
+ MeBasePacket: MeBasePacket{
+ EntityClass: m.GetClassID(),
+ EntityInstance: m.GetEntityID(),
+ Extended: opt.frameFormat == ExtendedIdent,
+ },
+ AttributeMask: 0,
+ Attributes: make(me.AttributeValueMap),
+ }
+ for mask != 0 {
+ // Iterate down the attributes (Attribute 0 is the ManagedEntity ID)
+ var attrIndex uint
+ for attrIndex = 1; attrIndex <= 16; attrIndex++ {
+ // Is this attribute requested
+ if mask&(1<<(16-attrIndex)) != 0 {
+ // Get definitions since we need the name
+ attrDef, ok := attrDefs[attrIndex]
+ if !ok {
+ msg := fmt.Sprintf("Unexpected error, index %v not valued for ME %v",
+ attrIndex, meDefinition.GetName())
+ return nil, errors.New(msg)
+ }
+ var attrValue interface{}
+ attrValue, ok = attrMap[attrDef.Name]
+ if !ok {
+ msg := fmt.Sprintf("Unexpected error, attribute %v not provided in ME %v: %v",
+ attrDef.GetName(), meDefinition.GetName(), m)
+ return nil, errors.New(msg)
+ }
+ // Is space available?
+ if attrDef.Size <= payloadAvailable {
+ // Mark bit handled
+ mask &= ^attrDef.Mask
+ meLayer.AttributeMask |= attrDef.Mask
+ meLayer.Attributes[attrDef.Name] = attrValue
+ payloadAvailable -= attrDef.Size
+ } else {
+ // TODO: Should we set truncate?
+ msg := fmt.Sprintf("out-of-space. Cannot fit attribute %v into SetRequest message",
+ attrDef.GetName())
+ return nil, me.NewMessageTruncatedError(msg)
+ }
+ }
+ }
+ }
+ if meLayer.AttributeMask == 0 {
+ // TODO: Is a set request with no attributes valid?
+ return nil, errors.New("no attributes encoded for SetRequest")
+ }
+ return meLayer, nil
+}
+
+func SetResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
+ if opt.frameFormat == ExtendedIdent {
+ return nil, errors.New("extended message set for this message type is not supported")
+ }
+ meLayer := &SetResponse{
+ MeBasePacket: MeBasePacket{
+ EntityClass: m.GetClassID(),
+ EntityInstance: m.GetEntityID(),
+ Extended: opt.frameFormat == ExtendedIdent,
+ },
+ Result: opt.result,
+ }
+ if meLayer.Result == me.AttributeFailure {
+ meLayer.UnsupportedAttributeMask = opt.unsupportedMask
+ meLayer.FailedAttributeMask = opt.attrExecutionMask
+ }
+ return meLayer, nil
+}
diff --git a/vendor/github.com/opencord/omci-lib-go/v2/meframe/me_setable.go b/vendor/github.com/opencord/omci-lib-go/v2/meframe/me_setable.go
new file mode 100644
index 0000000..b5b4a8c
--- /dev/null
+++ b/vendor/github.com/opencord/omci-lib-go/v2/meframe/me_setable.go
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2018 - present. Boling Consulting Solutions (bcsw.net)
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package meframe
+
+import (
+ "errors"
+ "fmt"
+ "github.com/google/gopacket"
+ . "github.com/opencord/omci-lib-go/v2"
+ me "github.com/opencord/omci-lib-go/v2/generated"
+)
+
+func SetTableRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
+ if opt.frameFormat != ExtendedIdent {
+ return nil, errors.New("set table message type only supported with Extended OMCI Messaging")
+ }
+ if opt.frameFormat == ExtendedIdent {
+ return nil, errors.New("extended message set for this message type is not supported")
+ }
+ mask, err := checkAttributeMask(m, opt.attributeMask)
+ if err != nil {
+ return nil, err
+ }
+ // Common for all MEs
+ meLayer := &SetTableRequest{
+ MeBasePacket: MeBasePacket{
+ EntityClass: m.GetClassID(),
+ EntityInstance: m.GetEntityID(),
+ Extended: opt.frameFormat == ExtendedIdent,
+ },
+ }
+ // Get payload space available
+ maxPayload := maxPacketAvailable(m, opt)
+
+ // TODO: Lots of work to do
+
+ fmt.Println(mask, maxPayload)
+ return meLayer, errors.New("todo: Not implemented")
+}
+
+func SetTableResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
+ if opt.frameFormat != ExtendedIdent {
+ return nil, errors.New("set table message type only supported with Extended OMCI Message Set")
+ }
+ if opt.frameFormat == ExtendedIdent {
+ return nil, errors.New("extended message set for this message type is not supported")
+ }
+ mask, err := checkAttributeMask(m, opt.attributeMask)
+ if err != nil {
+ return nil, err
+ }
+ // Common for all MEs
+ meLayer := &SetTableResponse{
+ MeBasePacket: MeBasePacket{
+ EntityClass: m.GetClassID(),
+ EntityInstance: m.GetEntityID(),
+ Extended: true,
+ },
+ }
+ // Get payload space available
+ maxPayload := maxPacketAvailable(m, opt)
+
+ // TODO: Lots of work to do
+
+ fmt.Println(mask, maxPayload)
+ return meLayer, errors.New("todo: Not implemented")
+}
diff --git a/vendor/github.com/opencord/omci-lib-go/v2/meframe/me_software.go b/vendor/github.com/opencord/omci-lib-go/v2/meframe/me_software.go
new file mode 100644
index 0000000..249baba
--- /dev/null
+++ b/vendor/github.com/opencord/omci-lib-go/v2/meframe/me_software.go
@@ -0,0 +1,262 @@
+/*
+ * Copyright (c) 2018 - present. Boling Consulting Solutions (bcsw.net)
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package meframe
+
+import (
+ "errors"
+ "fmt"
+ "github.com/google/gopacket"
+ . "github.com/opencord/omci-lib-go/v2"
+ me "github.com/opencord/omci-lib-go/v2/generated"
+)
+
+func StartSoftwareDownloadRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
+ if opt.frameFormat == ExtendedIdent {
+ return nil, errors.New("extended message set for this message type is not supported")
+ }
+ // Common for all MEs
+ meLayer := &StartSoftwareDownloadRequest{
+ MeBasePacket: MeBasePacket{
+ EntityClass: m.GetClassID(),
+ EntityInstance: m.GetEntityID(),
+ Extended: opt.frameFormat == ExtendedIdent,
+ },
+ WindowSize: opt.software.WindowSize,
+ ImageSize: opt.software.ImageSize,
+ NumberOfCircuitPacks: byte(len(opt.software.CircuitPacks)),
+ CircuitPacks: opt.software.CircuitPacks,
+ }
+ // TODO: Add length check to insure we do not exceed maximum packet size
+ // payloadAvailable := int(maxPacketAvailable(m, opt))
+ payloadAvailable := 2
+ sizeNeeded := 1
+ if sizeNeeded > payloadAvailable {
+ // TODO: Should we set truncate?
+ msg := "out-of-space. Cannot fit Circuit Pack instances into Start Software Download Request message"
+ return nil, me.NewMessageTruncatedError(msg)
+ }
+ return meLayer, nil
+}
+
+func StartSoftwareDownloadResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
+ if opt.frameFormat == ExtendedIdent {
+ return nil, errors.New("extended message set for this message type is not supported")
+ }
+ // Common for all MEs
+ meLayer := &StartSoftwareDownloadResponse{
+ MeBasePacket: MeBasePacket{
+ EntityClass: m.GetClassID(),
+ EntityInstance: m.GetEntityID(),
+ Extended: opt.frameFormat == ExtendedIdent,
+ },
+ WindowSize: opt.software.WindowSize,
+ NumberOfInstances: byte(len(opt.software.CircuitPacks)),
+ MeResults: opt.software.Results,
+ }
+ // TODO: Add length check to insure we do not exceed maximum packet size
+ // payloadAvailable := int(maxPacketAvailable(m, opt))
+ payloadAvailable := 2
+ sizeNeeded := 1
+ if sizeNeeded > payloadAvailable {
+ // TODO: Should we set truncate?
+ msg := "out-of-space. Cannot fit Results into Start Software Download Response message"
+ return nil, me.NewMessageTruncatedError(msg)
+ }
+ return meLayer, nil
+}
+
+func DownloadSectionRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
+ if opt.software.Data == nil {
+ return nil, me.NewNonStatusError("Software image data missing")
+ }
+ // Common for all MEs
+ meLayer := &DownloadSectionRequest{
+ MeBasePacket: MeBasePacket{
+ EntityClass: m.GetClassID(),
+ EntityInstance: m.GetEntityID(),
+ Extended: opt.frameFormat == ExtendedIdent,
+ },
+ SectionNumber: opt.software.SectionNumber,
+ SectionData: opt.software.Data,
+ }
+ return meLayer, nil
+}
+
+func DownloadSectionResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
+ // Common for all MEs
+ meLayer := &DownloadSectionResponse{
+ MeBasePacket: MeBasePacket{
+ EntityClass: m.GetClassID(),
+ EntityInstance: m.GetEntityID(),
+ Extended: opt.frameFormat == ExtendedIdent,
+ },
+ Result: opt.result,
+ SectionNumber: opt.software.SectionNumber,
+ }
+ return meLayer, nil
+}
+
+func EndSoftwareDownloadRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
+ if opt.frameFormat == ExtendedIdent {
+ return nil, errors.New("extended message set for this message type is not supported")
+ }
+ mask, err := checkAttributeMask(m, opt.attributeMask)
+ if err != nil {
+ return nil, err
+ }
+ // Common for all MEs
+ meLayer := &EndSoftwareDownloadRequest{
+ MeBasePacket: MeBasePacket{
+ EntityClass: m.GetClassID(),
+ EntityInstance: m.GetEntityID(),
+ Extended: opt.frameFormat == ExtendedIdent,
+ },
+ }
+ // Get payload space available
+ maxPayload := maxPacketAvailable(m, opt)
+
+ // TODO: Lots of work to do
+
+ fmt.Println(mask, maxPayload)
+ return meLayer, errors.New("todo: Not implemented")
+}
+
+func EndSoftwareDownloadResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
+ if opt.frameFormat == ExtendedIdent {
+ return nil, errors.New("extended message set for this message type is not supported")
+ }
+ mask, err := checkAttributeMask(m, opt.attributeMask)
+ if err != nil {
+ return nil, err
+ }
+ // Common for all MEs
+ meLayer := &EndSoftwareDownloadResponse{
+ MeBasePacket: MeBasePacket{
+ EntityClass: m.GetClassID(),
+ EntityInstance: m.GetEntityID(),
+ Extended: opt.frameFormat == ExtendedIdent,
+ },
+ }
+ // Get payload space available
+ maxPayload := maxPacketAvailable(m, opt)
+
+ // TODO: Lots of work to do
+
+ fmt.Println(mask, maxPayload)
+ return meLayer, errors.New("todo: Not implemented")
+}
+
+func ActivateSoftwareRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
+ if opt.frameFormat == ExtendedIdent {
+ return nil, errors.New("extended message set for this message type is not supported")
+ }
+ mask, err := checkAttributeMask(m, opt.attributeMask)
+ if err != nil {
+ return nil, err
+ }
+ // Common for all MEs
+ meLayer := &ActivateSoftwareRequest{
+ MeBasePacket: MeBasePacket{
+ EntityClass: m.GetClassID(),
+ EntityInstance: m.GetEntityID(),
+ Extended: opt.frameFormat == ExtendedIdent,
+ },
+ }
+ // Get payload space available
+ maxPayload := maxPacketAvailable(m, opt)
+
+ // TODO: Lots of work to do
+
+ fmt.Println(mask, maxPayload)
+ return meLayer, errors.New("todo: Not implemented")
+}
+
+func ActivateSoftwareResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
+ if opt.frameFormat == ExtendedIdent {
+ return nil, errors.New("extended message set for this message type is not supported")
+ }
+ mask, err := checkAttributeMask(m, opt.attributeMask)
+ if err != nil {
+ return nil, err
+ }
+ // Common for all MEs
+ meLayer := &ActivateSoftwareResponse{
+ MeBasePacket: MeBasePacket{
+ EntityClass: m.GetClassID(),
+ EntityInstance: m.GetEntityID(),
+ Extended: opt.frameFormat == ExtendedIdent,
+ },
+ }
+ // Get payload space available
+ maxPayload := maxPacketAvailable(m, opt)
+
+ // TODO: Lots of work to do
+
+ fmt.Println(mask, maxPayload)
+ return meLayer, errors.New("todo: Not implemented")
+}
+
+func CommitSoftwareRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
+ if opt.frameFormat == ExtendedIdent {
+ return nil, errors.New("extended message set for this message type is not supported")
+ }
+ mask, err := checkAttributeMask(m, opt.attributeMask)
+ if err != nil {
+ return nil, err
+ }
+ // Common for all MEs
+ meLayer := &CommitSoftwareRequest{
+ MeBasePacket: MeBasePacket{
+ EntityClass: m.GetClassID(),
+ EntityInstance: m.GetEntityID(),
+ Extended: opt.frameFormat == ExtendedIdent,
+ },
+ }
+ // Get payload space available
+ maxPayload := maxPacketAvailable(m, opt)
+
+ // TODO: Lots of work to do
+
+ fmt.Println(mask, maxPayload)
+ return meLayer, errors.New("todo: Not implemented")
+}
+
+func CommitSoftwareResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
+ if opt.frameFormat == ExtendedIdent {
+ return nil, errors.New("extended message set for this message type is not supported")
+ }
+ mask, err := checkAttributeMask(m, opt.attributeMask)
+ if err != nil {
+ return nil, err
+ }
+ // Common for all MEs
+ meLayer := &CommitSoftwareResponse{
+ MeBasePacket: MeBasePacket{
+ EntityClass: m.GetClassID(),
+ EntityInstance: m.GetEntityID(),
+ Extended: opt.frameFormat == ExtendedIdent,
+ },
+ }
+ // Get payload space available
+ maxPayload := maxPacketAvailable(m, opt)
+
+ // TODO: Lots of work to do
+
+ fmt.Println(mask, maxPayload)
+ return meLayer, errors.New("todo: Not implemented")
+}
diff --git a/vendor/github.com/opencord/omci-lib-go/v2/meframe/me_synctime.go b/vendor/github.com/opencord/omci-lib-go/v2/meframe/me_synctime.go
new file mode 100644
index 0000000..1aa1e06
--- /dev/null
+++ b/vendor/github.com/opencord/omci-lib-go/v2/meframe/me_synctime.go
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2018 - present. Boling Consulting Solutions (bcsw.net)
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package meframe
+
+import (
+ "errors"
+ "github.com/google/gopacket"
+ . "github.com/opencord/omci-lib-go/v2"
+ me "github.com/opencord/omci-lib-go/v2/generated"
+ "time"
+)
+
+func SynchronizeTimeRequestFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
+ if opt.frameFormat == ExtendedIdent {
+ return nil, errors.New("extended message set for this message type is not supported")
+ }
+ // Common for all MEs
+ meLayer := &SynchronizeTimeRequest{
+ MeBasePacket: MeBasePacket{
+ EntityClass: m.GetClassID(),
+ EntityInstance: m.GetEntityID(),
+ Extended: opt.frameFormat == ExtendedIdent,
+ },
+ }
+ // Decode payload option. If nil, no timestamp provided
+ if timestamp, ok := opt.payload.(int64); ok {
+ tm := time.Unix(timestamp, 0)
+ meLayer.Year = uint16(tm.UTC().Year())
+ meLayer.Month = uint8(tm.UTC().Month())
+ meLayer.Day = uint8(tm.UTC().Day())
+ meLayer.Hour = uint8(tm.UTC().Hour())
+ meLayer.Minute = uint8(tm.UTC().Minute())
+ meLayer.Second = uint8(tm.UTC().Second())
+ }
+ return meLayer, nil
+}
+
+func SynchronizeTimeResponseFrame(m *me.ManagedEntity, opt options) (gopacket.SerializableLayer, error) {
+ if opt.frameFormat == ExtendedIdent {
+ return nil, errors.New("extended message set for this message type is not supported")
+ }
+ // Common for all MEs
+ meLayer := &SynchronizeTimeResponse{
+ MeBasePacket: MeBasePacket{
+ EntityClass: m.GetClassID(),
+ EntityInstance: m.GetEntityID(),
+ Extended: opt.frameFormat == ExtendedIdent,
+ },
+ Result: opt.result,
+ SuccessResults: opt.mode,
+ }
+ return meLayer, nil
+}
diff --git a/vendor/github.com/opencord/omci-lib-go/v2/meframe/meframe.go b/vendor/github.com/opencord/omci-lib-go/v2/meframe/meframe.go
new file mode 100644
index 0000000..e9a55ae
--- /dev/null
+++ b/vendor/github.com/opencord/omci-lib-go/v2/meframe/meframe.go
@@ -0,0 +1,415 @@
+/*
+ * Copyright (c) 2018 - present. Boling Consulting Solutions (bcsw.net)
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package meframe
+
+import (
+ "errors"
+ "fmt"
+ "github.com/deckarep/golang-set"
+ "github.com/google/gopacket"
+ . "github.com/opencord/omci-lib-go/v2"
+ me "github.com/opencord/omci-lib-go/v2/generated"
+)
+
+var encoderMap map[MessageType]func(*me.ManagedEntity, options) (gopacket.SerializableLayer, error)
+
+func init() {
+ encoderMap = make(map[MessageType]func(*me.ManagedEntity, options) (gopacket.SerializableLayer, error))
+
+ encoderMap[CreateRequestType] = CreateRequestFrame
+ encoderMap[DeleteRequestType] = DeleteRequestFrame
+ encoderMap[SetRequestType] = SetRequestFrame
+ encoderMap[GetRequestType] = GetRequestFrame
+ encoderMap[GetAllAlarmsRequestType] = GetAllAlarmsRequestFrame
+ encoderMap[GetAllAlarmsNextRequestType] = GetAllAlarmsNextRequestFrame
+ encoderMap[MibUploadRequestType] = MibUploadRequestFrame
+ encoderMap[MibUploadNextRequestType] = MibUploadNextRequestFrame
+ encoderMap[MibResetRequestType] = MibResetRequestFrame
+ //encoderMap[TestRequestType] = TestRequestFrame
+ encoderMap[StartSoftwareDownloadRequestType] = StartSoftwareDownloadRequestFrame
+ encoderMap[DownloadSectionRequestType] = DownloadSectionRequestFrame
+ encoderMap[EndSoftwareDownloadRequestType] = EndSoftwareDownloadRequestFrame
+ encoderMap[ActivateSoftwareRequestType] = ActivateSoftwareRequestFrame
+ encoderMap[CommitSoftwareRequestType] = CommitSoftwareRequestFrame
+ encoderMap[SynchronizeTimeRequestType] = SynchronizeTimeRequestFrame
+ encoderMap[RebootRequestType] = RebootRequestFrame
+ encoderMap[GetNextRequestType] = GetNextRequestFrame
+ encoderMap[GetCurrentDataRequestType] = GetCurrentDataRequestFrame
+ encoderMap[SetTableRequestType] = SetTableRequestFrame
+ encoderMap[CreateResponseType] = CreateResponseFrame
+ encoderMap[DeleteResponseType] = DeleteResponseFrame
+ encoderMap[SetResponseType] = SetResponseFrame
+ encoderMap[GetResponseType] = GetResponseFrame
+ encoderMap[GetAllAlarmsResponseType] = GetAllAlarmsResponseFrame
+ encoderMap[GetAllAlarmsNextResponseType] = GetAllAlarmsNextResponseFrame
+ encoderMap[MibUploadResponseType] = MibUploadResponseFrame
+ encoderMap[MibUploadNextResponseType] = MibUploadNextResponseFrame
+ encoderMap[MibResetResponseType] = MibResetResponseFrame
+ //encoderMap[TestResponseType] = TestResponseFrame
+ encoderMap[StartSoftwareDownloadResponseType] = StartSoftwareDownloadResponseFrame
+ encoderMap[DownloadSectionResponseType] = DownloadSectionResponseFrame
+ encoderMap[EndSoftwareDownloadResponseType] = EndSoftwareDownloadResponseFrame
+ encoderMap[ActivateSoftwareResponseType] = ActivateSoftwareResponseFrame
+ encoderMap[CommitSoftwareResponseType] = CommitSoftwareResponseFrame
+ encoderMap[SynchronizeTimeResponseType] = SynchronizeTimeResponseFrame
+ encoderMap[RebootResponseType] = RebootResponseFrame
+ encoderMap[GetNextResponseType] = GetNextResponseFrame
+ encoderMap[GetCurrentDataResponseType] = GetCurrentDataResponseFrame
+ encoderMap[SetTableResponseType] = SetTableResponseFrame
+ encoderMap[AlarmNotificationType] = AlarmNotificationFrame
+ encoderMap[AttributeValueChangeType] = AttributeValueChangeFrame
+ //encoderMap[TestResultType] = TestResultFrame
+}
+
+type options struct {
+ frameFormat DeviceIdent
+ failIfTruncated bool
+ attributeMask uint16
+ result me.Results // Common for many responses
+ attrExecutionMask uint16 // Create Response Only if results == 3 or Set Response only if results == 0
+ unsupportedMask uint16 // Set Response only if results == 9
+ sequenceNumberCountOrSize uint16 // For get-next request frames and for frames that return number of commands or length
+ transactionID uint16 // OMCI TID
+ mode uint8 // Get All Alarms retrieval mode
+ alarm AlarmOptions // Alarm related frames
+ software SoftwareOptions // Software image related frames
+ payload interface{} // ME or list of MEs, alarm bitmap, timestamp, ...
+ addDefaults bool // Add missing SetByCreate attributes for Create Requests
+}
+
+var defaultFrameOptions = options{
+ frameFormat: BaselineIdent,
+ failIfTruncated: false,
+ attributeMask: 0xFFFF,
+ result: me.Success,
+ attrExecutionMask: 0,
+ unsupportedMask: 0,
+ sequenceNumberCountOrSize: 0,
+ transactionID: 0,
+ mode: 0,
+ software: defaultSoftwareOptions,
+ alarm: defaultAlarmOptions,
+ payload: nil,
+ addDefaults: false,
+}
+
+// FrameOption sets options such as frame format, etc.
+type FrameOption func(*options)
+
+// FrameFormat determines determines the OMCI message format used on the fiber.
+// The default value is BaselineIdent
+func FrameFormat(ff DeviceIdent) FrameOption {
+ return func(o *options) {
+ o.frameFormat = ff
+ }
+}
+
+// FailIfTruncated determines whether a request to encode a frame that does
+// not have enough room for all requested options should fail and return an
+// error.
+//
+// If set to 'false', the behaviour depends on the message type/operation
+// requested. The table below provides more information:
+//
+// Request Type Behavour
+// ------------------------------------------------------------------------
+// CreateRequest A single CreateRequest struct is always returned as the
+// CreateRequest message does not have an attributes Mask
+// field and a Baseline OMCI message is large enough to
+// support all Set-By-Create attributes.
+//
+// GetResponse If multiple OMCI response frames are needed to return
+// all requested attributes, only the attributes that can
+// fit will be returned and the FailedAttributeMask field
+// set to the attributes that could not be returned
+//
+// If this is an ME with an attribute that is a table, the
+// first GetResponse struct will return the size of the
+// attribute and the following GetNextResponse structs will
+// contain the attribute data. The ONU application is
+// responsible for stashing these extra struct(s) away in
+// anticipation of possible GetNext Requests occurring for
+// the attribute. See the discussion on Table attributes
+// in the GetResponse section of ITU G.988 for more
+// information.
+//
+// If set to 'true', no struct(s) are returned and an error is provided.
+//
+// The default value is 'false'
+func FailIfTruncated(f bool) FrameOption {
+ return func(o *options) {
+ o.failIfTruncated = f
+ }
+}
+
+// attributeMask determines the attributes to encode into the frame.
+// The default value is 0xFFFF which specifies all available attributes
+// in the frame
+func AttributeMask(m uint16) FrameOption {
+ return func(o *options) {
+ o.attributeMask = m
+ }
+}
+
+// AttributeExecutionMask is used by the Create and Set Response frames to indicate
+// attributes that failed to be created/set.
+func AttributeExecutionMask(m uint16) FrameOption {
+ return func(o *options) {
+ o.attrExecutionMask = m
+ }
+}
+
+// UnsupportedAttributeMask is used by the Set Response frames to indicate
+// attributes are not supported on this ONU
+func UnsupportedAttributeMask(m uint16) FrameOption {
+ return func(o *options) {
+ o.unsupportedMask = m
+ }
+}
+
+// Result is used to set returned results in responses
+// that have that field
+func Result(r me.Results) FrameOption {
+ return func(o *options) {
+ o.result = r
+ }
+}
+
+// SequenceNumberCountOrSize is used by the GetNext and MibUploadGetNext request frames and for
+// frames that return number of commands or length such as Get (table attribute) or
+// MibUpload/GetAllAlarms/...
+func SequenceNumberCountOrSize(m uint16) FrameOption {
+ return func(o *options) {
+ o.sequenceNumberCountOrSize = m
+ }
+}
+
+// TransactionID is to specify the TID in the OMCI header. The default is
+// zero which requires the caller to set it to the appropriate value if this
+// is not an autonomous ONU notification frame
+func TransactionID(tid uint16) FrameOption {
+ return func(o *options) {
+ o.transactionID = tid
+ }
+}
+
+// RetrievalMode is to specify the the Alarm Retrieval Mode in a GetAllAlarms Request
+func RetrievalMode(m uint8) FrameOption {
+ return func(o *options) {
+ o.mode = m
+ }
+}
+
+// SuccessResult is to specify the the SuccessResult for a SynchronizeTime Response
+func SuccessResult(m uint8) FrameOption {
+ return func(o *options) {
+ o.mode = m
+ }
+}
+
+// RebootCondition is to specify the the Reboot Condition for a ONU Reboot request
+func RebootCondition(m uint8) FrameOption {
+ return func(o *options) {
+ o.mode = m
+ }
+}
+
+// Alarm is used to specify a collection of options related to Alarm notifications
+func Alarm(ao AlarmOptions) FrameOption {
+ return func(o *options) {
+ o.alarm = ao
+ }
+}
+
+// Software is used to specify a collection of options related to Software image
+// manipulation
+func Software(so SoftwareOptions) FrameOption {
+ return func(o *options) {
+ o.software = so
+ }
+}
+
+// Payload is used to specify ME payload options that are not simple types. This
+// include the ME (list of MEs) to encode into a GetNextMibUpload response, the
+// alarm bitmap for alarm relates responses/notifications, alarm bitmaps, and
+// for specifying the download section data when performing Software Download.
+func Payload(p interface{}) FrameOption {
+ return func(o *options) {
+ o.payload = p
+ }
+}
+
+// AddDefaults is used to specify that if a SetByCreate attribute is not
+// specified in the list of attributes for a Create Request, use the attribute
+// defined default
+func AddDefaults(add bool) FrameOption {
+ return func(o *options) {
+ o.addDefaults = add
+ }
+}
+
+// Alarm related frames have a wide variety of settable values. Placing them
+// in a separate struct is mainly to keep the base options simple
+type AlarmOptions struct {
+ AlarmClassID me.ClassID
+ AlarmInstance uint16
+ AlarmBitmap []byte // Should be up to 58 octets
+}
+
+var defaultAlarmOptions = AlarmOptions{
+ AlarmClassID: 0,
+ AlarmInstance: 0,
+ AlarmBitmap: nil,
+}
+
+// Software related frames have a wide variety of settable values. Placing them
+// in a separate struct is mainly to keep the base options simple
+type SoftwareOptions struct {
+ WindowSize uint8 // Window size - 1
+ SectionNumber uint8 // [0..Window size - 1]
+ ImageSize uint32
+ CircuitPacks []uint16 // slot (upper 8 bits) and instance (lower 8 bits)
+ Results []DownloadResults
+ Data []byte
+}
+
+var defaultSoftwareOptions = SoftwareOptions{
+ WindowSize: 0,
+ SectionNumber: 0,
+ ImageSize: 0,
+ CircuitPacks: nil,
+ Results: nil,
+ Data: nil,
+}
+
+// EncodeFrame will encode the Managed Entity specific protocol struct and an
+// OMCILayer struct. This struct can be provided to the gopacket.SerializeLayers()
+// function to be serialized into a buffer for transmission.
+func EncodeFrame(m *me.ManagedEntity, messageType MessageType, opt ...FrameOption) (*OMCI, gopacket.SerializableLayer, error) {
+ // Check for message type support
+ msgType := me.MsgType(messageType & me.MsgTypeMask)
+ meDefinition := m.GetManagedEntityDefinition()
+
+ if !me.SupportsMsgType(meDefinition, msgType) {
+ msg := fmt.Sprintf("managed entity %v does not support %v Message-Type",
+ meDefinition.GetName(), msgType)
+ return nil, nil, errors.New(msg)
+ }
+ // Decode options
+ opts := defaultFrameOptions
+ for _, o := range opt {
+ o(&opts)
+ }
+ // TODO: If AttributesMask option passed in, check for deprecated options. Allow encoding option
+ // that will ignore deprecated option. Add additional in the get and set meframe_test,go
+ // test functions to test this. Also have it test attribute name(s) to see if the attribute
+ // is deprecated. The OMCI-Parser now supports detection of deprecated attributes and
+ // provides that to the code-generator (and currently available in generated golang code).
+ // Note: Transaction ID should be set before frame serialization
+ omci := &OMCI{
+ TransactionID: opts.transactionID,
+ MessageType: messageType,
+ DeviceIdentifier: opts.frameFormat,
+ }
+ var meInfo gopacket.SerializableLayer
+ var err error
+
+ if encoder, ok := encoderMap[messageType]; ok {
+ meInfo, err = encoder(m, opts)
+ } else {
+ err = fmt.Errorf("message-type: %v/%#x is not supported", messageType, messageType)
+ }
+ if err != nil {
+ return nil, nil, err
+ }
+ return omci, meInfo, err
+}
+
+// For most all create methods below, error checking for valid masks, attribute
+// values, and other fields is left to when the frame is actually serialized.
+
+func checkAttributeMask(m *me.ManagedEntity, mask uint16) (uint16, error) {
+ if mask == defaultFrameOptions.attributeMask {
+ // Scale back to just what is allowed
+ return m.GetAllowedAttributeMask(), nil
+ }
+ if mask&m.GetManagedEntityDefinition().GetAllowedAttributeMask() != mask {
+ return 0, errors.New("invalid attribute mask")
+ }
+ return mask & m.GetManagedEntityDefinition().GetAllowedAttributeMask(), nil
+}
+
+// return the maximum space that can be used by attributes
+func maxPacketAvailable(m *me.ManagedEntity, opt options) uint {
+ if opt.frameFormat == BaselineIdent {
+ // OMCI Header - 4 octets
+ // Class ID/Instance ID - 4 octets
+ // Length field - 4 octets
+ // MIC - 4 octets
+ return MaxBaselineLength - 16
+ }
+ // OMCI Header - 4 octets
+ // Class ID/Instance ID - 4 octets
+ // Length field - 2 octets
+ // MIC - 4 octets
+ return MaxExtendedLength - 14
+}
+
+func calculateAttributeMask(m *me.ManagedEntity, requestedMask uint16) (uint16, error) {
+ attrDefs := m.GetAttributeDefinitions()
+ var entityIDName string
+ if entry, ok := attrDefs[0]; ok {
+ entityIDName = entry.GetName()
+ } else {
+ panic("unexpected error") // All attribute definition maps have an entity ID
+ }
+ attributeNames := make([]interface{}, 0)
+ for attrName := range m.GetAttributeValueMap() {
+ if attrName == entityIDName {
+ continue // No mask for EntityID
+ }
+ attributeNames = append(attributeNames, attrName)
+ }
+ calculatedMask, err := me.GetAttributesBitmap(attrDefs, mapset.NewSetWith(attributeNames...))
+
+ if err != nil {
+ return 0, err
+ }
+ return calculatedMask & requestedMask, nil
+}
+
+// GenFrame is a helper function to make tests a little easier to read.
+// For a real application, use the .../omci/generated/class.go 'New'
+// functions to create your Managed Entity and then use it to call the
+// EncodeFrame method.
+func GenFrame(meInstance *me.ManagedEntity, messageType MessageType, options ...FrameOption) ([]byte, error) {
+ omciLayer, msgLayer, err := EncodeFrame(meInstance, messageType, options...)
+ if err != nil {
+ return nil, err
+ }
+ // Serialize the frame and send it
+ var serializeOptions gopacket.SerializeOptions
+ serializeOptions.FixLengths = true
+
+ buffer := gopacket.NewSerializeBuffer()
+ err = gopacket.SerializeLayers(buffer, serializeOptions, omciLayer, msgLayer)
+ if err != nil {
+ return nil, err
+ }
+ return buffer.Bytes(), nil
+}