-- Copyright (c) 2024 Huawei Technologies Co., Ltd.
-- openUBMC is licensed under Mulan PSL v2.
-- You can use this software according to the terms and conditions of the Mulan PSL v2.
-- You may obtain a copy of Mulan PSL v2 at:
--          http://license.coscl.org.cn/MulanPSL2
-- THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
-- EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
-- MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
-- See the Mulan PSL v2 for more details.
local mdb = require 'mc.mdb'
local class = require 'mc.class_mgnt'
local privilege = require 'mc.privilege'

local lsw_switch_info_class_types = require 'class.types.LswSwitchInfo'
local lsw_port_info_class_types = require 'class.types.LswPortInfo'
local lsw_phy_info_class_types = require 'class.types.LswPhyInfo'
local lsw_vlan_info_class_types = require 'class.types.LswVlanInfo'
local lsw_info_class_types = require 'class.types.LswInfo'
local smm_msg_class_types = require 'class.types.SmmMsg'
local lan_switch_intf_types = require 'lsw.json_types.LanSwitch'
local properties_intf_types = require 'lsw.json_types.Properties'
local lan_switch_mock_intf_types = require 'lsw.json_types.LanSwitchMock'

local LanSwitch = {
    ['mdb_prop_configs'] = {
        ['bmc.kepler.Chassis.LanSwitch'] = {},
        ['bmc.kepler.Object.Properties'] = {
            ['ClassName'] = {
                ['baseType'] = 'String',
                ['readOnly'] = true,
                ['validator'] = properties_intf_types.ClassName
            },
            ['ObjectName'] = {
                ['baseType'] = 'String',
                ['readOnly'] = true,
                ['validator'] = properties_intf_types.ObjectName
            },
            ['ObjectIdentifier'] = {
                ['baseType'] = 'Struct',
                ['$ref'] = '#/defs/StructIdentifier',
                ['readOnly'] = true,
                ['validator'] = properties_intf_types.ObjectIdentifier
            }
        }
    },
    ['mdb_method_configs'] = {
        ['bmc.kepler.Chassis.LanSwitch'] = {
            ['LswReset'] = {
                ['privilege'] = {'BasicSetting'},
                ['req'] = {{['baseType'] = 'U32', ['param'] = 'Device'}, {['baseType'] = 'U32', ['param'] = 'Type'}},
                ['rsp'] = {}
            },
            ['GetConfigInfo'] = {
                ['req'] = {},
                ['rsp'] = {{['baseType'] = 'String', ['param'] = 'Value'}},
                ['privilege'] = {'ReadOnly'}
            }
        }
    },
    ['mdb_classes'] = mdb.get_class_obj('/bmc/kepler/Chassis/:ChassisId/LanSwitchs/:Id'),
    ['new_mdb_objects'] = mdb.new_objects_builder({
        ['bmc.kepler.Chassis.LanSwitch'] = {
            ['property_defaults'] = {},
            ['privileges'] = {
                ['path'] = privilege.ConfigureSelf,
                ['methods'] = {['LswReset'] = privilege.BasicSetting, ['GetConfigInfo'] = privilege.ReadOnly}
            },
            ['interface_types'] = lan_switch_intf_types
        },
        ['bmc.kepler.Object.Properties'] = {
            ['property_defaults'] = {
                ['ClassName'] = properties_intf_types.ClassName.default[1],
                ['ObjectName'] = properties_intf_types.ObjectName.default[1],
                ['ObjectIdentifier'] = properties_intf_types.ObjectIdentifier.default[1]
            },
            ['privileges'] = {['path'] = privilege.ConfigureSelf},
            ['interface_types'] = properties_intf_types
        }
    })
}

local LanSwitchMock = {
    ['mdb_prop_configs'] = {
        ['bmc.kepler.Debug.LanSwitchMock'] = {},
        ['bmc.kepler.Object.Properties'] = {
            ['ClassName'] = {
                ['baseType'] = 'String',
                ['readOnly'] = true,
                ['validator'] = properties_intf_types.ClassName
            },
            ['ObjectName'] = {
                ['baseType'] = 'String',
                ['readOnly'] = true,
                ['validator'] = properties_intf_types.ObjectName
            },
            ['ObjectIdentifier'] = {
                ['baseType'] = 'Struct',
                ['$ref'] = '#/defs/StructIdentifier',
                ['readOnly'] = true,
                ['validator'] = properties_intf_types.ObjectIdentifier
            }
        }
    },
    ['mdb_method_configs'] = {
        ['bmc.kepler.Debug.LanSwitchMock'] = {
            ['RegRead'] = {
                ['req'] = {
                    {['baseType'] = 'U8', ['param'] = 'Unit'}, {['baseType'] = 'U8', ['param'] = 'Type'},
                    {['baseType'] = 'U8', ['param'] = 'Port'}, {['baseType'] = 'U32', ['param'] = 'Addr'}
                },
                ['rsp'] = {{['baseType'] = 'U32', ['param'] = 'Value'}},
                ['privilege'] = {'ReadOnly'}
            },
            ['RegWrite'] = {
                ['privilege'] = {'BasicSetting'},
                ['req'] = {
                    {['baseType'] = 'U8', ['param'] = 'Unit'}, {['baseType'] = 'U8', ['param'] = 'Type'},
                    {['baseType'] = 'U8', ['param'] = 'Port'}, {['baseType'] = 'U32', ['param'] = 'Addr'},
                    {['baseType'] = 'U32', ['param'] = 'Value'}
                },
                ['rsp'] = {}
            },
            ['GetPortInfo'] = {
                ['req'] = {{['baseType'] = 'U32', ['param'] = 'Unit'}, {['baseType'] = 'U32', ['param'] = 'Port'}},
                ['rsp'] = {{['baseType'] = 'String', ['param'] = 'Value'}},
                ['privilege'] = {'ReadOnly'}
            },
            ['SetPortEnable'] = {
                ['privilege'] = {'BasicSetting'},
                ['req'] = {
                    {['baseType'] = 'U32', ['param'] = 'Unit'}, {['baseType'] = 'U32', ['param'] = 'Port'},
                    {['baseType'] = 'U32', ['param'] = 'Enable'}
                },
                ['rsp'] = {}
            },
            ['SetPortStpState'] = {
                ['privilege'] = {'BasicSetting'},
                ['req'] = {
                    {['baseType'] = 'U32', ['param'] = 'Unit'}, {['baseType'] = 'U32', ['param'] = 'Port'},
                    {['baseType'] = 'U32', ['param'] = 'State'}
                },
                ['rsp'] = {}
            },
            ['GetSwitchErrorCode'] = {
                ['req'] = {{['baseType'] = 'U32', ['param'] = 'Unit'}, {['baseType'] = 'U32', ['param'] = 'UtpNum'}},
                ['rsp'] = {{['baseType'] = 'U32', ['param'] = 'Value'}},
                ['privilege'] = {'ReadOnly'}
            },
            ['SetPortMacAddr'] = {
                ['privilege'] = {'BasicSetting'},
                ['req'] = {
                    {['baseType'] = 'U32', ['param'] = 'Unit'}, {['baseType'] = 'U32', ['param'] = 'Port'},
                    {['baseType'] = 'String', ['param'] = 'MacStr'}
                },
                ['rsp'] = {}
            },
            ['FlushPortAddr'] = {
                ['privilege'] = {'BasicSetting'},
                ['req'] = {{['baseType'] = 'U32', ['param'] = 'Unit'}, {['baseType'] = 'U32', ['param'] = 'Port'}},
                ['rsp'] = {}
            },
            ['GetVlanInfo'] = {
                ['req'] = {{['baseType'] = 'U32', ['param'] = 'Unit'}},
                ['rsp'] = {{['baseType'] = 'String', ['param'] = 'Value'}},
                ['privilege'] = {'ReadOnly'}
            }
        }
    },
    ['mdb_classes'] = mdb.get_class_obj('/bmc/kepler/Debug/LanSwitchMock'),
    ['new_mdb_objects'] = mdb.new_objects_builder({
        ['bmc.kepler.Debug.LanSwitchMock'] = {
            ['property_defaults'] = {},
            ['privileges'] = {
                ['path'] = privilege.ConfigureSelf,
                ['methods'] = {
                    ['RegRead'] = privilege.ReadOnly,
                    ['RegWrite'] = privilege.BasicSetting,
                    ['GetPortInfo'] = privilege.ReadOnly,
                    ['SetPortEnable'] = privilege.BasicSetting,
                    ['SetPortStpState'] = privilege.BasicSetting,
                    ['GetSwitchErrorCode'] = privilege.ReadOnly,
                    ['SetPortMacAddr'] = privilege.BasicSetting,
                    ['FlushPortAddr'] = privilege.BasicSetting,
                    ['GetVlanInfo'] = privilege.ReadOnly
                }
            },
            ['interface_types'] = lan_switch_mock_intf_types
        },
        ['bmc.kepler.Object.Properties'] = {
            ['property_defaults'] = {
                ['ClassName'] = properties_intf_types.ClassName.default[1],
                ['ObjectName'] = properties_intf_types.ObjectName.default[1],
                ['ObjectIdentifier'] = properties_intf_types.ObjectIdentifier.default[1]
            },
            ['privileges'] = {['path'] = privilege.ConfigureSelf},
            ['interface_types'] = properties_intf_types
        }
    })
}

local LswSwitchInfo = {
    ['prop_configs'] = {
        ['Unit'] = {['usage'] = {'CSR'}, ['baseType'] = 'U32', ['validator'] = lsw_switch_info_class_types.Unit},
        ['Type'] = {['usage'] = {'CSR'}, ['baseType'] = 'U32', ['validator'] = lsw_switch_info_class_types.Type},
        ['ChipRst'] = {['usage'] = {'CSR'}, ['baseType'] = 'U8', ['validator'] = lsw_switch_info_class_types.ChipRst},
        ['PowerState'] = {
            ['usage'] = {'CSR'},
            ['baseType'] = 'U8',
            ['validator'] = lsw_switch_info_class_types.PowerState
        },
        ['ErrorCode'] = {
            ['usage'] = {'CSR'},
            ['baseType'] = 'U8',
            ['validator'] = lsw_switch_info_class_types.ErrorCode
        },
        ['HealthState'] = {
            ['usage'] = {'CSR'},
            ['baseType'] = 'U8',
            ['validator'] = lsw_switch_info_class_types.HealthState
        },
        ['SlotNumber'] = {
            ['usage'] = {'CSR'},
            ['baseType'] = 'U8',
            ['validator'] = lsw_switch_info_class_types.SlotNumber
        }
    },
    ['default_props'] = {
        ['Unit'] = lsw_switch_info_class_types.Unit.default[1],
        ['Type'] = lsw_switch_info_class_types.Type.default[1],
        ['ChipRst'] = lsw_switch_info_class_types.ChipRst.default[1],
        ['PowerState'] = lsw_switch_info_class_types.PowerState.default[1],
        ['ErrorCode'] = lsw_switch_info_class_types.ErrorCode.default[1],
        ['HealthState'] = lsw_switch_info_class_types.HealthState.default[1],
        ['SlotNumber'] = lsw_switch_info_class_types.SlotNumber.default[1]
    }
}

local LswPortInfo = {
    ['prop_configs'] = {
        ['Unit'] = {['usage'] = {'CSR'}, ['baseType'] = 'U32', ['validator'] = lsw_port_info_class_types.Unit},
        ['LogicId'] = {['usage'] = {'CSR'}, ['baseType'] = 'U32', ['validator'] = lsw_port_info_class_types.LogicId},
        ['PhysicalId'] = {
            ['usage'] = {'CSR'},
            ['baseType'] = 'U32',
            ['validator'] = lsw_port_info_class_types.PhysicalId
        },
        ['PortType'] = {['usage'] = {'CSR'}, ['baseType'] = 'U32', ['validator'] = lsw_port_info_class_types.PortType},
        ['ExtMode'] = {['usage'] = {'CSR'}, ['baseType'] = 'U32', ['validator'] = lsw_port_info_class_types.ExtMode},
        ['ConPhyAddr'] = {
            ['usage'] = {'CSR'},
            ['baseType'] = 'U32',
            ['validator'] = lsw_port_info_class_types.ConPhyAddr
        },
        ['LinkCheck'] = {
            ['usage'] = {'CSR'},
            ['baseType'] = 'Boolean',
            ['validator'] = lsw_port_info_class_types.LinkCheck
        },
        ['PortIso'] = {['usage'] = {'CSR'}, ['baseType'] = 'U32', ['validator'] = lsw_port_info_class_types.PortIso},
        ['PVid'] = {['usage'] = {'CSR'}, ['baseType'] = 'U32', ['validator'] = lsw_port_info_class_types.PVid},
        ['AccFrameType'] = {
            ['usage'] = {'CSR'},
            ['baseType'] = 'U32',
            ['validator'] = lsw_port_info_class_types.AccFrameType
        },
        ['ExportPort'] = {
            ['usage'] = {'CSR'},
            ['baseType'] = 'Boolean',
            ['validator'] = lsw_port_info_class_types.ExportPort
        },
        ['LinkStatus'] = {['baseType'] = 'U32', ['validator'] = lsw_port_info_class_types.LinkStatus},
        ['Speed'] = {['baseType'] = 'U32', ['validator'] = lsw_port_info_class_types.Speed},
        ['Duplex'] = {['baseType'] = 'U32', ['validator'] = lsw_port_info_class_types.Duplex},
        ['PortError'] = {['baseType'] = 'U32', ['validator'] = lsw_port_info_class_types.PortError},
        ['AutoNego'] = {['baseType'] = 'U32', ['validator'] = lsw_port_info_class_types.AutoNego},
        ['StpState'] = {['baseType'] = 'U32', ['validator'] = lsw_port_info_class_types.StpState}
    },
    ['default_props'] = {
        ['Unit'] = lsw_port_info_class_types.Unit.default[1],
        ['LogicId'] = lsw_port_info_class_types.LogicId.default[1],
        ['PhysicalId'] = lsw_port_info_class_types.PhysicalId.default[1],
        ['PortType'] = lsw_port_info_class_types.PortType.default[1],
        ['ExtMode'] = lsw_port_info_class_types.ExtMode.default[1],
        ['ConPhyAddr'] = lsw_port_info_class_types.ConPhyAddr.default[1],
        ['LinkCheck'] = lsw_port_info_class_types.LinkCheck.default[1],
        ['PortIso'] = lsw_port_info_class_types.PortIso.default[1],
        ['PVid'] = lsw_port_info_class_types.PVid.default[1],
        ['AccFrameType'] = lsw_port_info_class_types.AccFrameType.default[1],
        ['ExportPort'] = lsw_port_info_class_types.ExportPort.default[1],
        ['LinkStatus'] = lsw_port_info_class_types.LinkStatus.default[1],
        ['Speed'] = lsw_port_info_class_types.Speed.default[1],
        ['Duplex'] = lsw_port_info_class_types.Duplex.default[1],
        ['PortError'] = lsw_port_info_class_types.PortError.default[1],
        ['AutoNego'] = lsw_port_info_class_types.AutoNego.default[1],
        ['StpState'] = lsw_port_info_class_types.StpState.default[1]
    }
}

local LswPhyInfo = {
    ['prop_configs'] = {
        ['Unit'] = {['usage'] = {'CSR'}, ['baseType'] = 'U32', ['validator'] = lsw_phy_info_class_types.Unit},
        ['PhysicalId'] = {
            ['usage'] = {'CSR'},
            ['baseType'] = 'U32',
            ['validator'] = lsw_phy_info_class_types.PhysicalId
        },
        ['PhysicalAddr'] = {
            ['usage'] = {'CSR'},
            ['baseType'] = 'U8',
            ['validator'] = lsw_phy_info_class_types.PhysicalAddr
        },
        ['ChipRst'] = {['usage'] = {'CSR'}, ['baseType'] = 'U8', ['validator'] = lsw_phy_info_class_types.ChipRst},
        ['CfgType'] = {['baseType'] = 'U8', ['validator'] = lsw_phy_info_class_types.CfgType},
        ['PowerState'] = {['usage'] = {'CSR'}, ['baseType'] = 'U8', ['validator'] = lsw_phy_info_class_types.PowerState},
        ['HealthState'] = {
            ['usage'] = {'CSR'},
            ['baseType'] = 'U8',
            ['validator'] = lsw_phy_info_class_types.HealthState
        },
        ['SlotNumber'] = {['usage'] = {'CSR'}, ['baseType'] = 'U8', ['validator'] = lsw_phy_info_class_types.SlotNumber}
    },
    ['default_props'] = {
        ['Unit'] = lsw_phy_info_class_types.Unit.default[1],
        ['PhysicalId'] = lsw_phy_info_class_types.PhysicalId.default[1],
        ['PhysicalAddr'] = lsw_phy_info_class_types.PhysicalAddr.default[1],
        ['ChipRst'] = lsw_phy_info_class_types.ChipRst.default[1],
        ['CfgType'] = lsw_phy_info_class_types.CfgType.default[1],
        ['PowerState'] = lsw_phy_info_class_types.PowerState.default[1],
        ['HealthState'] = lsw_phy_info_class_types.HealthState.default[1],
        ['SlotNumber'] = lsw_phy_info_class_types.SlotNumber.default[1]
    }
}

local LswVlanInfo = {
    ['prop_configs'] = {
        ['Unit'] = {['usage'] = {'CSR'}, ['baseType'] = 'U32', ['validator'] = lsw_vlan_info_class_types.Unit},
        ['VlanId'] = {['usage'] = {'CSR'}, ['baseType'] = 'U32', ['validator'] = lsw_vlan_info_class_types.VlanId},
        ['Member'] = {['usage'] = {'CSR'}, ['baseType'] = 'U32', ['validator'] = lsw_vlan_info_class_types.Member},
        ['Untaged'] = {['usage'] = {'CSR'}, ['baseType'] = 'U32', ['validator'] = lsw_vlan_info_class_types.Untaged}
    },
    ['default_props'] = {
        ['Unit'] = lsw_vlan_info_class_types.Unit.default[1],
        ['VlanId'] = lsw_vlan_info_class_types.VlanId.default[1],
        ['Member'] = lsw_vlan_info_class_types.Member.default[1],
        ['Untaged'] = lsw_vlan_info_class_types.Untaged.default[1]
    }
}

local LswInfo = {
    ['table_name'] = 't_lsw_info',
    ['prop_configs'] = {
        ['Unit'] = {
            ['primaryKey'] = true,
            ['baseType'] = 'U32',
            ['description'] = '交换板芯片ID',
            ['validator'] = lsw_info_class_types.Unit
        },
        ['IsCfg'] = {
            ['notAllowNull'] = true,
            ['baseType'] = 'Boolean',
            ['description'] = '是否初始化',
            ['default'] = false,
            ['validator'] = lsw_info_class_types.IsCfg
        }
    },
    ['default_props'] = {['Unit'] = lsw_info_class_types.Unit.default[1], ['IsCfg'] = false}
}

local SmmMsg = {
    ['table_name'] = 't_smm_info',
    ['prop_configs'] = {
        ['Unit'] = {
            ['primaryKey'] = true,
            ['baseType'] = 'U32',
            ['description'] = '交换板芯片ID',
            ['validator'] = smm_msg_class_types.Unit
        },
        ['SMMLinkPath'] = {
            ['notAllowNull'] = true,
            ['baseType'] = 'U8',
            ['description'] = '当前外网通路',
            ['default'] = 0,
            ['validator'] = smm_msg_class_types.SMMLinkPath
        },
        ['ExternalVlanId'] = {
            ['notAllowNull'] = true,
            ['baseType'] = 'U32',
            ['description'] = '外网VlanId',
            ['default'] = 0,
            ['validator'] = smm_msg_class_types.ExternalVlanId
        }
    },
    ['default_props'] = {['Unit'] = smm_msg_class_types.Unit.default[1], ['SMMLinkPath'] = 0, ['ExternalVlanId'] = 0}
}

local M = {}

function M.init(bus)
    class('LanSwitch', LanSwitch):set_bus(bus)
    class('LanSwitchMock', LanSwitchMock):set_bus(bus)
    class('LswSwitchInfo', LswSwitchInfo):set_bus(bus)
    class('LswPortInfo', LswPortInfo):set_bus(bus)
    class('LswPhyInfo', LswPhyInfo):set_bus(bus)
    class('LswVlanInfo', LswVlanInfo):set_bus(bus)
    class('LswInfo', LswInfo):set_bus(bus)
    class('SmmMsg', SmmMsg):set_bus(bus)
end

-- The callback needs to be registered during app initialization
function M.ImplLanSwitchLanSwitchLswReset(cb)
    class('LanSwitch')['bmc.kepler.Chassis.LanSwitch'].LswReset = function(obj, ctx, ...)
        local req = lan_switch_intf_types.LswResetReq.new(...):validate(nil, nil, true)
        local rsp = lan_switch_intf_types.LswResetRsp.new(cb(obj, ctx, req:unpack())):validate()
        return rsp:unpack(true)
    end
end

-- The callback needs to be registered during app initialization
function M.ImplLanSwitchLanSwitchGetConfigInfo(cb)
    class('LanSwitch')['bmc.kepler.Chassis.LanSwitch'].GetConfigInfo = function(obj, ctx, ...)
        local req = lan_switch_intf_types.GetConfigInfoReq.new(...):validate(nil, nil, true)
        local rsp = lan_switch_intf_types.GetConfigInfoRsp.new(cb(obj, ctx, req:unpack())):validate()
        return rsp:unpack(true)
    end
end

-- The callback needs to be registered during app initialization
function M.ImplLanSwitchMockLanSwitchMockRegRead(cb)
    class('LanSwitchMock')['bmc.kepler.Debug.LanSwitchMock'].RegRead = function(obj, ctx, ...)
        local req = lan_switch_mock_intf_types.RegReadReq.new(...):validate(nil, nil, true)
        local rsp = lan_switch_mock_intf_types.RegReadRsp.new(cb(obj, ctx, req:unpack())):validate()
        return rsp:unpack(true)
    end
end

-- The callback needs to be registered during app initialization
function M.ImplLanSwitchMockLanSwitchMockRegWrite(cb)
    class('LanSwitchMock')['bmc.kepler.Debug.LanSwitchMock'].RegWrite = function(obj, ctx, ...)
        local req = lan_switch_mock_intf_types.RegWriteReq.new(...):validate(nil, nil, true)
        local rsp = lan_switch_mock_intf_types.RegWriteRsp.new(cb(obj, ctx, req:unpack())):validate()
        return rsp:unpack(true)
    end
end

-- The callback needs to be registered during app initialization
function M.ImplLanSwitchMockLanSwitchMockGetPortInfo(cb)
    class('LanSwitchMock')['bmc.kepler.Debug.LanSwitchMock'].GetPortInfo = function(obj, ctx, ...)
        local req = lan_switch_mock_intf_types.GetPortInfoReq.new(...):validate(nil, nil, true)
        local rsp = lan_switch_mock_intf_types.GetPortInfoRsp.new(cb(obj, ctx, req:unpack())):validate()
        return rsp:unpack(true)
    end
end

-- The callback needs to be registered during app initialization
function M.ImplLanSwitchMockLanSwitchMockSetPortEnable(cb)
    class('LanSwitchMock')['bmc.kepler.Debug.LanSwitchMock'].SetPortEnable = function(obj, ctx, ...)
        local req = lan_switch_mock_intf_types.SetPortEnableReq.new(...):validate(nil, nil, true)
        local rsp = lan_switch_mock_intf_types.SetPortEnableRsp.new(cb(obj, ctx, req:unpack())):validate()
        return rsp:unpack(true)
    end
end

-- The callback needs to be registered during app initialization
function M.ImplLanSwitchMockLanSwitchMockSetPortStpState(cb)
    class('LanSwitchMock')['bmc.kepler.Debug.LanSwitchMock'].SetPortStpState = function(obj, ctx, ...)
        local req = lan_switch_mock_intf_types.SetPortStpStateReq.new(...):validate(nil, nil, true)
        local rsp = lan_switch_mock_intf_types.SetPortStpStateRsp.new(cb(obj, ctx, req:unpack())):validate()
        return rsp:unpack(true)
    end
end

-- The callback needs to be registered during app initialization
function M.ImplLanSwitchMockLanSwitchMockGetSwitchErrorCode(cb)
    class('LanSwitchMock')['bmc.kepler.Debug.LanSwitchMock'].GetSwitchErrorCode = function(obj, ctx, ...)
        local req = lan_switch_mock_intf_types.GetSwitchErrorCodeReq.new(...):validate(nil, nil, true)
        local rsp = lan_switch_mock_intf_types.GetSwitchErrorCodeRsp.new(cb(obj, ctx, req:unpack())):validate()
        return rsp:unpack(true)
    end
end

-- The callback needs to be registered during app initialization
function M.ImplLanSwitchMockLanSwitchMockSetPortMacAddr(cb)
    class('LanSwitchMock')['bmc.kepler.Debug.LanSwitchMock'].SetPortMacAddr = function(obj, ctx, ...)
        local req = lan_switch_mock_intf_types.SetPortMacAddrReq.new(...):validate(nil, nil, true)
        local rsp = lan_switch_mock_intf_types.SetPortMacAddrRsp.new(cb(obj, ctx, req:unpack())):validate()
        return rsp:unpack(true)
    end
end

-- The callback needs to be registered during app initialization
function M.ImplLanSwitchMockLanSwitchMockFlushPortAddr(cb)
    class('LanSwitchMock')['bmc.kepler.Debug.LanSwitchMock'].FlushPortAddr = function(obj, ctx, ...)
        local req = lan_switch_mock_intf_types.FlushPortAddrReq.new(...):validate(nil, nil, true)
        local rsp = lan_switch_mock_intf_types.FlushPortAddrRsp.new(cb(obj, ctx, req:unpack())):validate()
        return rsp:unpack(true)
    end
end

-- The callback needs to be registered during app initialization
function M.ImplLanSwitchMockLanSwitchMockGetVlanInfo(cb)
    class('LanSwitchMock')['bmc.kepler.Debug.LanSwitchMock'].GetVlanInfo = function(obj, ctx, ...)
        local req = lan_switch_mock_intf_types.GetVlanInfoReq.new(...):validate(nil, nil, true)
        local rsp = lan_switch_mock_intf_types.GetVlanInfoRsp.new(cb(obj, ctx, req:unpack())):validate()
        return rsp:unpack(true)
    end
end

return M
