/*
 * 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.
 */
/*
 * NOTE: This file was generated, manual edits will be overwritten!
 *
 * Generated by 'goCodeGenerator.py':
 *              https://github.com/cboling/OMCI-parser/README.md
 */

package generated

import "github.com/deckarep/golang-set"

// VoipFeatureAccessCodesClassID is the 16-bit ID for the OMCI
// Managed entity VoIP feature access codes
const VoipFeatureAccessCodesClassID = ClassID(147) // 0x0093

var voipfeatureaccesscodesBME *ManagedEntityDefinition

// VoipFeatureAccessCodes (Class ID: #147 / 0x0093)
//	The VoIP feature access codes ME defines administrable feature access codes for the VoIP
//	subscriber. It is optional for ONUs that support VoIP services. If a non-OMCI interface is used
//	to manage VoIP signalling, this ME is unnecessary.
//
//	Instances of this ME are created and deleted by the OLT. A VoIP feature access codes instance is
//	needed for each unique set of feature access code attributes.
//
//	Relationships
//		An instance of this ME may be associated with one or more SIP user data MEs.
//
//	Attributes
//		Managed Entity Id
//			The remaining attributes are access codes for the features mentioned in their names. Each
//			attribute is a string of characters from the set {0..9, *, #}, with trailing nulls in any unused
//			bytes.
//
//			This attribute uniquely identifies each instance of this ME. (R) (mandatory) (2-bytes)
//
//		Cancel Call Waiting
//			(R,-W) (optional) (5-bytes)
//
//		Call Hold
//				(R,-W) (optional) (5-bytes)
//
//		Call Park
//				(R,-W) (optional) (5-bytes)
//
//		Caller Id Activate
//			(R,-W) (optional) (5-bytes)
//
//		Caller Id Deactivate
//			(R,-W) (optional) (5-bytes)
//
//		Do Not Disturb Activation
//			(R,-W) (optional) (5-bytes)
//
//		Do Not Disturb Deactivation
//			(R,-W) (optional) (5-bytes)
//
//		Do Not Disturb Pin Change
//			(R,-W) (optional) (5-bytes)
//
//		Emergency Service Number
//			(R,-W) (optional) (5-bytes)
//
//		Intercom Service
//			(R,-W) (optional) (5-bytes)
//
//		Unattended_Blind Call Transfer
//			Unattended/blind call transfer:	(R, W) (optional) (5 bytes)
//
//		Attended Call Transfer
//			(R, W) (optional) (5 bytes)
//
type VoipFeatureAccessCodes struct {
	ManagedEntityDefinition
	Attributes AttributeValueMap
}

// Attribute name constants

const VoipFeatureAccessCodes_CancelCallWaiting = "CancelCallWaiting"
const VoipFeatureAccessCodes_CallHold = "CallHold"
const VoipFeatureAccessCodes_CallPark = "CallPark"
const VoipFeatureAccessCodes_CallerIdActivate = "CallerIdActivate"
const VoipFeatureAccessCodes_CallerIdDeactivate = "CallerIdDeactivate"
const VoipFeatureAccessCodes_DoNotDisturbActivation = "DoNotDisturbActivation"
const VoipFeatureAccessCodes_DoNotDisturbDeactivation = "DoNotDisturbDeactivation"
const VoipFeatureAccessCodes_DoNotDisturbPinChange = "DoNotDisturbPinChange"
const VoipFeatureAccessCodes_EmergencyServiceNumber = "EmergencyServiceNumber"
const VoipFeatureAccessCodes_IntercomService = "IntercomService"
const VoipFeatureAccessCodes_UnattendedBlindCallTransfer = "UnattendedBlindCallTransfer"
const VoipFeatureAccessCodes_AttendedCallTransfer = "AttendedCallTransfer"

func init() {
	voipfeatureaccesscodesBME = &ManagedEntityDefinition{
		Name:    "VoipFeatureAccessCodes",
		ClassID: VoipFeatureAccessCodesClassID,
		MessageTypes: mapset.NewSetWith(
			Create,
			Delete,
			Get,
			Set,
		),
		AllowedAttributeMask: 0xfff0,
		AttributeDefinitions: AttributeDefinitionMap{
			0:  Uint16Field(ManagedEntityID, PointerAttributeType, 0x0000, 0, mapset.NewSetWith(Read), false, false, false, 0),
			1:  MultiByteField(VoipFeatureAccessCodes_CancelCallWaiting, OctetsAttributeType, 0x8000, 5, toOctets("AAAAAAA="), mapset.NewSetWith(Read, Write), false, true, false, 1),
			2:  MultiByteField(VoipFeatureAccessCodes_CallHold, OctetsAttributeType, 0x4000, 5, toOctets("AAAAAAA="), mapset.NewSetWith(Read, Write), false, true, false, 2),
			3:  MultiByteField(VoipFeatureAccessCodes_CallPark, OctetsAttributeType, 0x2000, 5, toOctets("AAAAAAA="), mapset.NewSetWith(Read, Write), false, true, false, 3),
			4:  MultiByteField(VoipFeatureAccessCodes_CallerIdActivate, OctetsAttributeType, 0x1000, 5, toOctets("AAAAAAA="), mapset.NewSetWith(Read, Write), false, true, false, 4),
			5:  MultiByteField(VoipFeatureAccessCodes_CallerIdDeactivate, OctetsAttributeType, 0x0800, 5, toOctets("AAAAAAA="), mapset.NewSetWith(Read, Write), false, true, false, 5),
			6:  MultiByteField(VoipFeatureAccessCodes_DoNotDisturbActivation, OctetsAttributeType, 0x0400, 5, toOctets("AAAAAAA="), mapset.NewSetWith(Read, Write), false, true, false, 6),
			7:  MultiByteField(VoipFeatureAccessCodes_DoNotDisturbDeactivation, OctetsAttributeType, 0x0200, 5, toOctets("AAAAAAA="), mapset.NewSetWith(Read, Write), false, true, false, 7),
			8:  MultiByteField(VoipFeatureAccessCodes_DoNotDisturbPinChange, OctetsAttributeType, 0x0100, 5, toOctets("AAAAAAA="), mapset.NewSetWith(Read, Write), false, true, false, 8),
			9:  MultiByteField(VoipFeatureAccessCodes_EmergencyServiceNumber, OctetsAttributeType, 0x0080, 5, toOctets("AAAAAAA="), mapset.NewSetWith(Read, Write), false, true, false, 9),
			10: MultiByteField(VoipFeatureAccessCodes_IntercomService, OctetsAttributeType, 0x0040, 5, toOctets("AAAAAAA="), mapset.NewSetWith(Read, Write), false, true, false, 10),
			11: MultiByteField(VoipFeatureAccessCodes_UnattendedBlindCallTransfer, OctetsAttributeType, 0x0020, 5, toOctets("AAAAAAA="), mapset.NewSetWith(Read, Write), false, true, false, 11),
			12: MultiByteField(VoipFeatureAccessCodes_AttendedCallTransfer, OctetsAttributeType, 0x0010, 5, toOctets("AAAAAAA="), mapset.NewSetWith(Read, Write), false, true, false, 12),
		},
		Access:  CreatedByOlt,
		Support: UnknownSupport,
	}
}

// NewVoipFeatureAccessCodes (class ID 147) creates the basic
// Managed Entity definition that is used to validate an ME of this type that
// is received from or transmitted to the OMCC.
func NewVoipFeatureAccessCodes(params ...ParamData) (*ManagedEntity, OmciErrors) {
	return NewManagedEntity(*voipfeatureaccesscodesBME, params...)
}
