From 6824bd46de64d21c977b46123e5a021c6323c0a0 Mon Sep 17 00:00:00 2001 From: Kanji Nakano Date: Wed, 24 Dec 2025 19:16:04 +0900 Subject: [PATCH 01/12] add OC Platform Transceiver Signed-off-by: Kanji Nakano --- translib/pfm_app.go | 1722 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 1662 insertions(+), 60 deletions(-) diff --git a/translib/pfm_app.go b/translib/pfm_app.go index f2dab02a3..3ba8a95fd 100644 --- a/translib/pfm_app.go +++ b/translib/pfm_app.go @@ -20,24 +20,43 @@ package translib import ( "errors" + "fmt" "github.com/Azure/sonic-mgmt-common/translib/db" "github.com/Azure/sonic-mgmt-common/translib/ocbinds" "github.com/Azure/sonic-mgmt-common/translib/tlerr" log "github.com/golang/glog" "github.com/openconfig/ygot/ygot" + "math" "reflect" + "regexp" "strconv" + "strings" ) type PlatformApp struct { - path *PathInfo - reqData []byte - ygotRoot *ygot.GoStruct - ygotTarget *interface{} - eepromTs *db.TableSpec - eepromTable map[string]dbEntry + path *PathInfo + reqData []byte + ygotRoot *ygot.GoStruct + ygotTarget *interface{} + eepromTs *db.TableSpec + transceiverInfoTs *db.TableSpec + transceiverDomSensorTs *db.TableSpec + transceiverDomThresholdTs *db.TableSpec + applPortTs *db.TableSpec + eepromTable map[string]dbEntry + transceiverInfoTable map[string]dbEntry + transceiverDomSensorTable map[string]dbEntry + transceiverDomThresholdTable map[string]dbEntry + applPortTable map[string]dbEntry } +const ( + fractionDigits1 = 10 + fractionDigits2 = 100 + fractionDigits3 = 1000 + fractionDigits18 = 1000000000000000000 +) + func init() { log.Info("Init called for Platform module") err := register("/openconfig-platform:components", @@ -64,6 +83,10 @@ func (app *PlatformApp) initialize(data appData) { app.ygotRoot = data.ygotRoot app.ygotTarget = data.ygotTarget app.eepromTs = &db.TableSpec{Name: "EEPROM_INFO"} + app.transceiverInfoTs = &db.TableSpec{Name: "TRANSCEIVER_INFO"} + app.transceiverDomSensorTs = &db.TableSpec{Name: "TRANSCEIVER_DOM_SENSOR"} + app.transceiverDomThresholdTs = &db.TableSpec{Name: "TRANSCEIVER_DOM_THRESHOLD"} + app.applPortTs = &db.TableSpec{Name: "PORT_TABLE"} } @@ -160,10 +183,11 @@ func (app *PlatformApp) processGet(dbs [db.MaxDB]*db.DB, fmtType TranslibFmtType pathInfo.Template, pathInfo.Path, pathInfo.Vars) stateDb := dbs[db.StateDB] + applDb := dbs[db.ApplDB] var payload []byte - // Read eeprom info from DB + // Read eeprom info from STATE_DB app.eepromTable = make(map[string]dbEntry) tbl, derr := stateDb.GetTable(app.eepromTs) @@ -183,6 +207,86 @@ func (app *PlatformApp) processGet(dbs [db.MaxDB]*db.DB, fmtType TranslibFmtType app.eepromTable[key.Get(0)] = dbEntry{entry: e} } + // Read transceiver info from STATE_DB + app.transceiverInfoTable = make(map[string]dbEntry) + + transceiverInfoTbl, derr := stateDb.GetTable(app.transceiverInfoTs) + if derr != nil { + log.Error("TRANSCEIVER_INFO table get failed!") + return GetResponse{Payload: payload}, derr + } + + transceiverInfoTblKeys, _ := transceiverInfoTbl.GetKeys() + for _, key := range transceiverInfoTblKeys { + e, kerr := transceiverInfoTbl.GetEntry(key) + if kerr != nil { + log.Error("TRANSCEIVER_INFO entry get failed!") + return GetResponse{Payload: payload}, kerr + } + + app.transceiverInfoTable[key.Get(0)] = dbEntry{entry: e} + } + + // Read transceiver dom sensor from STATE_DB + app.transceiverDomSensorTable = make(map[string]dbEntry) + + transceiverDomSensorTbl, derr := stateDb.GetTable(app.transceiverDomSensorTs) + if derr != nil { + log.Error("TRANSCEIVER_DOM_SENSOR table get failed!") + return GetResponse{Payload: payload}, derr + } + + transceiverDomSensorTblKeys, _ := transceiverDomSensorTbl.GetKeys() + for _, key := range transceiverDomSensorTblKeys { + e, kerr := transceiverDomSensorTbl.GetEntry(key) + if kerr != nil { + log.Error("TRANSCEIVER_DOM_SENSOR entry get failed!") + return GetResponse{Payload: payload}, kerr + } + + app.transceiverDomSensorTable[key.Get(0)] = dbEntry{entry: e} + } + + // Read transceiver dom threshold from STATE_DB + app.transceiverDomThresholdTable = make(map[string]dbEntry) + + transceiverDomThresholdTbl, derr := stateDb.GetTable(app.transceiverDomThresholdTs) + if derr != nil { + log.Error("TRANSCEIVER_DOM_THRESHOLD table get failed!") + return GetResponse{Payload: payload}, derr + } + + transceiverDomThresholdTblKeys, _ := transceiverDomThresholdTbl.GetKeys() + for _, key := range transceiverDomThresholdTblKeys { + e, kerr := transceiverDomThresholdTbl.GetEntry(key) + if kerr != nil { + log.Error("TRANSCEIVER_DOM_THRESHOLD entry get failed!") + return GetResponse{Payload: payload}, kerr + } + + app.transceiverDomThresholdTable[key.Get(0)] = dbEntry{entry: e} + } + + // Read port from APPL_DB + app.applPortTable = make(map[string]dbEntry) + + applPortTbl, derr := applDb.GetTable(app.applPortTs) + if derr != nil { + log.Error("APPL PORT table get failed!") + return GetResponse{Payload: payload}, derr + } + + applPortTblKeys, _ := applPortTbl.GetKeys() + for _, key := range applPortTblKeys { + e, kerr := applPortTbl.GetEntry(key) + if kerr != nil { + log.Error("PORT entry get failed!") + return GetResponse{Payload: payload}, kerr + } + + app.applPortTable[key.Get(0)] = dbEntry{entry: e} + } + targetUriPath, perr := getYangPathFromUri(app.path.Path) if perr != nil { log.Infof("getYangPathFromUri failed.") @@ -192,7 +296,7 @@ func (app *PlatformApp) processGet(dbs [db.MaxDB]*db.DB, fmtType TranslibFmtType var err error if isSubtreeRequest(targetUriPath, "/openconfig-platform:components") { - err = app.doGetSysEeprom() + err = app.doGetPlatformInfo() } else { err = errors.New("Not supported component") } @@ -430,70 +534,1568 @@ func (app *PlatformApp) getSysEepromFromDb(eeprom *ocbinds.OpenconfigPlatform_Co return nil } -func (app *PlatformApp) doGetSysEeprom() error { +type CompStateDb struct { + Serial string + Model string +} - log.Infof("Preparing collection for system eeprom") +func (app *PlatformApp) getCompStateDbObj(ifName string) CompStateDb { + log.Infof("parseCompStateDb Enter ifName=%s", ifName) - var err error - pf_cpts := app.getAppRootObject() + var compStateDbObj CompStateDb + + transceiverInfoTable := app.transceiverInfoTable[ifName].entry + + compStateDbObj.Serial = transceiverInfoTable.Get("serial") + compStateDbObj.Model = transceiverInfoTable.Get("model") + + return compStateDbObj +} + +func (app *PlatformApp) getCompStateFromDb(oc_val *ocbinds.OpenconfigPlatform_Components_Component_State, all bool, compName string) error { + log.Infof("getCompStateFromDb Enter compName=%s", compName) + + ifName := strings.Replace(compName, "transceiver_", "", -1) + compStateDb := app.getCompStateDbObj(ifName) targetUriPath, _ := getYangPathFromUri(app.path.Path) - switch targetUriPath { - case "/openconfig-platform:components": - pf_comp, _ := pf_cpts.NewComponent("System Eeprom") - ygot.BuildEmptyTree(pf_comp) - err = app.getSysEepromFromDb(pf_comp.State, true) - case "/openconfig-platform:components/component": - compName := app.path.Var("name") - if compName == "" { - pf_comp, _ := pf_cpts.NewComponent("System Eeprom") - ygot.BuildEmptyTree(pf_comp) - err = app.getSysEepromFromDb(pf_comp.State, true) - } else { - if compName != "System Eeprom" { - err = errors.New("Invalid component name") - break - } - pf_comp := pf_cpts.Component[compName] - if pf_comp != nil { - ygot.BuildEmptyTree(pf_comp) - err = app.getSysEepromFromDb(pf_comp.State, true) + if all || targetUriPath == "/openconfig-platform:components/component/state/serial-no" { + transceiverInfoTable := app.transceiverInfoTable[ifName].entry + if transceiverInfoTable.Has("serial") { + oc_val.SerialNo = &compStateDb.Serial + } + } + if all || targetUriPath == "/openconfig-platform:components/component/state/part-no" { + transceiverInfoTable := app.transceiverInfoTable[ifName].entry + if transceiverInfoTable.Has("model") { + oc_val.PartNo = &compStateDb.Model + } + } + + return nil +} + +type CompTransceiverStateDb struct { + Connector string + Manufacturer string + Vendor_Oui string + Vendor_Rev string + Serial string + Vendor_Date string +} + +func (app *PlatformApp) getCompTransceiverStateDbObj(ifName string) CompTransceiverStateDb { + log.Infof("parseCompTransceiverStateDb Enter ifName=%s", ifName) + + var compTransceiverStateDbObj CompTransceiverStateDb + + transceiverInfoTable := app.transceiverInfoTable[ifName].entry + + compTransceiverStateDbObj.Connector = transceiverInfoTable.Get("connector") + compTransceiverStateDbObj.Manufacturer = transceiverInfoTable.Get("manufacturer") + compTransceiverStateDbObj.Vendor_Oui = transceiverInfoTable.Get("vendor_oui") + compTransceiverStateDbObj.Vendor_Rev = transceiverInfoTable.Get("vendor_rev") + compTransceiverStateDbObj.Serial = transceiverInfoTable.Get("serial") + compTransceiverStateDbObj.Vendor_Date = transceiverInfoTable.Get("vendor_date") + + return compTransceiverStateDbObj +} + +func (app *PlatformApp) getCompTransceiverStateFromDb(oc_val *ocbinds.OpenconfigPlatform_Components_Component_Transceiver_State, all bool, compName string) error { + log.Infof("getCompTransceiverStateFromDb Enter compName=%s", compName) + + ifName := strings.Replace(compName, "transceiver_", "", -1) + compTransceiverStateDb := app.getCompTransceiverStateDbObj(ifName) + + targetUriPath, _ := getYangPathFromUri(app.path.Path) + + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/state/connector-type" { + transceiverInfoTable := app.transceiverInfoTable[ifName].entry + if transceiverInfoTable.Has("connector") { + if strings.HasPrefix(compTransceiverStateDb.Connector, "AOC") { + oc_val.ConnectorType = ocbinds.OpenconfigTransportTypes_FIBER_CONNECTOR_TYPE_AOC_CONNECTOR + } else if strings.HasPrefix(compTransceiverStateDb.Connector, "DAC") { + oc_val.ConnectorType = ocbinds.OpenconfigTransportTypes_FIBER_CONNECTOR_TYPE_DAC_CONNECTOR + } else if strings.HasPrefix(compTransceiverStateDb.Connector, "LC") { + oc_val.ConnectorType = ocbinds.OpenconfigTransportTypes_FIBER_CONNECTOR_TYPE_LC_CONNECTOR + } else if strings.HasPrefix(compTransceiverStateDb.Connector, "MPO") { + oc_val.ConnectorType = ocbinds.OpenconfigTransportTypes_FIBER_CONNECTOR_TYPE_MPO_CONNECTOR + } else if strings.HasPrefix(compTransceiverStateDb.Connector, "SC") { + oc_val.ConnectorType = ocbinds.OpenconfigTransportTypes_FIBER_CONNECTOR_TYPE_SC_CONNECTOR } else { - err = errors.New("Invalid input component name") + oc_val.ConnectorType = ocbinds.OpenconfigTransportTypes_FIBER_CONNECTOR_TYPE_UNSET } } - case "/openconfig-platform:components/component/state": - compName := app.path.Var("name") - if compName != "" && compName == "System Eeprom" { - pf_comp := pf_cpts.Component[compName] - if pf_comp != nil { - ygot.BuildEmptyTree(pf_comp) - err = app.getSysEepromFromDb(pf_comp.State, true) - } else { - err = errors.New("Invalid input component name") + } + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/state/vendor" { + transceiverInfoTable := app.transceiverInfoTable[ifName].entry + if transceiverInfoTable.Has("manufacturer") { + oc_val.Vendor = &compTransceiverStateDb.Manufacturer + } + } + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/state/vendor-part" { + transceiverInfoTable := app.transceiverInfoTable[ifName].entry + if transceiverInfoTable.Has("vendor_oui") { + oc_val.VendorPart = &compTransceiverStateDb.Vendor_Oui + } + } + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/state/vendor-rev" { + transceiverInfoTable := app.transceiverInfoTable[ifName].entry + if transceiverInfoTable.Has("vendor_rev") { + oc_val.VendorRev = &compTransceiverStateDb.Vendor_Rev + } + } + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/state/serial-no" { + transceiverInfoTable := app.transceiverInfoTable[ifName].entry + if transceiverInfoTable.Has("serial") { + oc_val.SerialNo = &compTransceiverStateDb.Serial + } + } + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/state/date-code" { + transceiverInfoTable := app.transceiverInfoTable[ifName].entry + if transceiverInfoTable.Has("vendor_date") { + rex := regexp.MustCompile("[0-9]+") + subMatchString := rex.FindAllString(compTransceiverStateDb.Vendor_Date, -1) + if len(subMatchString) >= 3 { + if len(subMatchString[0]) == 4 && len(subMatchString[1]) == 2 && len(subMatchString[2]) == 2 { + vendorDate := fmt.Sprintf("%s-%s-%sT00:00:00.000Z", subMatchString[0], subMatchString[1], subMatchString[2]) + formatMatch, _ := regexp.MatchString("[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])[Tt]00:00:00\\.000Z", vendorDate) + if formatMatch { + oc_val.DateCode = &vendorDate + } + } } - } else { - err = errors.New("Invalid component name ") } + } - default: - if isSubtreeRequest(targetUriPath, "/openconfig-platform:components/component/state") { - compName := app.path.Var("name") - if compName == "" || compName != "System Eeprom" { - err = errors.New("Invalid input component name") - } else { - pf_comp := pf_cpts.Component[compName] - if pf_comp != nil { - ygot.BuildEmptyTree(pf_comp) - err = app.getSysEepromFromDb(pf_comp.State, false) - } else { - err = errors.New("Invalid input component name") - } + return nil +} + +type CompTransceiverStateSupplyVoltageDb struct { + voltage float64 +} + +func (app *PlatformApp) getCompTransceiverStateSupplyVoltageDbObj(ifName string) CompTransceiverStateSupplyVoltageDb { + log.Infof("parseCompTransceiverStateSupplyVoltageDb Enter ifName=%s", ifName) + + var compTransceiverStateSupplyVoltageDbObj CompTransceiverStateSupplyVoltageDb + + transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry + + if transceiverDomSensorTable.Get("voltage") != "N/A" { + compTransceiverStateSupplyVoltageDbObj.voltage, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("voltage"), 64) + } else { + compTransceiverStateSupplyVoltageDbObj.voltage, _ = strconv.ParseFloat("NaN", 64) + } + + return compTransceiverStateSupplyVoltageDbObj +} + +func (app *PlatformApp) getCompTransceiverStateSupplyVoltageFromDb(oc_val *ocbinds.OpenconfigPlatform_Components_Component_Transceiver_State_SupplyVoltage, all bool, compName string) error { + log.Infof("getCompTransceiverStateSupplyVoltageFromDb Enter compName=%s", compName) + + ifName := strings.Replace(compName, "transceiver_", "", -1) + compTransceiverStateSupplyVoltageDb := app.getCompTransceiverStateSupplyVoltageDbObj(ifName) + + targetUriPath, _ := getYangPathFromUri(app.path.Path) + + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/state/supply-voltage/instant" { + transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry + if transceiverDomSensorTable.Has("voltage") { + voltage := math.Floor(compTransceiverStateSupplyVoltageDb.voltage*fractionDigits2) / fractionDigits2 + oc_val.Instant = &voltage + } + } + + return nil +} + +type CompTransceiverPhysicalChannelStateLaserTemperatureDb struct { + temperature float64 +} + +func (app *PlatformApp) getCompTransceiverPhysicalChannelStateLaserTemperatureDbObj(ifName string) CompTransceiverPhysicalChannelStateLaserTemperatureDb { + log.Infof("parseCompTransceiverPhysicalChannelStateLaserTemperatureDb Enter ifName=%s", ifName) + + var compTransceiverPhysicalChannelStateLaserTemperatureDbObj CompTransceiverPhysicalChannelStateLaserTemperatureDb + + transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry + + if transceiverDomSensorTable.Get("temperature") != "N/A" { + compTransceiverPhysicalChannelStateLaserTemperatureDbObj.temperature, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("temperature"), 64) + } else { + compTransceiverPhysicalChannelStateLaserTemperatureDbObj.temperature, _ = strconv.ParseFloat("NaN", 64) + } + + return compTransceiverPhysicalChannelStateLaserTemperatureDbObj +} + +func (app *PlatformApp) getCompTransceiverPhysicalChannelStateLaserTemperatureFromDb(oc_val *ocbinds.OpenconfigPlatform_Components_Component_Transceiver_PhysicalChannels_Channel_State_LaserTemperature, all bool, compName string) error { + log.Infof("getCompTransceiverPhysicalChannelStateLaserTemperatureFromDb Enter compName=%s", compName) + + ifName := strings.Replace(compName, "transceiver_", "", -1) + compTransceiverPhysicalChannelStateLaserTemperatureDb := app.getCompTransceiverPhysicalChannelStateLaserTemperatureDbObj(ifName) + + targetUriPath, _ := getYangPathFromUri(app.path.Path) + + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/physical-channels/channel/state/laser-temperature/instant" { + transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry + if transceiverDomSensorTable.Has("temperature") { + temperature := math.Floor(compTransceiverPhysicalChannelStateLaserTemperatureDb.temperature*fractionDigits1) / fractionDigits1 + oc_val.Instant = &temperature + } + } + + return nil +} + +type CompTransceiverPhysicalChannelStateOutputPowerDb struct { + tx1power float64 + tx2power float64 + tx3power float64 + tx4power float64 + tx5power float64 + tx6power float64 + tx7power float64 + tx8power float64 +} + +func (app *PlatformApp) getCompTransceiverPhysicalChannelStateOutputPowerDbObj(ifName string) CompTransceiverPhysicalChannelStateOutputPowerDb { + log.Infof("parseCompTransceiverPhysicalChannelStateOutputPowerDb Enter ifName=%s", ifName) + + var compTransceiverPhysicalChannelStateOutputPowerDbObj CompTransceiverPhysicalChannelStateOutputPowerDb + + transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry + + compTransceiverPhysicalChannelStateOutputPowerDbObj.tx1power, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("tx1power"), 64) + compTransceiverPhysicalChannelStateOutputPowerDbObj.tx2power, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("tx2power"), 64) + compTransceiverPhysicalChannelStateOutputPowerDbObj.tx3power, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("tx3power"), 64) + compTransceiverPhysicalChannelStateOutputPowerDbObj.tx4power, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("tx4power"), 64) + compTransceiverPhysicalChannelStateOutputPowerDbObj.tx5power, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("tx5power"), 64) + compTransceiverPhysicalChannelStateOutputPowerDbObj.tx6power, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("tx6power"), 64) + compTransceiverPhysicalChannelStateOutputPowerDbObj.tx7power, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("tx7power"), 64) + compTransceiverPhysicalChannelStateOutputPowerDbObj.tx8power, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("tx8power"), 64) + + return compTransceiverPhysicalChannelStateOutputPowerDbObj +} + +func (app *PlatformApp) getCompTransceiverPhysicalChannelStateOutputPowerFromDb(oc_val *ocbinds.OpenconfigPlatform_Components_Component_Transceiver_PhysicalChannels_Channel_State_OutputPower, all bool, compName string, laneIndex uint16) error { + log.Infof("getCompTransceiverPhysicalChannelStateOutputPowerFromDb Enter compName=%s laneIndex=%d", compName, laneIndex) + + ifName := strings.Replace(compName, "transceiver_", "", -1) + compTransceiverPhysicalChannelStateOutputPowerDb := app.getCompTransceiverPhysicalChannelStateOutputPowerDbObj(ifName) + + targetUriPath, _ := getYangPathFromUri(app.path.Path) + + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/physical-channels/channel/state/output-power/instant" { + switch laneIndex { + case 0: + transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry + if transceiverDomSensorTable.Has("tx1power") { + tx1power := math.Floor(compTransceiverPhysicalChannelStateOutputPowerDb.tx1power*fractionDigits2) / fractionDigits2 + oc_val.Instant = &tx1power + } + case 1: + transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry + if transceiverDomSensorTable.Has("tx2power") { + tx2power := math.Floor(compTransceiverPhysicalChannelStateOutputPowerDb.tx2power*fractionDigits2) / fractionDigits2 + oc_val.Instant = &tx2power + } + case 2: + transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry + if transceiverDomSensorTable.Has("tx3power") { + tx3power := math.Floor(compTransceiverPhysicalChannelStateOutputPowerDb.tx3power*fractionDigits2) / fractionDigits2 + oc_val.Instant = &tx3power + } + case 3: + transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry + if transceiverDomSensorTable.Has("tx4power") { + tx4power := math.Floor(compTransceiverPhysicalChannelStateOutputPowerDb.tx4power*fractionDigits2) / fractionDigits2 + oc_val.Instant = &tx4power + } + case 4: + transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry + if transceiverDomSensorTable.Has("tx5power") { + tx5power := math.Floor(compTransceiverPhysicalChannelStateOutputPowerDb.tx5power*fractionDigits2) / fractionDigits2 + oc_val.Instant = &tx5power + } + case 5: + transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry + if transceiverDomSensorTable.Has("tx6power") { + tx6power := math.Floor(compTransceiverPhysicalChannelStateOutputPowerDb.tx6power*fractionDigits2) / fractionDigits2 + oc_val.Instant = &tx6power + } + case 6: + transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry + if transceiverDomSensorTable.Has("tx7power") { + tx7power := math.Floor(compTransceiverPhysicalChannelStateOutputPowerDb.tx7power*fractionDigits2) / fractionDigits2 + oc_val.Instant = &tx7power + } + case 7: + transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry + if transceiverDomSensorTable.Has("tx8power") { + tx8power := math.Floor(compTransceiverPhysicalChannelStateOutputPowerDb.tx8power*fractionDigits2) / fractionDigits2 + oc_val.Instant = &tx8power } - } else { - err = errors.New("Invalid Path") } } - return err + + return nil } + +type CompTransceiverPhysicalChannelStateInputPowerDb struct { + rx1power float64 + rx2power float64 + rx3power float64 + rx4power float64 + rx5power float64 + rx6power float64 + rx7power float64 + rx8power float64 +} + +func (app *PlatformApp) getCompTransceiverPhysicalChannelStateInputPowerDbObj(ifName string) CompTransceiverPhysicalChannelStateInputPowerDb { + log.Infof("parseCompTransceiverPhysicalChannelStateInputPowerDb Enter ifName=%s", ifName) + + var compTransceiverPhysicalChannelStateInputPowerDbObj CompTransceiverPhysicalChannelStateInputPowerDb + + transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry + + compTransceiverPhysicalChannelStateInputPowerDbObj.rx1power, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("rx1power"), 64) + compTransceiverPhysicalChannelStateInputPowerDbObj.rx2power, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("rx2power"), 64) + compTransceiverPhysicalChannelStateInputPowerDbObj.rx3power, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("rx3power"), 64) + compTransceiverPhysicalChannelStateInputPowerDbObj.rx4power, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("rx4power"), 64) + compTransceiverPhysicalChannelStateInputPowerDbObj.rx5power, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("rx5power"), 64) + compTransceiverPhysicalChannelStateInputPowerDbObj.rx6power, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("rx6power"), 64) + compTransceiverPhysicalChannelStateInputPowerDbObj.rx7power, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("rx7power"), 64) + compTransceiverPhysicalChannelStateInputPowerDbObj.rx8power, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("rx8power"), 64) + + return compTransceiverPhysicalChannelStateInputPowerDbObj +} + +func (app *PlatformApp) getCompTransceiverPhysicalChannelStateInputPowerFromDb(oc_val *ocbinds.OpenconfigPlatform_Components_Component_Transceiver_PhysicalChannels_Channel_State_InputPower, all bool, compName string, laneIndex uint16) error { + log.Infof("getCompTransceiverPhysicalChannelStateInputPowerFromDb Enter compName=%s laneIndex=%d", compName, laneIndex) + + ifName := strings.Replace(compName, "transceiver_", "", -1) + compTransceiverPhysicalChannelStateInputPowerDb := app.getCompTransceiverPhysicalChannelStateInputPowerDbObj(ifName) + + targetUriPath, _ := getYangPathFromUri(app.path.Path) + + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/physical-channels/channel/state/input-power/instant" { + switch laneIndex { + case 0: + transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry + if transceiverDomSensorTable.Has("rx1power") { + rx1power := math.Floor(compTransceiverPhysicalChannelStateInputPowerDb.rx1power*fractionDigits2) / fractionDigits2 + oc_val.Instant = &rx1power + } + case 1: + transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry + if transceiverDomSensorTable.Has("rx2power") { + rx2power := math.Floor(compTransceiverPhysicalChannelStateInputPowerDb.rx2power*fractionDigits2) / fractionDigits2 + oc_val.Instant = &rx2power + } + case 2: + transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry + if transceiverDomSensorTable.Has("rx3power") { + rx3power := math.Floor(compTransceiverPhysicalChannelStateInputPowerDb.rx3power*fractionDigits2) / fractionDigits2 + oc_val.Instant = &rx3power + } + case 3: + transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry + if transceiverDomSensorTable.Has("rx4power") { + rx4power := math.Floor(compTransceiverPhysicalChannelStateInputPowerDb.rx4power*fractionDigits2) / fractionDigits2 + oc_val.Instant = &rx4power + } + case 4: + transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry + if transceiverDomSensorTable.Has("rx5power") { + rx5power := math.Floor(compTransceiverPhysicalChannelStateInputPowerDb.rx5power*fractionDigits2) / fractionDigits2 + oc_val.Instant = &rx5power + } + case 5: + transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry + if transceiverDomSensorTable.Has("rx6power") { + rx6power := math.Floor(compTransceiverPhysicalChannelStateInputPowerDb.rx6power*fractionDigits2) / fractionDigits2 + oc_val.Instant = &rx6power + } + case 6: + transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry + if transceiverDomSensorTable.Has("rx7power") { + rx7power := math.Floor(compTransceiverPhysicalChannelStateInputPowerDb.rx7power*fractionDigits2) / fractionDigits2 + oc_val.Instant = &rx7power + } + case 7: + transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry + if transceiverDomSensorTable.Has("rx8power") { + rx8power := math.Floor(compTransceiverPhysicalChannelStateInputPowerDb.rx8power*fractionDigits2) / fractionDigits2 + oc_val.Instant = &rx8power + } + } + } + + return nil +} + +type CompTransceiverPhysicalChannelStateLaserBiasCurrentDb struct { + tx1bias float64 + tx2bias float64 + tx3bias float64 + tx4bias float64 + tx5bias float64 + tx6bias float64 + tx7bias float64 + tx8bias float64 +} + +func (app *PlatformApp) getCompTransceiverPhysicalChannelStateLaserBiasCurrentDbObj(ifName string) CompTransceiverPhysicalChannelStateLaserBiasCurrentDb { + log.Infof("parseCompTransceiverPhysicalChannelStateLaserBiasCurrentDb Enter ifName=%s", ifName) + + var compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj CompTransceiverPhysicalChannelStateLaserBiasCurrentDb + + transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry + + if transceiverDomSensorTable.Get("tx1bias") != "N/A" { + compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj.tx1bias, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("tx1bias"), 64) + } else { + compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj.tx1bias, _ = strconv.ParseFloat("NaN", 64) + } + if transceiverDomSensorTable.Get("tx2bias") != "N/A" { + compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj.tx2bias, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("tx2bias"), 64) + } else { + compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj.tx2bias, _ = strconv.ParseFloat("NaN", 64) + } + if transceiverDomSensorTable.Get("tx3bias") != "N/A" { + compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj.tx3bias, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("tx3bias"), 64) + } else { + compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj.tx3bias, _ = strconv.ParseFloat("NaN", 64) + } + if transceiverDomSensorTable.Get("tx4bias") != "N/A" { + compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj.tx4bias, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("tx4bias"), 64) + } else { + compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj.tx4bias, _ = strconv.ParseFloat("NaN", 64) + } + if transceiverDomSensorTable.Get("tx5bias") != "N/A" { + compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj.tx5bias, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("tx5bias"), 64) + } else { + compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj.tx5bias, _ = strconv.ParseFloat("NaN", 64) + } + if transceiverDomSensorTable.Get("tx6bias") != "N/A" { + compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj.tx6bias, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("tx6bias"), 64) + } else { + compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj.tx6bias, _ = strconv.ParseFloat("NaN", 64) + } + if transceiverDomSensorTable.Get("tx7bias") != "N/A" { + compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj.tx7bias, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("tx7bias"), 64) + } else { + compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj.tx7bias, _ = strconv.ParseFloat("NaN", 64) + } + if transceiverDomSensorTable.Get("tx8bias") != "N/A" { + compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj.tx8bias, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("tx8bias"), 64) + } else { + compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj.tx8bias, _ = strconv.ParseFloat("NaN", 64) + } + + return compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj +} + +func (app *PlatformApp) getCompTransceiverPhysicalChannelStateLaserBiasCurrentFromDb(oc_val *ocbinds.OpenconfigPlatform_Components_Component_Transceiver_PhysicalChannels_Channel_State_LaserBiasCurrent, all bool, compName string, laneIndex uint16) error { + log.Infof("getCompTransceiverPhysicalChannelStateLaserBiasCurrentFromDb Enter compName=%s laneIndex=%d", compName, laneIndex) + + ifName := strings.Replace(compName, "transceiver_", "", -1) + compTransceiverPhysicalChannelStateLaserBiasCurrentDb := app.getCompTransceiverPhysicalChannelStateLaserBiasCurrentDbObj(ifName) + + targetUriPath, _ := getYangPathFromUri(app.path.Path) + + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/physical-channels/channel/state/laser-bias-current/instant" { + switch laneIndex { + case 0: + transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry + if transceiverDomSensorTable.Has("tx1bias") { + tx1bias := math.Floor(compTransceiverPhysicalChannelStateLaserBiasCurrentDb.tx1bias*fractionDigits2) / fractionDigits2 + oc_val.Instant = &tx1bias + } + case 1: + transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry + if transceiverDomSensorTable.Has("tx2bias") { + tx2bias := math.Floor(compTransceiverPhysicalChannelStateLaserBiasCurrentDb.tx2bias*fractionDigits2) / fractionDigits2 + oc_val.Instant = &tx2bias + } + case 2: + transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry + if transceiverDomSensorTable.Has("tx3bias") { + tx3bias := math.Floor(compTransceiverPhysicalChannelStateLaserBiasCurrentDb.tx3bias*fractionDigits2) / fractionDigits2 + oc_val.Instant = &tx3bias + } + case 3: + transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry + if transceiverDomSensorTable.Has("tx4bias") { + tx4bias := math.Floor(compTransceiverPhysicalChannelStateLaserBiasCurrentDb.tx4bias*fractionDigits2) / fractionDigits2 + oc_val.Instant = &tx4bias + } + case 4: + transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry + if transceiverDomSensorTable.Has("tx5bias") { + tx5bias := math.Floor(compTransceiverPhysicalChannelStateLaserBiasCurrentDb.tx5bias*fractionDigits2) / fractionDigits2 + oc_val.Instant = &tx5bias + } + case 5: + transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry + if transceiverDomSensorTable.Has("tx6bias") { + tx6bias := math.Floor(compTransceiverPhysicalChannelStateLaserBiasCurrentDb.tx6bias*fractionDigits2) / fractionDigits2 + oc_val.Instant = &tx6bias + } + case 6: + transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry + if transceiverDomSensorTable.Has("tx7bias") { + tx7bias := math.Floor(compTransceiverPhysicalChannelStateLaserBiasCurrentDb.tx7bias*fractionDigits2) / fractionDigits2 + oc_val.Instant = &tx7bias + } + case 7: + transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry + if transceiverDomSensorTable.Has("tx8bias") { + tx8bias := math.Floor(compTransceiverPhysicalChannelStateLaserBiasCurrentDb.tx8bias*fractionDigits2) / fractionDigits2 + oc_val.Instant = &tx8bias + } + } + } + + return nil +} + +type CompTransceiverThresholdStateDb struct { + temphighalarm float64 + templowalarm float64 + vcchighalarm float64 + vcclowalarm float64 + temphighwarning float64 + templowwarning float64 + vcchighwarning float64 + vcclowwarning float64 + txpowerhighalarm float64 + txpowerlowalarm float64 + rxpowerhighalarm float64 + rxpowerlowalarm float64 + txbiashighalarm float64 + txbiaslowalarm float64 + txpowerhighwarning float64 + txpowerlowwarning float64 + rxpowerhighwarning float64 + rxpowerlowwarning float64 + txbiashighwarning float64 + txbiaslowwarning float64 +} + +func (app *PlatformApp) getCompTransceiverThresholdStateDbObj(ifName string) CompTransceiverThresholdStateDb { + log.Infof("parseCompTransceiverThresholdStateDb Enter ifName=%s", ifName) + + var compTransceiverThresholdStateDbObj CompTransceiverThresholdStateDb + + transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry + + compTransceiverThresholdStateDbObj.temphighalarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("temphighalarm"), 64) + compTransceiverThresholdStateDbObj.templowalarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("templowalarm"), 64) + compTransceiverThresholdStateDbObj.vcchighalarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("vcchighalarm"), 64) + compTransceiverThresholdStateDbObj.vcclowalarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("vcclowalarm"), 64) + compTransceiverThresholdStateDbObj.temphighwarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("temphighwarning"), 64) + compTransceiverThresholdStateDbObj.templowwarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("templowwarning"), 64) + compTransceiverThresholdStateDbObj.vcchighwarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("vcchighwarning"), 64) + compTransceiverThresholdStateDbObj.vcclowwarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("vcclowwarning"), 64) + compTransceiverThresholdStateDbObj.txpowerhighalarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("txpowerhighalarm"), 64) + compTransceiverThresholdStateDbObj.txpowerlowalarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("txpowerlowalarm"), 64) + compTransceiverThresholdStateDbObj.rxpowerhighalarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("rxpowerhighalarm"), 64) + compTransceiverThresholdStateDbObj.rxpowerlowalarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("rxpowerlowalarm"), 64) + compTransceiverThresholdStateDbObj.txbiashighalarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("txbiashighalarm"), 64) + compTransceiverThresholdStateDbObj.txbiaslowalarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("txbiaslowalarm"), 64) + compTransceiverThresholdStateDbObj.txpowerhighwarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("txpowerhighwarning"), 64) + compTransceiverThresholdStateDbObj.txpowerlowwarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("txpowerlowwarning"), 64) + compTransceiverThresholdStateDbObj.rxpowerhighwarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("rxpowerhighwarning"), 64) + compTransceiverThresholdStateDbObj.rxpowerlowwarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("rxpowerlowwarning"), 64) + compTransceiverThresholdStateDbObj.txbiashighwarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("txbiashighwarning"), 64) + compTransceiverThresholdStateDbObj.txbiaslowwarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("txbiaslowwarning"), 64) + + return compTransceiverThresholdStateDbObj +} + +func (app *PlatformApp) getCompTransceiverThresholdStateFromDb(oc_val *ocbinds.OpenconfigPlatform_Components_Component_Transceiver_Thresholds_Threshold_State, all bool, compName string, severityName string) error { + log.Infof("getCompTransceiverThresholdStateFromDb Enter compName=%s severityName=%s", compName, severityName) + + ifName := strings.Replace(compName, "transceiver_", "", -1) + compTransceiverThresholdStateDb := app.getCompTransceiverThresholdStateDbObj(ifName) + + targetUriPath, _ := getYangPathFromUri(app.path.Path) + + if severityName == "CRITICAL" { + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/laser-temperature-upper" { + transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry + if transceiverDomThresholdTable.Has("temphighalarm") { + temphighalarm := math.Floor(compTransceiverThresholdStateDb.temphighalarm*fractionDigits1) / fractionDigits1 + oc_val.LaserTemperatureUpper = &temphighalarm + } + } + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/laser-temperature-lower" { + transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry + if transceiverDomThresholdTable.Has("templowalarm") { + templowalarm := math.Floor(compTransceiverThresholdStateDb.templowalarm*fractionDigits1) / fractionDigits1 + oc_val.LaserTemperatureLower = &templowalarm + } + } + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/supply-voltage-upper" { + transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry + if transceiverDomThresholdTable.Has("vcchighalarm") { + vcchighalarm := math.Floor(compTransceiverThresholdStateDb.vcchighalarm*fractionDigits2) / fractionDigits2 + oc_val.SupplyVoltageUpper = &vcchighalarm + } + } + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/supply-voltage-lower" { + transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry + if transceiverDomThresholdTable.Has("vcclowalarm") { + vcclowalarm := math.Floor(compTransceiverThresholdStateDb.vcclowalarm*fractionDigits2) / fractionDigits2 + oc_val.SupplyVoltageLower = &vcclowalarm + } + } + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/output-power-upper" { + transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry + if transceiverDomThresholdTable.Has("txpowerhighalarm") { + txpowerhighalarm := math.Floor(compTransceiverThresholdStateDb.txpowerhighalarm*fractionDigits2) / fractionDigits2 + oc_val.OutputPowerUpper = &txpowerhighalarm + } + } + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/output-power-lower" { + transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry + if transceiverDomThresholdTable.Has("txpowerlowalarm") { + txpowerlowalarm := math.Floor(compTransceiverThresholdStateDb.txpowerlowalarm*fractionDigits2) / fractionDigits2 + oc_val.OutputPowerLower = &txpowerlowalarm + } + } + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/input-power-upper" { + transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry + if transceiverDomThresholdTable.Has("rxpowerhighalarm") { + rxpowerhighalarm := math.Floor(compTransceiverThresholdStateDb.rxpowerhighalarm*fractionDigits2) / fractionDigits2 + oc_val.InputPowerUpper = &rxpowerhighalarm + } + } + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/input-power-lower" { + transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry + if transceiverDomThresholdTable.Has("rxpowerlowalarm") { + rxpowerlowalarm := math.Floor(compTransceiverThresholdStateDb.rxpowerlowalarm*fractionDigits2) / fractionDigits2 + oc_val.InputPowerLower = &rxpowerlowalarm + } + } + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/laser-bias-current-upper" { + transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry + if transceiverDomThresholdTable.Has("txbiashighalarm") { + txbiashighalarm := math.Floor(compTransceiverThresholdStateDb.txbiashighalarm*fractionDigits2) / fractionDigits2 + oc_val.LaserBiasCurrentUpper = &txbiashighalarm + } + } + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/laser-bias-current-lower" { + transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry + if transceiverDomThresholdTable.Has("txbiaslowalarm") { + txbiaslowalarm := math.Floor(compTransceiverThresholdStateDb.txbiaslowalarm*fractionDigits2) / fractionDigits2 + oc_val.LaserBiasCurrentLower = &txbiaslowalarm + } + } + } + + if severityName == "WARNING" { + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/laser-temperature-upper" { + transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry + if transceiverDomThresholdTable.Has("temphighwarning") { + temphighwarning := math.Floor(compTransceiverThresholdStateDb.temphighwarning*fractionDigits1) / fractionDigits1 + oc_val.LaserTemperatureUpper = &temphighwarning + } + } + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/laser-temperature-lower" { + transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry + if transceiverDomThresholdTable.Has("templowwarning") { + templowwarning := math.Floor(compTransceiverThresholdStateDb.templowwarning*fractionDigits1) / fractionDigits1 + oc_val.LaserTemperatureLower = &templowwarning + } + } + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/supply-voltage-upper" { + transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry + if transceiverDomThresholdTable.Has("vcchighwarning") { + vcchighwarning := math.Floor(compTransceiverThresholdStateDb.vcchighwarning*fractionDigits2) / fractionDigits2 + oc_val.SupplyVoltageUpper = &vcchighwarning + } + } + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/supply-voltage-lower" { + transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry + if transceiverDomThresholdTable.Has("vcclowwarning") { + vcclowwarning := math.Floor(compTransceiverThresholdStateDb.vcclowwarning*fractionDigits2) / fractionDigits2 + oc_val.SupplyVoltageLower = &vcclowwarning + } + } + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/output-power-upper" { + transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry + if transceiverDomThresholdTable.Has("txpowerhighwarning") { + v := math.Floor(compTransceiverThresholdStateDb.txpowerhighwarning*fractionDigits2) / fractionDigits2 + oc_val.OutputPowerUpper = &v + } + } + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/output-power-lower" { + transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry + if transceiverDomThresholdTable.Has("txpowerlowwarning") { + v := math.Floor(compTransceiverThresholdStateDb.txpowerlowwarning*fractionDigits2) / fractionDigits2 + oc_val.OutputPowerLower = &v + } + } + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/input-power-upper" { + transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry + if transceiverDomThresholdTable.Has("rxpowerhighwarning") { + v := math.Floor(compTransceiverThresholdStateDb.rxpowerhighwarning*fractionDigits2) / fractionDigits2 + oc_val.InputPowerUpper = &v + } + } + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/input-power-lower" { + transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry + if transceiverDomThresholdTable.Has("rxpowerlowwarning") { + v := math.Floor(compTransceiverThresholdStateDb.rxpowerlowwarning*fractionDigits2) / fractionDigits2 + oc_val.InputPowerLower = &v + } + } + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/laser-bias-current-upper" { + transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry + if transceiverDomThresholdTable.Has("txbiashighwarning") { + v := math.Floor(compTransceiverThresholdStateDb.txbiashighwarning*fractionDigits2) / fractionDigits2 + oc_val.LaserBiasCurrentUpper = &v + } + } + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/laser-bias-current-lower" { + transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry + if transceiverDomThresholdTable.Has("txbiaslowwarning") { + v := math.Floor(compTransceiverThresholdStateDb.txbiaslowwarning*fractionDigits2) / fractionDigits2 + oc_val.LaserBiasCurrentLower = &v + } + } + } + + return nil +} + +func (app *PlatformApp) doGetPlatformInfo() error { + log.Infof("Preparing collection for platform info") + + var err error + pf_cpts := app.getAppRootObject() + var compName string + var severityName string + + targetUriPath, _ := getYangPathFromUri(app.path.Path) + switch targetUriPath { + case "/openconfig-platform:components": + log.Info("case /openconfig-platform:components root") + pf_comp, _ := pf_cpts.NewComponent("System Eeprom") + ygot.BuildEmptyTree(pf_comp) + err = app.getSysEepromFromDb(pf_comp.State, true) + if err != nil { + break + } + + for epItem, _ := range app.transceiverInfoTable { + compName = "transceiver_" + epItem + pf_comp, _ := pf_cpts.NewComponent(compName) + ygot.BuildEmptyTree(pf_comp) + + err = app.getCompStateFromDb(pf_comp.State, true, compName) + if err != nil { + break + } + err = app.getCompTransceiverStateFromDb(pf_comp.Transceiver.State, true, compName) + if err != nil { + break + } + err = app.getCompTransceiverStateSupplyVoltageFromDb(pf_comp.Transceiver.State.SupplyVoltage, true, compName) + if err != nil { + break + } + ifName := strings.Replace(compName, "transceiver_", "", -1) + applPortTable := app.applPortTable[ifName].entry + + pf_channel_0, _ := pf_comp.Transceiver.PhysicalChannels.NewChannel(0) + if pf_channel_0 != nil { + ygot.BuildEmptyTree(pf_channel_0) + err = app.getCompTransceiverPhysicalChannelStateLaserTemperatureFromDb(pf_channel_0.State.LaserTemperature, true, compName) + if err != nil { + break + } + } + + for index, lane := range strings.Split(applPortTable.Get("lanes"), ",") { + laneNum, _ := strconv.ParseUint(lane, 10, 16) + pf_channel, _ := pf_comp.Transceiver.PhysicalChannels.NewChannel(uint16(laneNum)) + if pf_channel != nil { + ygot.BuildEmptyTree(pf_channel) + err = app.getCompTransceiverPhysicalChannelStateOutputPowerFromDb(pf_channel.State.OutputPower, true, compName, uint16(index)) + if err != nil { + break + } + err = app.getCompTransceiverPhysicalChannelStateInputPowerFromDb(pf_channel.State.InputPower, true, compName, uint16(index)) + if err != nil { + break + } + err = app.getCompTransceiverPhysicalChannelStateLaserBiasCurrentFromDb(pf_channel.State.LaserBiasCurrent, true, compName, uint16(index)) + } + } + } + + case "/openconfig-platform:components/component": + log.Info("case /openconfig-platform:components/component root") + compName = app.path.Var("name") + if compName == "" { + pf_comp, _ := pf_cpts.NewComponent("System Eeprom") + ygot.BuildEmptyTree(pf_comp) + err = app.getSysEepromFromDb(pf_comp.State, true) + if err != nil { + break + } + + for epItem, _ := range app.transceiverInfoTable { + compName = "transceiver_" + epItem + pf_comp, _ := pf_cpts.NewComponent(compName) + ygot.BuildEmptyTree(pf_comp) + + err = app.getCompStateFromDb(pf_comp.State, true, compName) + if err != nil { + break + } + err = app.getCompTransceiverStateFromDb(pf_comp.Transceiver.State, true, compName) + if err != nil { + break + } + err = app.getCompTransceiverStateSupplyVoltageFromDb(pf_comp.Transceiver.State.SupplyVoltage, true, compName) + if err != nil { + break + } + ifName := strings.Replace(compName, "transceiver_", "", -1) + applPortTable := app.applPortTable[ifName].entry + + pf_channel_0, _ := pf_comp.Transceiver.PhysicalChannels.NewChannel(0) + if pf_channel_0 != nil { + ygot.BuildEmptyTree(pf_channel_0) + err = app.getCompTransceiverPhysicalChannelStateLaserTemperatureFromDb(pf_channel_0.State.LaserTemperature, true, compName) + if err != nil { + break + } + } + + for index, lane := range strings.Split(applPortTable.Get("lanes"), ",") { + laneNum, _ := strconv.ParseUint(lane, 10, 16) + pf_channel, _ := pf_comp.Transceiver.PhysicalChannels.NewChannel(uint16(laneNum)) + if pf_channel != nil { + ygot.BuildEmptyTree(pf_channel) + err = app.getCompTransceiverPhysicalChannelStateOutputPowerFromDb(pf_channel.State.OutputPower, true, compName, uint16(index)) + if err != nil { + break + } + err = app.getCompTransceiverPhysicalChannelStateInputPowerFromDb(pf_channel.State.InputPower, true, compName, uint16(index)) + if err != nil { + break + } + err = app.getCompTransceiverPhysicalChannelStateLaserBiasCurrentFromDb(pf_channel.State.LaserBiasCurrent, true, compName, uint16(index)) + } + } + } + } else { + if compName != "System Eeprom" && !strings.Contains(compName, "transceiver_Ethernet") { + err = errors.New("Invalid component name") + break + } + pf_comp := pf_cpts.Component[compName] + if pf_comp != nil { + ygot.BuildEmptyTree(pf_comp) + + if compName == "System Eeprom" { + err = app.getSysEepromFromDb(pf_comp.State, true) + } + + if strings.Contains(compName, "transceiver_Ethernet") { + err = app.getCompStateFromDb(pf_comp.State, true, compName) + if err != nil { + break + } + err = app.getCompTransceiverStateFromDb(pf_comp.Transceiver.State, true, compName) + if err != nil { + break + } + err = app.getCompTransceiverStateSupplyVoltageFromDb(pf_comp.Transceiver.State.SupplyVoltage, true, compName) + if err != nil { + break + } + ifName := strings.Replace(compName, "transceiver_", "", -1) + applPortTable := app.applPortTable[ifName].entry + + pf_channel_0, _ := pf_comp.Transceiver.PhysicalChannels.NewChannel(0) + if pf_channel_0 != nil { + ygot.BuildEmptyTree(pf_channel_0) + err = app.getCompTransceiverPhysicalChannelStateLaserTemperatureFromDb(pf_channel_0.State.LaserTemperature, true, compName) + if err != nil { + break + } + } + + for index, lane := range strings.Split(applPortTable.Get("lanes"), ",") { + laneNum, _ := strconv.ParseUint(lane, 10, 16) + pf_channel, _ := pf_comp.Transceiver.PhysicalChannels.NewChannel(uint16(laneNum)) + if pf_channel != nil { + ygot.BuildEmptyTree(pf_channel) + err = app.getCompTransceiverPhysicalChannelStateOutputPowerFromDb(pf_channel.State.OutputPower, true, compName, uint16(index)) + if err != nil { + break + } + err = app.getCompTransceiverPhysicalChannelStateInputPowerFromDb(pf_channel.State.InputPower, true, compName, uint16(index)) + if err != nil { + break + } + err = app.getCompTransceiverPhysicalChannelStateLaserBiasCurrentFromDb(pf_channel.State.LaserBiasCurrent, true, compName, uint16(index)) + } + } + } + } else { + err = errors.New("Invalid input component name") + } + } + case "/openconfig-platform:components/component/state": + log.Info("case /openconfig-platform:components/component/state root") + compName = app.path.Var("name") + if compName == "System Eeprom" { + pf_comp := pf_cpts.Component[compName] + if pf_comp != nil { + ygot.BuildEmptyTree(pf_comp) + err = app.getSysEepromFromDb(pf_comp.State, true) + } else { + err = errors.New("Invalid input component name") + } + } else if strings.Contains(compName, "transceiver_Ethernet") { + pf_comp := pf_cpts.Component[compName] + if pf_comp != nil { + ygot.BuildEmptyTree(pf_comp) + err = app.getCompStateFromDb(pf_comp.State, true, compName) + } else { + err = errors.New("Invalid input component name") + } + } else { + err = errors.New("Invalid component name ") + } + case "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver": + log.Info("case /openconfig-platform:components/component/openconfig-platform-transceiver:transceiver root") + compName = app.path.Var("name") + if strings.Contains(compName, "transceiver_Ethernet") { + pf_comp := pf_cpts.Component[compName] + if pf_comp != nil { + ygot.BuildEmptyTree(pf_comp.Transceiver) + err = app.getCompTransceiverStateFromDb(pf_comp.Transceiver.State, true, compName) + if err != nil { + break + } + err = app.getCompTransceiverStateSupplyVoltageFromDb(pf_comp.Transceiver.State.SupplyVoltage, true, compName) + if err != nil { + break + } + ifName := strings.Replace(compName, "transceiver_", "", -1) + applPortTable := app.applPortTable[ifName].entry + + pf_channel_0, _ := pf_comp.Transceiver.PhysicalChannels.NewChannel(0) + if pf_channel_0 != nil { + ygot.BuildEmptyTree(pf_channel_0) + err = app.getCompTransceiverPhysicalChannelStateLaserTemperatureFromDb(pf_channel_0.State.LaserTemperature, true, compName) + if err != nil { + break + } + } + + for index, lane := range strings.Split(applPortTable.Get("lanes"), ",") { + laneNum, _ := strconv.ParseUint(lane, 10, 16) + pf_channel, _ := pf_comp.Transceiver.PhysicalChannels.NewChannel(uint16(laneNum)) + if pf_channel != nil { + ygot.BuildEmptyTree(pf_channel) + err = app.getCompTransceiverPhysicalChannelStateOutputPowerFromDb(pf_channel.State.OutputPower, true, compName, uint16(index)) + if err != nil { + break + } + err = app.getCompTransceiverPhysicalChannelStateInputPowerFromDb(pf_channel.State.InputPower, true, compName, uint16(index)) + if err != nil { + break + } + err = app.getCompTransceiverPhysicalChannelStateLaserBiasCurrentFromDb(pf_channel.State.LaserBiasCurrent, true, compName, uint16(index)) + } + } + } else { + err = errors.New("Invalid input component name") + } + } else { + err = errors.New("Invalid component name ") + } + case "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/state": + log.Info("case /openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/state root") + compName = app.path.Var("name") + if strings.Contains(compName, "transceiver_Ethernet") { + pf_comp := pf_cpts.Component[compName] + if pf_comp != nil { + ygot.BuildEmptyTree(pf_comp.Transceiver.State) + err = app.getCompTransceiverStateFromDb(pf_comp.Transceiver.State, true, compName) + if err != nil { + break + } + err = app.getCompTransceiverStateSupplyVoltageFromDb(pf_comp.Transceiver.State.SupplyVoltage, true, compName) + } else { + err = errors.New("Invalid input component name") + } + } else { + err = errors.New("Invalid component name ") + } + case "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/state/supply-voltage": + log.Info("case /openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/state/supply-voltage root") + compName = app.path.Var("name") + if strings.Contains(compName, "transceiver_Ethernet") { + pf_comp := pf_cpts.Component[compName] + if pf_comp != nil { + ygot.BuildEmptyTree(pf_comp) + err = app.getCompTransceiverStateSupplyVoltageFromDb(pf_comp.Transceiver.State.SupplyVoltage, true, compName) + } else { + err = errors.New("Invalid input component name") + } + } else { + err = errors.New("Invalid component name ") + } + case "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/physical-channels": + log.Info("case /openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/physical-channels root") + compName = app.path.Var("name") + if strings.Contains(compName, "transceiver_Ethernet") { + pf_comp := pf_cpts.Component[compName] + if pf_comp != nil { + ygot.BuildEmptyTree(pf_comp) + ifName := strings.Replace(compName, "transceiver_", "", -1) + applPortTable := app.applPortTable[ifName].entry + + pf_channel_0, _ := pf_comp.Transceiver.PhysicalChannels.NewChannel(0) + if pf_channel_0 != nil { + ygot.BuildEmptyTree(pf_channel_0) + err = app.getCompTransceiverPhysicalChannelStateLaserTemperatureFromDb(pf_channel_0.State.LaserTemperature, true, compName) + if err != nil { + break + } + } + + for index, lane := range strings.Split(applPortTable.Get("lanes"), ",") { + laneNum, _ := strconv.ParseUint(lane, 10, 16) + pf_channel, _ := pf_comp.Transceiver.PhysicalChannels.NewChannel(uint16(laneNum)) + if pf_channel != nil { + ygot.BuildEmptyTree(pf_channel) + err = app.getCompTransceiverPhysicalChannelStateOutputPowerFromDb(pf_channel.State.OutputPower, true, compName, uint16(index)) + if err != nil { + break + } + err = app.getCompTransceiverPhysicalChannelStateInputPowerFromDb(pf_channel.State.InputPower, true, compName, uint16(index)) + if err != nil { + break + } + err = app.getCompTransceiverPhysicalChannelStateLaserBiasCurrentFromDb(pf_channel.State.LaserBiasCurrent, true, compName, uint16(index)) + } + } + } else { + err = errors.New("Invalid input component name") + } + } else { + err = errors.New("Invalid component name ") + } + case "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/physical-channels/channel": + log.Info("case /openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/physical-channels/channel root") + compName = app.path.Var("name") + if strings.Contains(compName, "transceiver_Ethernet") { + pf_comp := pf_cpts.Component[compName] + if pf_comp != nil { + ygot.BuildEmptyTree(pf_comp) + indexName := app.path.Var("index") + if indexName == "" { + ifName := strings.Replace(compName, "transceiver_", "", -1) + applPortTable := app.applPortTable[ifName].entry + + pf_channel_0, _ := pf_comp.Transceiver.PhysicalChannels.NewChannel(0) + if pf_channel_0 != nil { + ygot.BuildEmptyTree(pf_channel_0) + err = app.getCompTransceiverPhysicalChannelStateLaserTemperatureFromDb(pf_channel_0.State.LaserTemperature, true, compName) + if err != nil { + break + } + } + + for index, lane := range strings.Split(applPortTable.Get("lanes"), ",") { + laneNum, _ := strconv.ParseUint(lane, 10, 16) + pf_channel, _ := pf_comp.Transceiver.PhysicalChannels.NewChannel(uint16(laneNum)) + if pf_channel != nil { + ygot.BuildEmptyTree(pf_channel) + err = app.getCompTransceiverPhysicalChannelStateOutputPowerFromDb(pf_channel.State.OutputPower, true, compName, uint16(index)) + if err != nil { + break + } + err = app.getCompTransceiverPhysicalChannelStateInputPowerFromDb(pf_channel.State.InputPower, true, compName, uint16(index)) + if err != nil { + break + } + err = app.getCompTransceiverPhysicalChannelStateLaserBiasCurrentFromDb(pf_channel.State.LaserBiasCurrent, true, compName, uint16(index)) + } + } + } else { + compIndex, _ := strconv.ParseUint(indexName, 10, 16) + log.Info("compIndex =", compIndex) + ifName := strings.Replace(compName, "transceiver_", "", -1) + applPortTable := app.applPortTable[ifName].entry + + if compIndex == 0 { + pf_channel := pf_comp.Transceiver.PhysicalChannels.Channel[uint16(compIndex)] + if pf_channel != nil { + ygot.BuildEmptyTree(pf_channel) + err = app.getCompTransceiverPhysicalChannelStateLaserTemperatureFromDb(pf_channel.State.LaserTemperature, true, compName) + } else { + err = errors.New("Invalid input component index") + } + } else { + for index, lane := range strings.Split(applPortTable.Get("lanes"), ",") { + laneNum, _ := strconv.ParseUint(lane, 10, 16) + if uint16(laneNum) == uint16(compIndex) { + pf_channel := pf_comp.Transceiver.PhysicalChannels.Channel[uint16(compIndex)] + if pf_channel != nil { + ygot.BuildEmptyTree(pf_channel) + err = app.getCompTransceiverPhysicalChannelStateOutputPowerFromDb(pf_channel.State.OutputPower, true, compName, uint16(index)) + if err != nil { + break + } + err = app.getCompTransceiverPhysicalChannelStateInputPowerFromDb(pf_channel.State.InputPower, true, compName, uint16(index)) + if err != nil { + break + } + err = app.getCompTransceiverPhysicalChannelStateLaserBiasCurrentFromDb(pf_channel.State.LaserBiasCurrent, true, compName, uint16(index)) + } else { + err = errors.New("Invalid input component index") + } + break + } else { + err = errors.New("Invalid input component index") + } + } + } + } + } else { + err = errors.New("Invalid input component name") + } + } else { + err = errors.New("Invalid component name ") + } + case "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/physical-channels/channel/state": + log.Info("case /openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/physical-channels/channel/state root") + compName = app.path.Var("name") + if strings.Contains(compName, "transceiver_Ethernet") { + pf_comp := pf_cpts.Component[compName] + if pf_comp != nil { + ygot.BuildEmptyTree(pf_comp) + compIndex, _ := strconv.ParseUint(app.path.Var("index"), 10, 16) + log.Info("compIndex =", compIndex) + ifName := strings.Replace(compName, "transceiver_", "", -1) + applPortTable := app.applPortTable[ifName].entry + + if compIndex == 0 { + pf_channel := pf_comp.Transceiver.PhysicalChannels.Channel[uint16(compIndex)] + if pf_channel != nil { + ygot.BuildEmptyTree(pf_channel.State) + err = app.getCompTransceiverPhysicalChannelStateLaserTemperatureFromDb(pf_channel.State.LaserTemperature, true, compName) + } else { + err = errors.New("Invalid input component index") + } + } else { + for index, lane := range strings.Split(applPortTable.Get("lanes"), ",") { + laneNum, _ := strconv.ParseUint(lane, 10, 16) + if uint16(laneNum) == uint16(compIndex) { + pf_channel := pf_comp.Transceiver.PhysicalChannels.Channel[uint16(compIndex)] + if pf_channel != nil { + ygot.BuildEmptyTree(pf_channel.State) + err = app.getCompTransceiverPhysicalChannelStateOutputPowerFromDb(pf_channel.State.OutputPower, true, compName, uint16(index)) + if err != nil { + break + } + err = app.getCompTransceiverPhysicalChannelStateInputPowerFromDb(pf_channel.State.InputPower, true, compName, uint16(index)) + if err != nil { + break + } + err = app.getCompTransceiverPhysicalChannelStateLaserBiasCurrentFromDb(pf_channel.State.LaserBiasCurrent, true, compName, uint16(index)) + } else { + err = errors.New("Invalid input component index") + } + break + } else { + err = errors.New("Invalid input component index") + } + } + } + } else { + err = errors.New("Invalid input component name") + } + } else { + err = errors.New("Invalid component name ") + } + case "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/physical-channels/channel/state/laser-temperature": + log.Info("case /openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/physical-channels/channel/state/laser-temperature root") + compName = app.path.Var("name") + if strings.Contains(compName, "transceiver_Ethernet") { + pf_comp := pf_cpts.Component[compName] + if pf_comp != nil { + ygot.BuildEmptyTree(pf_comp) + compIndex, _ := strconv.ParseUint(app.path.Var("index"), 10, 16) + log.Info("compIndex =", compIndex) + + if compIndex == 0 { + pf_channel := pf_comp.Transceiver.PhysicalChannels.Channel[uint16(compIndex)] + if pf_channel != nil { + ygot.BuildEmptyTree(pf_channel.State) + err = app.getCompTransceiverPhysicalChannelStateLaserTemperatureFromDb(pf_channel.State.LaserTemperature, true, compName) + } else { + err = errors.New("Invalid input component index") + } + } else { + err = errors.New("Invalid input component index") + } + } else { + err = errors.New("Invalid input component name") + } + } else { + err = errors.New("Invalid component name ") + } + case "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/physical-channels/channel/state/output-power": + log.Info("case /openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/physical-channels/channel/state/output-power root") + compName = app.path.Var("name") + if strings.Contains(compName, "transceiver_Ethernet") { + pf_comp := pf_cpts.Component[compName] + if pf_comp != nil { + ygot.BuildEmptyTree(pf_comp) + compIndex, _ := strconv.ParseUint(app.path.Var("index"), 10, 16) + log.Info("compIndex =", compIndex) + ifName := strings.Replace(compName, "transceiver_", "", -1) + applPortTable := app.applPortTable[ifName].entry + + for index, lane := range strings.Split(applPortTable.Get("lanes"), ",") { + laneNum, _ := strconv.ParseUint(lane, 10, 16) + if uint16(laneNum) == uint16(compIndex) { + pf_channel := pf_comp.Transceiver.PhysicalChannels.Channel[uint16(compIndex)] + if pf_channel != nil { + ygot.BuildEmptyTree(pf_channel.State) + err = app.getCompTransceiverPhysicalChannelStateOutputPowerFromDb(pf_channel.State.OutputPower, true, compName, uint16(index)) + } else { + err = errors.New("Invalid input component index") + } + break + } else { + err = errors.New("Invalid input component index") + } + } + } else { + err = errors.New("Invalid input component name") + } + } else { + err = errors.New("Invalid component name ") + } + case "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/physical-channels/channel/state/input-power": + log.Info("case /openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/physical-channels/channel/state/input-power root") + compName = app.path.Var("name") + if strings.Contains(compName, "transceiver_Ethernet") { + pf_comp := pf_cpts.Component[compName] + if pf_comp != nil { + ygot.BuildEmptyTree(pf_comp) + compIndex, _ := strconv.ParseUint(app.path.Var("index"), 10, 16) + log.Info("compIndex =", compIndex) + ifName := strings.Replace(compName, "transceiver_", "", -1) + applPortTable := app.applPortTable[ifName].entry + + for index, lane := range strings.Split(applPortTable.Get("lanes"), ",") { + laneNum, _ := strconv.ParseUint(lane, 10, 16) + if uint16(laneNum) == uint16(compIndex) { + pf_channel := pf_comp.Transceiver.PhysicalChannels.Channel[uint16(compIndex)] + if pf_channel != nil { + ygot.BuildEmptyTree(pf_channel.State) + err = app.getCompTransceiverPhysicalChannelStateInputPowerFromDb(pf_channel.State.InputPower, true, compName, uint16(index)) + } else { + err = errors.New("Invalid input component index") + } + break + } else { + err = errors.New("Invalid input component index") + } + } + } else { + err = errors.New("Invalid input component name") + } + } else { + err = errors.New("Invalid component name ") + } + case "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/physical-channels/channel/state/laser-bias-current": + log.Info("case /openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/physical-channels/channel/state/laser-bias-current root") + compName = app.path.Var("name") + if strings.Contains(compName, "transceiver_Ethernet") { + pf_comp := pf_cpts.Component[compName] + if pf_comp != nil { + ygot.BuildEmptyTree(pf_comp) + compIndex, _ := strconv.ParseUint(app.path.Var("index"), 10, 16) + log.Info("compIndex =", compIndex) + ifName := strings.Replace(compName, "transceiver_", "", -1) + applPortTable := app.applPortTable[ifName].entry + + for index, lane := range strings.Split(applPortTable.Get("lanes"), ",") { + laneNum, _ := strconv.ParseUint(lane, 10, 16) + if uint16(laneNum) == uint16(compIndex) { + pf_channel := pf_comp.Transceiver.PhysicalChannels.Channel[uint16(compIndex)] + if pf_channel != nil { + ygot.BuildEmptyTree(pf_channel.State) + err = app.getCompTransceiverPhysicalChannelStateLaserBiasCurrentFromDb(pf_channel.State.LaserBiasCurrent, true, compName, uint16(index)) + } else { + err = errors.New("Invalid input component index") + } + break + } else { + err = errors.New("Invalid input component index") + } + } + } else { + err = errors.New("Invalid input component name") + } + } else { + err = errors.New("Invalid component name ") + } + case "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state": + log.Info("case /openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state root") + compName = app.path.Var("name") + if strings.Contains(compName, "transceiver_Ethernet") { + pf_comp := pf_cpts.Component[compName] + if pf_comp != nil { + ygot.BuildEmptyTree(pf_comp) + severityName = app.path.Var("severity") + if strings.Contains(severityName, "CRITICAL") { + pf_threshold := pf_comp.Transceiver.Thresholds.Threshold[ocbinds.OpenconfigAlarmTypes_OPENCONFIG_ALARM_SEVERITY_CRITICAL] + if pf_threshold != nil { + ygot.BuildEmptyTree(pf_threshold.State) + err = app.getCompTransceiverThresholdStateFromDb(pf_threshold.State, true, compName, severityName) + } else { + err = errors.New("Invalid input severity name") + } + } else if strings.Contains(severityName, "WARNING") { + pf_threshold := pf_comp.Transceiver.Thresholds.Threshold[ocbinds.OpenconfigAlarmTypes_OPENCONFIG_ALARM_SEVERITY_WARNING] + if pf_threshold != nil { + ygot.BuildEmptyTree(pf_threshold.State) + err = app.getCompTransceiverThresholdStateFromDb(pf_threshold.State, true, compName, severityName) + } else { + err = errors.New("Invalid input severity name") + } + } else { + err = errors.New("Invalid input severity name") + } + } else { + err = errors.New("Invalid input component name") + } + } else { + err = errors.New("Invalid component name ") + } + + default: + if isSubtreeRequest(targetUriPath, "/openconfig-platform:components/component/state") { + compName = app.path.Var("name") + if compName == "System Eeprom" { + pf_comp := pf_cpts.Component[compName] + if pf_comp != nil { + ygot.BuildEmptyTree(pf_comp) + err = app.getSysEepromFromDb(pf_comp.State, false) + } else { + err = errors.New("Invalid input component name") + } + } else if strings.Contains(compName, "transceiver_Ethernet") { + pf_comp := pf_cpts.Component[compName] + if pf_comp != nil { + ygot.BuildEmptyTree(pf_comp) + err = app.getCompStateFromDb(pf_comp.State, false, compName) + } else { + err = errors.New("Invalid input component name") + } + } else { + err = errors.New("Invalid input component name") + } + } else if isSubtreeRequest(targetUriPath, "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/state/supply-voltage") { + compName = app.path.Var("name") + if strings.Contains(compName, "transceiver_Ethernet") { + pf_comp := pf_cpts.Component[compName] + if pf_comp != nil { + ygot.BuildEmptyTree(pf_comp) + err = app.getCompTransceiverStateSupplyVoltageFromDb(pf_comp.Transceiver.State.SupplyVoltage, false, compName) + } else { + err = errors.New("Invalid input component name") + } + } else { + err = errors.New("Invalid input component name") + } + } else if isSubtreeRequest(targetUriPath, "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/state") { + compName = app.path.Var("name") + if strings.Contains(compName, "transceiver_Ethernet") { + pf_comp := pf_cpts.Component[compName] + if pf_comp != nil { + ygot.BuildEmptyTree(pf_comp) + err = app.getCompTransceiverStateFromDb(pf_comp.Transceiver.State, false, compName) + } else { + err = errors.New("Invalid input component name") + } + } else { + err = errors.New("Invalid input component name") + } + } else if isSubtreeRequest(targetUriPath, "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/physical-channels/channel/state/laser-temperature") { + compName = app.path.Var("name") + if strings.Contains(compName, "transceiver_Ethernet") { + pf_comp := pf_cpts.Component[compName] + if pf_comp != nil { + ygot.BuildEmptyTree(pf_comp) + compIndex, _ := strconv.ParseUint(app.path.Var("index"), 10, 16) + + if compIndex == 0 { + pf_channel := pf_comp.Transceiver.PhysicalChannels.Channel[uint16(compIndex)] + if pf_channel != nil { + ygot.BuildEmptyTree(pf_channel.State) + err = app.getCompTransceiverPhysicalChannelStateLaserTemperatureFromDb(pf_channel.State.LaserTemperature, false, compName) + } else { + err = errors.New("Invalid input component index") + } + } else { + err = errors.New("Invalid input component index") + } + } else { + err = errors.New("Invalid input component name") + } + } else { + err = errors.New("Invalid input component name") + } + } else if isSubtreeRequest(targetUriPath, "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/physical-channels/channel/state/output-power") { + compName = app.path.Var("name") + if strings.Contains(compName, "transceiver_Ethernet") { + pf_comp := pf_cpts.Component[compName] + if pf_comp != nil { + ygot.BuildEmptyTree(pf_comp) + compIndex, _ := strconv.ParseUint(app.path.Var("index"), 10, 16) + ifName := strings.Replace(compName, "transceiver_", "", -1) + applPortTable := app.applPortTable[ifName].entry + + for index, lane := range strings.Split(applPortTable.Get("lanes"), ",") { + laneNum, _ := strconv.ParseUint(lane, 10, 16) + if uint16(laneNum) == uint16(compIndex) { + pf_channel := pf_comp.Transceiver.PhysicalChannels.Channel[uint16(compIndex)] + if pf_channel != nil { + ygot.BuildEmptyTree(pf_channel.State) + err = app.getCompTransceiverPhysicalChannelStateOutputPowerFromDb(pf_channel.State.OutputPower, false, compName, uint16(index)) + } else { + err = errors.New("Invalid input component index") + } + break + } else { + err = errors.New("Invalid input component index") + } + } + } else { + err = errors.New("Invalid input component name") + } + } else { + err = errors.New("Invalid input component name") + } + } else if isSubtreeRequest(targetUriPath, "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/physical-channels/channel/state/input-power") { + compName = app.path.Var("name") + if strings.Contains(compName, "transceiver_Ethernet") { + pf_comp := pf_cpts.Component[compName] + if pf_comp != nil { + ygot.BuildEmptyTree(pf_comp) + compIndex, _ := strconv.ParseUint(app.path.Var("index"), 10, 16) + ifName := strings.Replace(compName, "transceiver_", "", -1) + applPortTable := app.applPortTable[ifName].entry + + for index, lane := range strings.Split(applPortTable.Get("lanes"), ",") { + laneNum, _ := strconv.ParseUint(lane, 10, 16) + if uint16(laneNum) == uint16(compIndex) { + pf_channel := pf_comp.Transceiver.PhysicalChannels.Channel[uint16(compIndex)] + if pf_channel != nil { + ygot.BuildEmptyTree(pf_channel.State) + err = app.getCompTransceiverPhysicalChannelStateInputPowerFromDb(pf_channel.State.InputPower, false, compName, uint16(index)) + } else { + err = errors.New("Invalid input component index") + } + break + } else { + err = errors.New("Invalid input component index") + } + } + } else { + err = errors.New("Invalid input component name") + } + } else { + err = errors.New("Invalid input component name") + } + } else if isSubtreeRequest(targetUriPath, "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/physical-channels/channel/state/laser-bias-current") { + compName = app.path.Var("name") + if strings.Contains(compName, "transceiver_Ethernet") { + pf_comp := pf_cpts.Component[compName] + if pf_comp != nil { + ygot.BuildEmptyTree(pf_comp) + compIndex, _ := strconv.ParseUint(app.path.Var("index"), 10, 16) + ifName := strings.Replace(compName, "transceiver_", "", -1) + applPortTable := app.applPortTable[ifName].entry + + for index, lane := range strings.Split(applPortTable.Get("lanes"), ",") { + laneNum, _ := strconv.ParseUint(lane, 10, 16) + if uint16(laneNum) == uint16(compIndex) { + pf_channel := pf_comp.Transceiver.PhysicalChannels.Channel[uint16(compIndex)] + if pf_channel != nil { + ygot.BuildEmptyTree(pf_channel.State) + err = app.getCompTransceiverPhysicalChannelStateLaserBiasCurrentFromDb(pf_channel.State.LaserBiasCurrent, false, compName, uint16(index)) + } else { + err = errors.New("Invalid input component index") + } + break + } else { + err = errors.New("Invalid input component index") + } + } + } else { + err = errors.New("Invalid input component name") + } + } else { + err = errors.New("Invalid input component name") + } + } else if isSubtreeRequest(targetUriPath, "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state") { + compName = app.path.Var("name") + if strings.Contains(compName, "transceiver_Ethernet") { + pf_comp := pf_cpts.Component[compName] + if pf_comp != nil { + ygot.BuildEmptyTree(pf_comp) + severityName = app.path.Var("severity") + if strings.Contains(severityName, "CRITICAL") { + pf_threshold := pf_comp.Transceiver.Thresholds.Threshold[ocbinds.OpenconfigAlarmTypes_OPENCONFIG_ALARM_SEVERITY_CRITICAL] + if pf_threshold != nil { + ygot.BuildEmptyTree(pf_threshold.State) + err = app.getCompTransceiverThresholdStateFromDb(pf_threshold.State, false, compName, severityName) + } else { + err = errors.New("Invalid input severity name") + } + } else if strings.Contains(severityName, "WARNING") { + pf_threshold := pf_comp.Transceiver.Thresholds.Threshold[ocbinds.OpenconfigAlarmTypes_OPENCONFIG_ALARM_SEVERITY_WARNING] + if pf_threshold != nil { + ygot.BuildEmptyTree(pf_threshold.State) + err = app.getCompTransceiverThresholdStateFromDb(pf_threshold.State, false, compName, severityName) + } else { + err = errors.New("Invalid input severity name") + } + } else { + err = errors.New("Invalid input severity name") + } + } else { + err = errors.New("Invalid input component name") + } + } else { + err = errors.New("Invalid input component name") + } + } else { + err = errors.New("Invalid Path") + } + } + return err +} \ No newline at end of file From 228f966c0ea2d1a7f3cc61cd3d36468b82b241c8 Mon Sep 17 00:00:00 2001 From: Kanji Nakano Date: Wed, 24 Dec 2025 19:28:57 +0900 Subject: [PATCH 02/12] translib: gofmt pfm_app.go Signed-off-by: Kanji Nakano --- translib/pfm_app.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/translib/pfm_app.go b/translib/pfm_app.go index 3ba8a95fd..4dba490ea 100644 --- a/translib/pfm_app.go +++ b/translib/pfm_app.go @@ -2098,4 +2098,4 @@ func (app *PlatformApp) doGetPlatformInfo() error { } } return err -} \ No newline at end of file +} From 8343c2fde2f67266b4647f767bbbfa68826268c1 Mon Sep 17 00:00:00 2001 From: Kanji Nakano Date: Mon, 25 May 2026 18:10:20 +0900 Subject: [PATCH 03/12] translib/pfm_app: rename Vendor_* struct fields to PascalCase Address review comments on PR #201: the CompTransceiverStateDb struct used snake_case fields (Vendor_Oui, Vendor_Rev, Vendor_Date) which violate Go naming conventions. Rename to VendorOui, VendorRev, VendorDate and update all references. Also add an inline comment on the vendor-part code path documenting that sourcing it from TRANSCEIVER_INFO.vendor_oui is intentional and follows the HLD's DB mapping table (sonic-net/SONiC PR #1858, Section 4 "Mapping between Openconfig YANG and Redis DB" Table 2), to avoid future reviewers re-raising the question. Signed-off-by: Kanji Nakano --- translib/pfm_app.go | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/translib/pfm_app.go b/translib/pfm_app.go index 4dba490ea..1752bf1ba 100644 --- a/translib/pfm_app.go +++ b/translib/pfm_app.go @@ -579,10 +579,10 @@ func (app *PlatformApp) getCompStateFromDb(oc_val *ocbinds.OpenconfigPlatform_Co type CompTransceiverStateDb struct { Connector string Manufacturer string - Vendor_Oui string - Vendor_Rev string + VendorOui string + VendorRev string Serial string - Vendor_Date string + VendorDate string } func (app *PlatformApp) getCompTransceiverStateDbObj(ifName string) CompTransceiverStateDb { @@ -594,10 +594,10 @@ func (app *PlatformApp) getCompTransceiverStateDbObj(ifName string) CompTranscei compTransceiverStateDbObj.Connector = transceiverInfoTable.Get("connector") compTransceiverStateDbObj.Manufacturer = transceiverInfoTable.Get("manufacturer") - compTransceiverStateDbObj.Vendor_Oui = transceiverInfoTable.Get("vendor_oui") - compTransceiverStateDbObj.Vendor_Rev = transceiverInfoTable.Get("vendor_rev") + compTransceiverStateDbObj.VendorOui = transceiverInfoTable.Get("vendor_oui") + compTransceiverStateDbObj.VendorRev = transceiverInfoTable.Get("vendor_rev") compTransceiverStateDbObj.Serial = transceiverInfoTable.Get("serial") - compTransceiverStateDbObj.Vendor_Date = transceiverInfoTable.Get("vendor_date") + compTransceiverStateDbObj.VendorDate = transceiverInfoTable.Get("vendor_date") return compTransceiverStateDbObj } @@ -637,13 +637,16 @@ func (app *PlatformApp) getCompTransceiverStateFromDb(oc_val *ocbinds.Openconfig if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/state/vendor-part" { transceiverInfoTable := app.transceiverInfoTable[ifName].entry if transceiverInfoTable.Has("vendor_oui") { - oc_val.VendorPart = &compTransceiverStateDb.Vendor_Oui + // Per HLD (sonic-net/SONiC PR #1858, "Mapping between Openconfig + // YANG and Redis DB" Table 2): vendor-part is sourced from + // STATE_DB TRANSCEIVER_INFO.vendor_oui. + oc_val.VendorPart = &compTransceiverStateDb.VendorOui } } if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/state/vendor-rev" { transceiverInfoTable := app.transceiverInfoTable[ifName].entry if transceiverInfoTable.Has("vendor_rev") { - oc_val.VendorRev = &compTransceiverStateDb.Vendor_Rev + oc_val.VendorRev = &compTransceiverStateDb.VendorRev } } if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/state/serial-no" { @@ -656,7 +659,7 @@ func (app *PlatformApp) getCompTransceiverStateFromDb(oc_val *ocbinds.Openconfig transceiverInfoTable := app.transceiverInfoTable[ifName].entry if transceiverInfoTable.Has("vendor_date") { rex := regexp.MustCompile("[0-9]+") - subMatchString := rex.FindAllString(compTransceiverStateDb.Vendor_Date, -1) + subMatchString := rex.FindAllString(compTransceiverStateDb.VendorDate, -1) if len(subMatchString) >= 3 { if len(subMatchString[0]) == 4 && len(subMatchString[1]) == 2 && len(subMatchString[2]) == 2 { vendorDate := fmt.Sprintf("%s-%s-%sT00:00:00.000Z", subMatchString[0], subMatchString[1], subMatchString[2]) From 0eb13bf845fd5a1f7c002518a1774b4d492b7ec0 Mon Sep 17 00:00:00 2001 From: Kanji Nakano Date: Mon, 25 May 2026 18:14:49 +0900 Subject: [PATCH 04/12] translib/pfm_app: collapse 8-lane channel structs into arrays Address review comments on PR #201 (maintainer-endorsed "very valid" on the output-power instance, plus systemic equivalents for input-power and laser-bias-current): - CompTransceiverPhysicalChannelStateOutputPowerDb - CompTransceiverPhysicalChannelStateInputPowerDb - CompTransceiverPhysicalChannelStateLaserBiasCurrentDb Each struct previously held eight identically-named float64 fields (tx1power..tx8power, rx1power..rx8power, tx1bias..tx8bias). The DbObj parser unrolled eight ParseFloat calls and the FromDb getter unrolled an eight-case switch that differed only in the field name. Replace each struct with a single fixed-size array of eight float64 values (TxPower / RxPower / TxBias). The parser becomes a for loop that builds the field name with fmt.Sprintf, and the getter indexes the array by laneIndex with a single bounds check. Net change is -220 / +32 lines and removes the lowercase struct fields that also violated Go naming conventions. For LaserBiasCurrent, preserve the existing N/A -> NaN handling by keeping the per-lane N/A check inside the loop, and switch from strconv.ParseFloat("NaN", 64) to math.NaN() for clarity. Signed-off-by: Kanji Nakano --- translib/pfm_app.go | 252 ++++++-------------------------------------- 1 file changed, 32 insertions(+), 220 deletions(-) diff --git a/translib/pfm_app.go b/translib/pfm_app.go index 1752bf1ba..e78473aba 100644 --- a/translib/pfm_app.go +++ b/translib/pfm_app.go @@ -754,14 +754,7 @@ func (app *PlatformApp) getCompTransceiverPhysicalChannelStateLaserTemperatureFr } type CompTransceiverPhysicalChannelStateOutputPowerDb struct { - tx1power float64 - tx2power float64 - tx3power float64 - tx4power float64 - tx5power float64 - tx6power float64 - tx7power float64 - tx8power float64 + TxPower [8]float64 } func (app *PlatformApp) getCompTransceiverPhysicalChannelStateOutputPowerDbObj(ifName string) CompTransceiverPhysicalChannelStateOutputPowerDb { @@ -771,14 +764,9 @@ func (app *PlatformApp) getCompTransceiverPhysicalChannelStateOutputPowerDbObj(i transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry - compTransceiverPhysicalChannelStateOutputPowerDbObj.tx1power, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("tx1power"), 64) - compTransceiverPhysicalChannelStateOutputPowerDbObj.tx2power, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("tx2power"), 64) - compTransceiverPhysicalChannelStateOutputPowerDbObj.tx3power, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("tx3power"), 64) - compTransceiverPhysicalChannelStateOutputPowerDbObj.tx4power, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("tx4power"), 64) - compTransceiverPhysicalChannelStateOutputPowerDbObj.tx5power, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("tx5power"), 64) - compTransceiverPhysicalChannelStateOutputPowerDbObj.tx6power, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("tx6power"), 64) - compTransceiverPhysicalChannelStateOutputPowerDbObj.tx7power, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("tx7power"), 64) - compTransceiverPhysicalChannelStateOutputPowerDbObj.tx8power, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("tx8power"), 64) + for i := 0; i < 8; i++ { + compTransceiverPhysicalChannelStateOutputPowerDbObj.TxPower[i], _ = strconv.ParseFloat(transceiverDomSensorTable.Get(fmt.Sprintf("tx%dpower", i+1)), 64) + } return compTransceiverPhysicalChannelStateOutputPowerDbObj } @@ -792,54 +780,12 @@ func (app *PlatformApp) getCompTransceiverPhysicalChannelStateOutputPowerFromDb( targetUriPath, _ := getYangPathFromUri(app.path.Path) if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/physical-channels/channel/state/output-power/instant" { - switch laneIndex { - case 0: - transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry - if transceiverDomSensorTable.Has("tx1power") { - tx1power := math.Floor(compTransceiverPhysicalChannelStateOutputPowerDb.tx1power*fractionDigits2) / fractionDigits2 - oc_val.Instant = &tx1power - } - case 1: - transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry - if transceiverDomSensorTable.Has("tx2power") { - tx2power := math.Floor(compTransceiverPhysicalChannelStateOutputPowerDb.tx2power*fractionDigits2) / fractionDigits2 - oc_val.Instant = &tx2power - } - case 2: - transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry - if transceiverDomSensorTable.Has("tx3power") { - tx3power := math.Floor(compTransceiverPhysicalChannelStateOutputPowerDb.tx3power*fractionDigits2) / fractionDigits2 - oc_val.Instant = &tx3power - } - case 3: - transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry - if transceiverDomSensorTable.Has("tx4power") { - tx4power := math.Floor(compTransceiverPhysicalChannelStateOutputPowerDb.tx4power*fractionDigits2) / fractionDigits2 - oc_val.Instant = &tx4power - } - case 4: - transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry - if transceiverDomSensorTable.Has("tx5power") { - tx5power := math.Floor(compTransceiverPhysicalChannelStateOutputPowerDb.tx5power*fractionDigits2) / fractionDigits2 - oc_val.Instant = &tx5power - } - case 5: - transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry - if transceiverDomSensorTable.Has("tx6power") { - tx6power := math.Floor(compTransceiverPhysicalChannelStateOutputPowerDb.tx6power*fractionDigits2) / fractionDigits2 - oc_val.Instant = &tx6power - } - case 6: - transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry - if transceiverDomSensorTable.Has("tx7power") { - tx7power := math.Floor(compTransceiverPhysicalChannelStateOutputPowerDb.tx7power*fractionDigits2) / fractionDigits2 - oc_val.Instant = &tx7power - } - case 7: + if int(laneIndex) < 8 { + fieldName := fmt.Sprintf("tx%dpower", laneIndex+1) transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry - if transceiverDomSensorTable.Has("tx8power") { - tx8power := math.Floor(compTransceiverPhysicalChannelStateOutputPowerDb.tx8power*fractionDigits2) / fractionDigits2 - oc_val.Instant = &tx8power + if transceiverDomSensorTable.Has(fieldName) { + txpower := math.Floor(compTransceiverPhysicalChannelStateOutputPowerDb.TxPower[laneIndex]*fractionDigits2) / fractionDigits2 + oc_val.Instant = &txpower } } } @@ -848,14 +794,7 @@ func (app *PlatformApp) getCompTransceiverPhysicalChannelStateOutputPowerFromDb( } type CompTransceiverPhysicalChannelStateInputPowerDb struct { - rx1power float64 - rx2power float64 - rx3power float64 - rx4power float64 - rx5power float64 - rx6power float64 - rx7power float64 - rx8power float64 + RxPower [8]float64 } func (app *PlatformApp) getCompTransceiverPhysicalChannelStateInputPowerDbObj(ifName string) CompTransceiverPhysicalChannelStateInputPowerDb { @@ -865,14 +804,9 @@ func (app *PlatformApp) getCompTransceiverPhysicalChannelStateInputPowerDbObj(if transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry - compTransceiverPhysicalChannelStateInputPowerDbObj.rx1power, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("rx1power"), 64) - compTransceiverPhysicalChannelStateInputPowerDbObj.rx2power, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("rx2power"), 64) - compTransceiverPhysicalChannelStateInputPowerDbObj.rx3power, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("rx3power"), 64) - compTransceiverPhysicalChannelStateInputPowerDbObj.rx4power, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("rx4power"), 64) - compTransceiverPhysicalChannelStateInputPowerDbObj.rx5power, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("rx5power"), 64) - compTransceiverPhysicalChannelStateInputPowerDbObj.rx6power, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("rx6power"), 64) - compTransceiverPhysicalChannelStateInputPowerDbObj.rx7power, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("rx7power"), 64) - compTransceiverPhysicalChannelStateInputPowerDbObj.rx8power, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("rx8power"), 64) + for i := 0; i < 8; i++ { + compTransceiverPhysicalChannelStateInputPowerDbObj.RxPower[i], _ = strconv.ParseFloat(transceiverDomSensorTable.Get(fmt.Sprintf("rx%dpower", i+1)), 64) + } return compTransceiverPhysicalChannelStateInputPowerDbObj } @@ -886,54 +820,12 @@ func (app *PlatformApp) getCompTransceiverPhysicalChannelStateInputPowerFromDb(o targetUriPath, _ := getYangPathFromUri(app.path.Path) if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/physical-channels/channel/state/input-power/instant" { - switch laneIndex { - case 0: + if int(laneIndex) < 8 { + fieldName := fmt.Sprintf("rx%dpower", laneIndex+1) transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry - if transceiverDomSensorTable.Has("rx1power") { - rx1power := math.Floor(compTransceiverPhysicalChannelStateInputPowerDb.rx1power*fractionDigits2) / fractionDigits2 - oc_val.Instant = &rx1power - } - case 1: - transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry - if transceiverDomSensorTable.Has("rx2power") { - rx2power := math.Floor(compTransceiverPhysicalChannelStateInputPowerDb.rx2power*fractionDigits2) / fractionDigits2 - oc_val.Instant = &rx2power - } - case 2: - transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry - if transceiverDomSensorTable.Has("rx3power") { - rx3power := math.Floor(compTransceiverPhysicalChannelStateInputPowerDb.rx3power*fractionDigits2) / fractionDigits2 - oc_val.Instant = &rx3power - } - case 3: - transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry - if transceiverDomSensorTable.Has("rx4power") { - rx4power := math.Floor(compTransceiverPhysicalChannelStateInputPowerDb.rx4power*fractionDigits2) / fractionDigits2 - oc_val.Instant = &rx4power - } - case 4: - transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry - if transceiverDomSensorTable.Has("rx5power") { - rx5power := math.Floor(compTransceiverPhysicalChannelStateInputPowerDb.rx5power*fractionDigits2) / fractionDigits2 - oc_val.Instant = &rx5power - } - case 5: - transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry - if transceiverDomSensorTable.Has("rx6power") { - rx6power := math.Floor(compTransceiverPhysicalChannelStateInputPowerDb.rx6power*fractionDigits2) / fractionDigits2 - oc_val.Instant = &rx6power - } - case 6: - transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry - if transceiverDomSensorTable.Has("rx7power") { - rx7power := math.Floor(compTransceiverPhysicalChannelStateInputPowerDb.rx7power*fractionDigits2) / fractionDigits2 - oc_val.Instant = &rx7power - } - case 7: - transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry - if transceiverDomSensorTable.Has("rx8power") { - rx8power := math.Floor(compTransceiverPhysicalChannelStateInputPowerDb.rx8power*fractionDigits2) / fractionDigits2 - oc_val.Instant = &rx8power + if transceiverDomSensorTable.Has(fieldName) { + rxpower := math.Floor(compTransceiverPhysicalChannelStateInputPowerDb.RxPower[laneIndex]*fractionDigits2) / fractionDigits2 + oc_val.Instant = &rxpower } } } @@ -942,14 +834,7 @@ func (app *PlatformApp) getCompTransceiverPhysicalChannelStateInputPowerFromDb(o } type CompTransceiverPhysicalChannelStateLaserBiasCurrentDb struct { - tx1bias float64 - tx2bias float64 - tx3bias float64 - tx4bias float64 - tx5bias float64 - tx6bias float64 - tx7bias float64 - tx8bias float64 + TxBias [8]float64 } func (app *PlatformApp) getCompTransceiverPhysicalChannelStateLaserBiasCurrentDbObj(ifName string) CompTransceiverPhysicalChannelStateLaserBiasCurrentDb { @@ -959,45 +844,14 @@ func (app *PlatformApp) getCompTransceiverPhysicalChannelStateLaserBiasCurrentDb transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry - if transceiverDomSensorTable.Get("tx1bias") != "N/A" { - compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj.tx1bias, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("tx1bias"), 64) - } else { - compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj.tx1bias, _ = strconv.ParseFloat("NaN", 64) - } - if transceiverDomSensorTable.Get("tx2bias") != "N/A" { - compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj.tx2bias, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("tx2bias"), 64) - } else { - compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj.tx2bias, _ = strconv.ParseFloat("NaN", 64) - } - if transceiverDomSensorTable.Get("tx3bias") != "N/A" { - compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj.tx3bias, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("tx3bias"), 64) - } else { - compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj.tx3bias, _ = strconv.ParseFloat("NaN", 64) - } - if transceiverDomSensorTable.Get("tx4bias") != "N/A" { - compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj.tx4bias, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("tx4bias"), 64) - } else { - compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj.tx4bias, _ = strconv.ParseFloat("NaN", 64) - } - if transceiverDomSensorTable.Get("tx5bias") != "N/A" { - compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj.tx5bias, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("tx5bias"), 64) - } else { - compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj.tx5bias, _ = strconv.ParseFloat("NaN", 64) - } - if transceiverDomSensorTable.Get("tx6bias") != "N/A" { - compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj.tx6bias, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("tx6bias"), 64) - } else { - compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj.tx6bias, _ = strconv.ParseFloat("NaN", 64) - } - if transceiverDomSensorTable.Get("tx7bias") != "N/A" { - compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj.tx7bias, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("tx7bias"), 64) - } else { - compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj.tx7bias, _ = strconv.ParseFloat("NaN", 64) - } - if transceiverDomSensorTable.Get("tx8bias") != "N/A" { - compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj.tx8bias, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("tx8bias"), 64) - } else { - compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj.tx8bias, _ = strconv.ParseFloat("NaN", 64) + for i := 0; i < 8; i++ { + field := fmt.Sprintf("tx%dbias", i+1) + raw := transceiverDomSensorTable.Get(field) + if raw != "N/A" { + compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj.TxBias[i], _ = strconv.ParseFloat(raw, 64) + } else { + compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj.TxBias[i] = math.NaN() + } } return compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj @@ -1012,54 +866,12 @@ func (app *PlatformApp) getCompTransceiverPhysicalChannelStateLaserBiasCurrentFr targetUriPath, _ := getYangPathFromUri(app.path.Path) if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/physical-channels/channel/state/laser-bias-current/instant" { - switch laneIndex { - case 0: - transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry - if transceiverDomSensorTable.Has("tx1bias") { - tx1bias := math.Floor(compTransceiverPhysicalChannelStateLaserBiasCurrentDb.tx1bias*fractionDigits2) / fractionDigits2 - oc_val.Instant = &tx1bias - } - case 1: - transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry - if transceiverDomSensorTable.Has("tx2bias") { - tx2bias := math.Floor(compTransceiverPhysicalChannelStateLaserBiasCurrentDb.tx2bias*fractionDigits2) / fractionDigits2 - oc_val.Instant = &tx2bias - } - case 2: - transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry - if transceiverDomSensorTable.Has("tx3bias") { - tx3bias := math.Floor(compTransceiverPhysicalChannelStateLaserBiasCurrentDb.tx3bias*fractionDigits2) / fractionDigits2 - oc_val.Instant = &tx3bias - } - case 3: - transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry - if transceiverDomSensorTable.Has("tx4bias") { - tx4bias := math.Floor(compTransceiverPhysicalChannelStateLaserBiasCurrentDb.tx4bias*fractionDigits2) / fractionDigits2 - oc_val.Instant = &tx4bias - } - case 4: - transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry - if transceiverDomSensorTable.Has("tx5bias") { - tx5bias := math.Floor(compTransceiverPhysicalChannelStateLaserBiasCurrentDb.tx5bias*fractionDigits2) / fractionDigits2 - oc_val.Instant = &tx5bias - } - case 5: - transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry - if transceiverDomSensorTable.Has("tx6bias") { - tx6bias := math.Floor(compTransceiverPhysicalChannelStateLaserBiasCurrentDb.tx6bias*fractionDigits2) / fractionDigits2 - oc_val.Instant = &tx6bias - } - case 6: - transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry - if transceiverDomSensorTable.Has("tx7bias") { - tx7bias := math.Floor(compTransceiverPhysicalChannelStateLaserBiasCurrentDb.tx7bias*fractionDigits2) / fractionDigits2 - oc_val.Instant = &tx7bias - } - case 7: + if int(laneIndex) < 8 { + fieldName := fmt.Sprintf("tx%dbias", laneIndex+1) transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry - if transceiverDomSensorTable.Has("tx8bias") { - tx8bias := math.Floor(compTransceiverPhysicalChannelStateLaserBiasCurrentDb.tx8bias*fractionDigits2) / fractionDigits2 - oc_val.Instant = &tx8bias + if transceiverDomSensorTable.Has(fieldName) { + txbias := math.Floor(compTransceiverPhysicalChannelStateLaserBiasCurrentDb.TxBias[laneIndex]*fractionDigits2) / fractionDigits2 + oc_val.Instant = &txbias } } } From ca19c7be583ec8357cf7141117b159d886826521 Mon Sep 17 00:00:00 2001 From: Kanji Nakano Date: Mon, 25 May 2026 18:17:08 +0900 Subject: [PATCH 05/12] translib/pfm_app: rename threshold struct fields to PascalCase Address review comment on PR #201: CompTransceiverThresholdStateDb held 20 float64 fields with lowercase names (temphighalarm, templowalarm, vcchighalarm, ..., txbiaslowwarning), which violate Go naming conventions for struct fields. Rename them to PascalCase (TempHighAlarm, TempLowAlarm, VccHighAlarm, ...) and update both the parser assignments and the getter struct-field accesses. The DB field name strings ("temphighalarm" etc.) are left unchanged since they are the on-wire Redis keys defined by xcvrd, not Go identifiers. Local variables inside the FromDb getter (used purely as a stable address for a pointer take) also stay lowercase since short-scoped locals do not need to follow exported-field conventions. Signed-off-by: Kanji Nakano --- translib/pfm_app.go | 120 ++++++++++++++++++++++---------------------- 1 file changed, 60 insertions(+), 60 deletions(-) diff --git a/translib/pfm_app.go b/translib/pfm_app.go index e78473aba..32a7b03de 100644 --- a/translib/pfm_app.go +++ b/translib/pfm_app.go @@ -880,26 +880,26 @@ func (app *PlatformApp) getCompTransceiverPhysicalChannelStateLaserBiasCurrentFr } type CompTransceiverThresholdStateDb struct { - temphighalarm float64 - templowalarm float64 - vcchighalarm float64 - vcclowalarm float64 - temphighwarning float64 - templowwarning float64 - vcchighwarning float64 - vcclowwarning float64 - txpowerhighalarm float64 - txpowerlowalarm float64 - rxpowerhighalarm float64 - rxpowerlowalarm float64 - txbiashighalarm float64 - txbiaslowalarm float64 - txpowerhighwarning float64 - txpowerlowwarning float64 - rxpowerhighwarning float64 - rxpowerlowwarning float64 - txbiashighwarning float64 - txbiaslowwarning float64 + TempHighAlarm float64 + TempLowAlarm float64 + VccHighAlarm float64 + VccLowAlarm float64 + TempHighWarning float64 + TempLowWarning float64 + VccHighWarning float64 + VccLowWarning float64 + TxPowerHighAlarm float64 + TxPowerLowAlarm float64 + RxPowerHighAlarm float64 + RxPowerLowAlarm float64 + TxBiasHighAlarm float64 + TxBiasLowAlarm float64 + TxPowerHighWarning float64 + TxPowerLowWarning float64 + RxPowerHighWarning float64 + RxPowerLowWarning float64 + TxBiasHighWarning float64 + TxBiasLowWarning float64 } func (app *PlatformApp) getCompTransceiverThresholdStateDbObj(ifName string) CompTransceiverThresholdStateDb { @@ -909,26 +909,26 @@ func (app *PlatformApp) getCompTransceiverThresholdStateDbObj(ifName string) Com transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry - compTransceiverThresholdStateDbObj.temphighalarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("temphighalarm"), 64) - compTransceiverThresholdStateDbObj.templowalarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("templowalarm"), 64) - compTransceiverThresholdStateDbObj.vcchighalarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("vcchighalarm"), 64) - compTransceiverThresholdStateDbObj.vcclowalarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("vcclowalarm"), 64) - compTransceiverThresholdStateDbObj.temphighwarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("temphighwarning"), 64) - compTransceiverThresholdStateDbObj.templowwarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("templowwarning"), 64) - compTransceiverThresholdStateDbObj.vcchighwarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("vcchighwarning"), 64) - compTransceiverThresholdStateDbObj.vcclowwarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("vcclowwarning"), 64) - compTransceiverThresholdStateDbObj.txpowerhighalarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("txpowerhighalarm"), 64) - compTransceiverThresholdStateDbObj.txpowerlowalarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("txpowerlowalarm"), 64) - compTransceiverThresholdStateDbObj.rxpowerhighalarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("rxpowerhighalarm"), 64) - compTransceiverThresholdStateDbObj.rxpowerlowalarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("rxpowerlowalarm"), 64) - compTransceiverThresholdStateDbObj.txbiashighalarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("txbiashighalarm"), 64) - compTransceiverThresholdStateDbObj.txbiaslowalarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("txbiaslowalarm"), 64) - compTransceiverThresholdStateDbObj.txpowerhighwarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("txpowerhighwarning"), 64) - compTransceiverThresholdStateDbObj.txpowerlowwarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("txpowerlowwarning"), 64) - compTransceiverThresholdStateDbObj.rxpowerhighwarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("rxpowerhighwarning"), 64) - compTransceiverThresholdStateDbObj.rxpowerlowwarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("rxpowerlowwarning"), 64) - compTransceiverThresholdStateDbObj.txbiashighwarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("txbiashighwarning"), 64) - compTransceiverThresholdStateDbObj.txbiaslowwarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("txbiaslowwarning"), 64) + compTransceiverThresholdStateDbObj.TempHighAlarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("temphighalarm"), 64) + compTransceiverThresholdStateDbObj.TempLowAlarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("templowalarm"), 64) + compTransceiverThresholdStateDbObj.VccHighAlarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("vcchighalarm"), 64) + compTransceiverThresholdStateDbObj.VccLowAlarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("vcclowalarm"), 64) + compTransceiverThresholdStateDbObj.TempHighWarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("temphighwarning"), 64) + compTransceiverThresholdStateDbObj.TempLowWarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("templowwarning"), 64) + compTransceiverThresholdStateDbObj.VccHighWarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("vcchighwarning"), 64) + compTransceiverThresholdStateDbObj.VccLowWarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("vcclowwarning"), 64) + compTransceiverThresholdStateDbObj.TxPowerHighAlarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("txpowerhighalarm"), 64) + compTransceiverThresholdStateDbObj.TxPowerLowAlarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("txpowerlowalarm"), 64) + compTransceiverThresholdStateDbObj.RxPowerHighAlarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("rxpowerhighalarm"), 64) + compTransceiverThresholdStateDbObj.RxPowerLowAlarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("rxpowerlowalarm"), 64) + compTransceiverThresholdStateDbObj.TxBiasHighAlarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("txbiashighalarm"), 64) + compTransceiverThresholdStateDbObj.TxBiasLowAlarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("txbiaslowalarm"), 64) + compTransceiverThresholdStateDbObj.TxPowerHighWarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("txpowerhighwarning"), 64) + compTransceiverThresholdStateDbObj.TxPowerLowWarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("txpowerlowwarning"), 64) + compTransceiverThresholdStateDbObj.RxPowerHighWarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("rxpowerhighwarning"), 64) + compTransceiverThresholdStateDbObj.RxPowerLowWarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("rxpowerlowwarning"), 64) + compTransceiverThresholdStateDbObj.TxBiasHighWarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("txbiashighwarning"), 64) + compTransceiverThresholdStateDbObj.TxBiasLowWarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("txbiaslowwarning"), 64) return compTransceiverThresholdStateDbObj } @@ -945,70 +945,70 @@ func (app *PlatformApp) getCompTransceiverThresholdStateFromDb(oc_val *ocbinds.O if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/laser-temperature-upper" { transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry if transceiverDomThresholdTable.Has("temphighalarm") { - temphighalarm := math.Floor(compTransceiverThresholdStateDb.temphighalarm*fractionDigits1) / fractionDigits1 + temphighalarm := math.Floor(compTransceiverThresholdStateDb.TempHighAlarm*fractionDigits1) / fractionDigits1 oc_val.LaserTemperatureUpper = &temphighalarm } } if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/laser-temperature-lower" { transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry if transceiverDomThresholdTable.Has("templowalarm") { - templowalarm := math.Floor(compTransceiverThresholdStateDb.templowalarm*fractionDigits1) / fractionDigits1 + templowalarm := math.Floor(compTransceiverThresholdStateDb.TempLowAlarm*fractionDigits1) / fractionDigits1 oc_val.LaserTemperatureLower = &templowalarm } } if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/supply-voltage-upper" { transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry if transceiverDomThresholdTable.Has("vcchighalarm") { - vcchighalarm := math.Floor(compTransceiverThresholdStateDb.vcchighalarm*fractionDigits2) / fractionDigits2 + vcchighalarm := math.Floor(compTransceiverThresholdStateDb.VccHighAlarm*fractionDigits2) / fractionDigits2 oc_val.SupplyVoltageUpper = &vcchighalarm } } if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/supply-voltage-lower" { transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry if transceiverDomThresholdTable.Has("vcclowalarm") { - vcclowalarm := math.Floor(compTransceiverThresholdStateDb.vcclowalarm*fractionDigits2) / fractionDigits2 + vcclowalarm := math.Floor(compTransceiverThresholdStateDb.VccLowAlarm*fractionDigits2) / fractionDigits2 oc_val.SupplyVoltageLower = &vcclowalarm } } if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/output-power-upper" { transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry if transceiverDomThresholdTable.Has("txpowerhighalarm") { - txpowerhighalarm := math.Floor(compTransceiverThresholdStateDb.txpowerhighalarm*fractionDigits2) / fractionDigits2 + txpowerhighalarm := math.Floor(compTransceiverThresholdStateDb.TxPowerHighAlarm*fractionDigits2) / fractionDigits2 oc_val.OutputPowerUpper = &txpowerhighalarm } } if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/output-power-lower" { transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry if transceiverDomThresholdTable.Has("txpowerlowalarm") { - txpowerlowalarm := math.Floor(compTransceiverThresholdStateDb.txpowerlowalarm*fractionDigits2) / fractionDigits2 + txpowerlowalarm := math.Floor(compTransceiverThresholdStateDb.TxPowerLowAlarm*fractionDigits2) / fractionDigits2 oc_val.OutputPowerLower = &txpowerlowalarm } } if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/input-power-upper" { transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry if transceiverDomThresholdTable.Has("rxpowerhighalarm") { - rxpowerhighalarm := math.Floor(compTransceiverThresholdStateDb.rxpowerhighalarm*fractionDigits2) / fractionDigits2 + rxpowerhighalarm := math.Floor(compTransceiverThresholdStateDb.RxPowerHighAlarm*fractionDigits2) / fractionDigits2 oc_val.InputPowerUpper = &rxpowerhighalarm } } if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/input-power-lower" { transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry if transceiverDomThresholdTable.Has("rxpowerlowalarm") { - rxpowerlowalarm := math.Floor(compTransceiverThresholdStateDb.rxpowerlowalarm*fractionDigits2) / fractionDigits2 + rxpowerlowalarm := math.Floor(compTransceiverThresholdStateDb.RxPowerLowAlarm*fractionDigits2) / fractionDigits2 oc_val.InputPowerLower = &rxpowerlowalarm } } if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/laser-bias-current-upper" { transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry if transceiverDomThresholdTable.Has("txbiashighalarm") { - txbiashighalarm := math.Floor(compTransceiverThresholdStateDb.txbiashighalarm*fractionDigits2) / fractionDigits2 + txbiashighalarm := math.Floor(compTransceiverThresholdStateDb.TxBiasHighAlarm*fractionDigits2) / fractionDigits2 oc_val.LaserBiasCurrentUpper = &txbiashighalarm } } if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/laser-bias-current-lower" { transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry if transceiverDomThresholdTable.Has("txbiaslowalarm") { - txbiaslowalarm := math.Floor(compTransceiverThresholdStateDb.txbiaslowalarm*fractionDigits2) / fractionDigits2 + txbiaslowalarm := math.Floor(compTransceiverThresholdStateDb.TxBiasLowAlarm*fractionDigits2) / fractionDigits2 oc_val.LaserBiasCurrentLower = &txbiaslowalarm } } @@ -1018,70 +1018,70 @@ func (app *PlatformApp) getCompTransceiverThresholdStateFromDb(oc_val *ocbinds.O if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/laser-temperature-upper" { transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry if transceiverDomThresholdTable.Has("temphighwarning") { - temphighwarning := math.Floor(compTransceiverThresholdStateDb.temphighwarning*fractionDigits1) / fractionDigits1 + temphighwarning := math.Floor(compTransceiverThresholdStateDb.TempHighWarning*fractionDigits1) / fractionDigits1 oc_val.LaserTemperatureUpper = &temphighwarning } } if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/laser-temperature-lower" { transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry if transceiverDomThresholdTable.Has("templowwarning") { - templowwarning := math.Floor(compTransceiverThresholdStateDb.templowwarning*fractionDigits1) / fractionDigits1 + templowwarning := math.Floor(compTransceiverThresholdStateDb.TempLowWarning*fractionDigits1) / fractionDigits1 oc_val.LaserTemperatureLower = &templowwarning } } if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/supply-voltage-upper" { transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry if transceiverDomThresholdTable.Has("vcchighwarning") { - vcchighwarning := math.Floor(compTransceiverThresholdStateDb.vcchighwarning*fractionDigits2) / fractionDigits2 + vcchighwarning := math.Floor(compTransceiverThresholdStateDb.VccHighWarning*fractionDigits2) / fractionDigits2 oc_val.SupplyVoltageUpper = &vcchighwarning } } if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/supply-voltage-lower" { transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry if transceiverDomThresholdTable.Has("vcclowwarning") { - vcclowwarning := math.Floor(compTransceiverThresholdStateDb.vcclowwarning*fractionDigits2) / fractionDigits2 + vcclowwarning := math.Floor(compTransceiverThresholdStateDb.VccLowWarning*fractionDigits2) / fractionDigits2 oc_val.SupplyVoltageLower = &vcclowwarning } } if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/output-power-upper" { transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry if transceiverDomThresholdTable.Has("txpowerhighwarning") { - v := math.Floor(compTransceiverThresholdStateDb.txpowerhighwarning*fractionDigits2) / fractionDigits2 + v := math.Floor(compTransceiverThresholdStateDb.TxPowerHighWarning*fractionDigits2) / fractionDigits2 oc_val.OutputPowerUpper = &v } } if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/output-power-lower" { transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry if transceiverDomThresholdTable.Has("txpowerlowwarning") { - v := math.Floor(compTransceiverThresholdStateDb.txpowerlowwarning*fractionDigits2) / fractionDigits2 + v := math.Floor(compTransceiverThresholdStateDb.TxPowerLowWarning*fractionDigits2) / fractionDigits2 oc_val.OutputPowerLower = &v } } if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/input-power-upper" { transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry if transceiverDomThresholdTable.Has("rxpowerhighwarning") { - v := math.Floor(compTransceiverThresholdStateDb.rxpowerhighwarning*fractionDigits2) / fractionDigits2 + v := math.Floor(compTransceiverThresholdStateDb.RxPowerHighWarning*fractionDigits2) / fractionDigits2 oc_val.InputPowerUpper = &v } } if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/input-power-lower" { transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry if transceiverDomThresholdTable.Has("rxpowerlowwarning") { - v := math.Floor(compTransceiverThresholdStateDb.rxpowerlowwarning*fractionDigits2) / fractionDigits2 + v := math.Floor(compTransceiverThresholdStateDb.RxPowerLowWarning*fractionDigits2) / fractionDigits2 oc_val.InputPowerLower = &v } } if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/laser-bias-current-upper" { transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry if transceiverDomThresholdTable.Has("txbiashighwarning") { - v := math.Floor(compTransceiverThresholdStateDb.txbiashighwarning*fractionDigits2) / fractionDigits2 + v := math.Floor(compTransceiverThresholdStateDb.TxBiasHighWarning*fractionDigits2) / fractionDigits2 oc_val.LaserBiasCurrentUpper = &v } } if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/laser-bias-current-lower" { transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry if transceiverDomThresholdTable.Has("txbiaslowwarning") { - v := math.Floor(compTransceiverThresholdStateDb.txbiaslowwarning*fractionDigits2) / fractionDigits2 + v := math.Floor(compTransceiverThresholdStateDb.TxBiasLowWarning*fractionDigits2) / fractionDigits2 oc_val.LaserBiasCurrentLower = &v } } From 106436db97a10a6b9e3ccd7d92a0b76479b2c331 Mon Sep 17 00:00:00 2001 From: Kanji Nakano Date: Mon, 25 May 2026 18:21:50 +0900 Subject: [PATCH 06/12] translib/pfm_app_test: add transceiver unit-test scaffolding Address review comment on PR #201 (maintainer-endorsed): the new OpenConfig Platform Transceiver feature in translib/pfm_app.go had no test coverage. Extend pfm_app_test.go with: - createTransceiverFactoryDb / clearTransceiverDataFromDb helpers that load and tear down STATE_DB fixtures for TRANSCEIVER_INFO, TRANSCEIVER_DOM_SENSOR and TRANSCEIVER_DOM_THRESHOLD using the same db.SetEntry pattern as the existing EEPROM_INFO fixture. - Test_PfmApp_TransceiverState which exercises the transceiver state subtree (serial-no, vendor, vendor-part, vendor-rev, date-code, connector-type, supply-voltage) and the CRITICAL / WARNING thresholds against a populated Ethernet0 transceiver fixture. Assertions are scoped to "GET returns without error", which is the regression guard for the handler reaching completion against valid input. - Test_PfmApp_TransceiverState_Missing which queries the same paths against a non-existent component (transceiver_EthernetMissing) and verifies the handler does not panic. This is a regression guard for the map-lookup nil-pointer concerns raised by Copilot's auto-review on PR #201 (the actual map-safety helpers will follow in a separate patch). Fixtures are loaded inside each test and torn down via t.Cleanup so the existing Test_PfmApp_TopLevelPath bulk EEPROM test is not affected by run ordering. Strict JSON-equality assertions on the transceiver subtree are intentionally deferred until the encoding/precision of float and enum fields can be observed against a real run. Signed-off-by: Kanji Nakano --- translib/pfm_app_test.go | 218 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 218 insertions(+) diff --git a/translib/pfm_app_test.go b/translib/pfm_app_test.go index 0ad27bb36..d1184c2ef 100644 --- a/translib/pfm_app_test.go +++ b/translib/pfm_app_test.go @@ -36,6 +36,22 @@ const ( TEST_MANUF_NAME = "TestManufacture" ) +// Test transceiver fixture values for TRANSCEIVER_INFO|Ethernet0, +// TRANSCEIVER_DOM_SENSOR|Ethernet0 and TRANSCEIVER_DOM_THRESHOLD|Ethernet0 +// in STATE_DB. The interface name is the same one used by the existing +// PORT_TABLE entries to make scoped GETs land on a real component path. +const ( + TEST_XCVR_IFNAME = "Ethernet0" + TEST_XCVR_COMPONENT = "transceiver_Ethernet0" + TEST_XCVR_SERIAL = "TESTSERIAL0001" + TEST_XCVR_MODEL = "TESTMODEL-100G-LR" + TEST_XCVR_CONNECTOR = "LC" + TEST_XCVR_MANUFACTURER = "TestVendor" + TEST_XCVR_VENDOR_OUI = "00-11-22" + TEST_XCVR_VENDOR_REV = "A1" + TEST_XCVR_VENDOR_DATE = "2024-01-01 00:00:00" +) + type EepromEntry struct { TlvType string Name string @@ -58,6 +74,10 @@ func init() { } else { fmt.Printf("Failed to remove All Platform Data from Db: %v", err) } + + if err := clearTransceiverDataFromDb(); err != nil { + fmt.Printf("Failed to remove Transceiver Data from Db: %v\n", err) + } } // This will test GET on /openconfig-platform:components @@ -74,6 +94,100 @@ func Test_PfmApp_TopLevelPath(t *testing.T) { t.Run("Get_Full_Pfm_Tree_Top_Level", processGetRequest(url, bulkPfmShowAllJsonResponse, false)) } +// Test_PfmApp_TransceiverState exercises the OpenConfig transceiver state +// subtree against STATE_DB fixtures for TRANSCEIVER_INFO, TRANSCEIVER_DOM_SENSOR +// and TRANSCEIVER_DOM_THRESHOLD. The assertions are intentionally lenient: we +// verify that each GET returns without error or panic, which is the regression +// guard for the nil-pointer concerns raised on PR #201 (map lookups against +// transceiverInfoTable / transceiverDomSensorTable / transceiverDomThresholdTable). +// +// Fixtures are loaded inside the test and torn down on cleanup so the +// existing Test_PfmApp_TopLevelPath bulk EEPROM test is unaffected by run +// ordering. +func Test_PfmApp_TransceiverState(t *testing.T) { + if err := createTransceiverFactoryDb(); err != nil { + t.Fatalf("Failed to add Transceiver data to Db: %v", err) + } + t.Cleanup(func() { + if err := clearTransceiverDataFromDb(); err != nil { + t.Logf("Cleanup: failed to remove Transceiver Data from Db: %v", err) + } + }) + + cases := []struct { + name string + url string + }{ + {"State_Subtree", "/openconfig-platform:components/component[name=" + TEST_XCVR_COMPONENT + "]/openconfig-platform-transceiver:transceiver/state"}, + {"State_SerialNo", "/openconfig-platform:components/component[name=" + TEST_XCVR_COMPONENT + "]/openconfig-platform-transceiver:transceiver/state/serial-no"}, + {"State_Vendor", "/openconfig-platform:components/component[name=" + TEST_XCVR_COMPONENT + "]/openconfig-platform-transceiver:transceiver/state/vendor"}, + {"State_VendorPart", "/openconfig-platform:components/component[name=" + TEST_XCVR_COMPONENT + "]/openconfig-platform-transceiver:transceiver/state/vendor-part"}, + {"State_VendorRev", "/openconfig-platform:components/component[name=" + TEST_XCVR_COMPONENT + "]/openconfig-platform-transceiver:transceiver/state/vendor-rev"}, + {"State_DateCode", "/openconfig-platform:components/component[name=" + TEST_XCVR_COMPONENT + "]/openconfig-platform-transceiver:transceiver/state/date-code"}, + {"State_ConnectorType", "/openconfig-platform:components/component[name=" + TEST_XCVR_COMPONENT + "]/openconfig-platform-transceiver:transceiver/state/connector-type"}, + {"State_SupplyVoltage", "/openconfig-platform:components/component[name=" + TEST_XCVR_COMPONENT + "]/openconfig-platform-transceiver:transceiver/state/supply-voltage"}, + {"Thresholds_Critical", "/openconfig-platform:components/component[name=" + TEST_XCVR_COMPONENT + "]/openconfig-platform-transceiver:transceiver/thresholds/threshold[severity=CRITICAL]/state"}, + {"Thresholds_Warning", "/openconfig-platform:components/component[name=" + TEST_XCVR_COMPONENT + "]/openconfig-platform-transceiver:transceiver/thresholds/threshold[severity=WARNING]/state"}, + } + + for _, tc := range cases { + t.Run(tc.name, verifyTransceiverGetNoError(tc.url)) + } +} + +// Test_PfmApp_TransceiverState_Missing covers the case where no transceiver +// fixture is present in STATE_DB. The current pre-#201 code may return an +// empty response or surface a "data missing" tlerr depending on the path; the +// important regression property is that the handler does NOT panic from a +// nil map lookup on transceiverInfoTable / transceiverDomSensorTable / +// transceiverDomThresholdTable. Both nil-error and non-nil-error outcomes are +// accepted here; only a panic constitutes failure (recovered via t.Failed). +func Test_PfmApp_TransceiverState_Missing(t *testing.T) { + // Ensure no transceiver entries exist. + if err := clearTransceiverDataFromDb(); err != nil { + t.Logf("setup: cleanup failed (continuing): %v", err) + } + + cases := []struct { + name string + url string + }{ + {"Missing_State_SerialNo", "/openconfig-platform:components/component[name=transceiver_EthernetMissing]/openconfig-platform-transceiver:transceiver/state/serial-no"}, + {"Missing_State_SupplyVoltage", "/openconfig-platform:components/component[name=transceiver_EthernetMissing]/openconfig-platform-transceiver:transceiver/state/supply-voltage"}, + {"Missing_Thresholds_Critical", "/openconfig-platform:components/component[name=transceiver_EthernetMissing]/openconfig-platform-transceiver:transceiver/thresholds/threshold[severity=CRITICAL]/state"}, + } + + for _, tc := range cases { + t.Run(tc.name, verifyTransceiverGetDoesNotPanic(tc.url)) + } +} + +// verifyTransceiverGetNoError returns a t.Run-compatible function that issues +// a GET and fails the test if it surfaces an error. Body content is not +// inspected; this is regression scaffolding around the handler reaching +// completion against valid fixtures. +func verifyTransceiverGetNoError(url string) func(*testing.T) { + return func(t *testing.T) { + if _, err := Get(GetRequest{Path: url}); err != nil { + t.Fatalf("GET %s returned error: %v", url, err) + } + } +} + +// verifyTransceiverGetDoesNotPanic asserts the handler returns (either a +// response or a recoverable error) instead of panicking. Both error and +// success are acceptable; only an unrecovered panic fails the test. +func verifyTransceiverGetDoesNotPanic(url string) func(*testing.T) { + return func(t *testing.T) { + defer func() { + if r := recover(); r != nil { + t.Fatalf("GET %s panicked: %v", url, r) + } + }() + _, _ = Get(GetRequest{Path: url}) + } +} + // THis will delete Platform Table from DB func clearPfmDataFromDb() error { var err error @@ -116,6 +230,110 @@ func createPfmFactoryDb() error { return err } +// clearTransceiverDataFromDb deletes the TRANSCEIVER_INFO, TRANSCEIVER_DOM_SENSOR +// and TRANSCEIVER_DOM_THRESHOLD tables from STATE_DB. Errors from individual +// DeleteTable calls are collected but a missing table is not treated as fatal: +// the helper is also used in init() where the tables may not exist yet. +func clearTransceiverDataFromDb() error { + d := getStateDB() + if d == nil { + return errors.New("Failed to connect to state Db") + } + for _, name := range []string{"TRANSCEIVER_INFO", "TRANSCEIVER_DOM_SENSOR", "TRANSCEIVER_DOM_THRESHOLD"} { + ts := db.TableSpec{Name: name} + _ = d.DeleteTable(&ts) + } + return nil +} + +// createTransceiverFactoryDb loads a single Ethernet0 transceiver entry into +// each of TRANSCEIVER_INFO, TRANSCEIVER_DOM_SENSOR and TRANSCEIVER_DOM_THRESHOLD +// in STATE_DB. Values are static and mirror the schema fields consumed by +// translib/pfm_app.go's getCompTransceiver*FromDb functions. +func createTransceiverFactoryDb() error { + d := getStateDB() + if d == nil { + return errors.New("Failed to connect to state Db") + } + + infoTable := db.TableSpec{Name: "TRANSCEIVER_INFO"} + infoKey := db.Key{Comp: []string{TEST_XCVR_IFNAME}} + infoValue := db.Value{Field: map[string]string{ + "serial": TEST_XCVR_SERIAL, + "model": TEST_XCVR_MODEL, + "connector": TEST_XCVR_CONNECTOR, + "manufacturer": TEST_XCVR_MANUFACTURER, + "vendor_oui": TEST_XCVR_VENDOR_OUI, + "vendor_rev": TEST_XCVR_VENDOR_REV, + "vendor_date": TEST_XCVR_VENDOR_DATE, + }} + if err := d.SetEntry(&infoTable, infoKey, infoValue); err != nil { + return fmt.Errorf("SetEntry TRANSCEIVER_INFO: %w", err) + } + + sensorTable := db.TableSpec{Name: "TRANSCEIVER_DOM_SENSOR"} + sensorValue := db.Value{Field: map[string]string{ + "voltage": "3.30", + "temperature": "42.5", + "tx1power": "1.05", + "tx2power": "1.05", + "tx3power": "1.05", + "tx4power": "1.05", + "tx5power": "1.05", + "tx6power": "1.05", + "tx7power": "1.05", + "tx8power": "1.05", + "rx1power": "-2.10", + "rx2power": "-2.10", + "rx3power": "-2.10", + "rx4power": "-2.10", + "rx5power": "-2.10", + "rx6power": "-2.10", + "rx7power": "-2.10", + "rx8power": "-2.10", + "tx1bias": "8.50", + "tx2bias": "8.50", + "tx3bias": "8.50", + "tx4bias": "8.50", + "tx5bias": "8.50", + "tx6bias": "8.50", + "tx7bias": "8.50", + "tx8bias": "8.50", + }} + if err := d.SetEntry(&sensorTable, infoKey, sensorValue); err != nil { + return fmt.Errorf("SetEntry TRANSCEIVER_DOM_SENSOR: %w", err) + } + + thresholdTable := db.TableSpec{Name: "TRANSCEIVER_DOM_THRESHOLD"} + thresholdValue := db.Value{Field: map[string]string{ + "temphighalarm": "85.0", + "templowalarm": "-10.0", + "vcchighalarm": "3.6", + "vcclowalarm": "3.0", + "temphighwarning": "75.0", + "templowwarning": "-5.0", + "vcchighwarning": "3.5", + "vcclowwarning": "3.1", + "txpowerhighalarm": "3.0", + "txpowerlowalarm": "-5.0", + "rxpowerhighalarm": "3.0", + "rxpowerlowalarm": "-15.0", + "txbiashighalarm": "12.0", + "txbiaslowalarm": "2.0", + "txpowerhighwarning": "2.5", + "txpowerlowwarning": "-4.0", + "rxpowerhighwarning": "2.5", + "rxpowerlowwarning": "-13.0", + "txbiashighwarning": "11.0", + "txbiaslowwarning": "3.0", + }} + if err := d.SetEntry(&thresholdTable, infoKey, thresholdValue); err != nil { + return fmt.Errorf("SetEntry TRANSCEIVER_DOM_THRESHOLD: %w", err) + } + + return nil +} + func getStateDB() *db.DB { stateDb, _ := db.NewDB(db.Options{ DBNo: db.StateDB, From 6bb24ffd37feb8952fbf2eaad867610fd09c5313 Mon Sep 17 00:00:00 2001 From: Kanji Nakano Date: Mon, 25 May 2026 18:29:11 +0900 Subject: [PATCH 07/12] translib/pfm_app: add map-lookup helpers and apply to parsers Address review comments on PR #201 that flagged the raw app.Table[ifName].entry pattern at every DbObj parser entry (serial-no, transceiver state, supply-voltage, laser-temperature, output-power, input-power, laser-bias-current, threshold) and at fourteen sites inside doGetPlatformInfo for applPortTable. The cached maps store dbEntry values (not pointers), so a missing key returns a zero-value dbEntry whose .entry.Field map is nil. .Has and .Get on a nil Field map return false / "" rather than panicking, so the existing code was not literally crashing -- but silently treating "no entry" as "entry with every field absent" made the missing-row case invisible at runtime and reads as fragile to a reviewer. Introduce four small helpers: getTransceiverInfoEntry(ifName) -> (db.Value, bool) getTransceiverDomSensorEntry(ifName) -> (db.Value, bool) getTransceiverDomThresholdEntry(ifName) -> (db.Value, bool) getApplPortEntry(ifName) -> (db.Value, bool) Each wraps the underlying map indexing and reports whether the interface was actually present. Update each get*DbObj parser to call the helper, log a Warningf on missing entry, and short-circuit with a sensible zero / NaN result. For applPortTable, all fourteen doGetPlatformInfo call sites now go through getApplPortEntry; the ok value is currently discarded because the existing follow-on logic (.Get("lanes"), strings.Split, ...) is already missing-tolerant and dedicated error handling for the empty/missing case is the subject of a separate patch in this series. The per-branch transceiver*Table lookups inside the get*FromDb getters were not flagged by review and are left as-is in this patch; they will go through the helper once the doGetPlatformInfo split hoists the lookup into a single call per request. Signed-off-by: Kanji Nakano --- translib/pfm_app.go | 117 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 93 insertions(+), 24 deletions(-) diff --git a/translib/pfm_app.go b/translib/pfm_app.go index 32a7b03de..65e48eab2 100644 --- a/translib/pfm_app.go +++ b/translib/pfm_app.go @@ -534,6 +534,38 @@ func (app *PlatformApp) getSysEepromFromDb(eeprom *ocbinds.OpenconfigPlatform_Co return nil } +// getTransceiverInfoEntry returns the cached TRANSCEIVER_INFO entry for ifName +// and a boolean indicating whether the interface was present in STATE_DB. +// The returned db.Value is still safe to call .Has / .Get on if ok is false +// (both return zero values for a nil Field map), but callers SHOULD inspect +// ok and short-circuit so a missing entry is not silently treated as a row +// with every field absent. +func (app *PlatformApp) getTransceiverInfoEntry(ifName string) (db.Value, bool) { + e, ok := app.transceiverInfoTable[ifName] + return e.entry, ok +} + +// getTransceiverDomSensorEntry returns the cached TRANSCEIVER_DOM_SENSOR entry +// for ifName. See getTransceiverInfoEntry for ok semantics. +func (app *PlatformApp) getTransceiverDomSensorEntry(ifName string) (db.Value, bool) { + e, ok := app.transceiverDomSensorTable[ifName] + return e.entry, ok +} + +// getTransceiverDomThresholdEntry returns the cached TRANSCEIVER_DOM_THRESHOLD +// entry for ifName. See getTransceiverInfoEntry for ok semantics. +func (app *PlatformApp) getTransceiverDomThresholdEntry(ifName string) (db.Value, bool) { + e, ok := app.transceiverDomThresholdTable[ifName] + return e.entry, ok +} + +// getApplPortEntry returns the cached APPL_DB PORT_TABLE entry for ifName. +// See getTransceiverInfoEntry for ok semantics. +func (app *PlatformApp) getApplPortEntry(ifName string) (db.Value, bool) { + e, ok := app.applPortTable[ifName] + return e.entry, ok +} + type CompStateDb struct { Serial string Model string @@ -544,7 +576,11 @@ func (app *PlatformApp) getCompStateDbObj(ifName string) CompStateDb { var compStateDbObj CompStateDb - transceiverInfoTable := app.transceiverInfoTable[ifName].entry + transceiverInfoTable, ok := app.getTransceiverInfoEntry(ifName) + if !ok { + log.Warningf("getCompStateDbObj: TRANSCEIVER_INFO entry missing for ifName=%s", ifName) + return compStateDbObj + } compStateDbObj.Serial = transceiverInfoTable.Get("serial") compStateDbObj.Model = transceiverInfoTable.Get("model") @@ -590,7 +626,11 @@ func (app *PlatformApp) getCompTransceiverStateDbObj(ifName string) CompTranscei var compTransceiverStateDbObj CompTransceiverStateDb - transceiverInfoTable := app.transceiverInfoTable[ifName].entry + transceiverInfoTable, ok := app.getTransceiverInfoEntry(ifName) + if !ok { + log.Warningf("getCompTransceiverStateDbObj: TRANSCEIVER_INFO entry missing for ifName=%s", ifName) + return compTransceiverStateDbObj + } compTransceiverStateDbObj.Connector = transceiverInfoTable.Get("connector") compTransceiverStateDbObj.Manufacturer = transceiverInfoTable.Get("manufacturer") @@ -684,12 +724,17 @@ func (app *PlatformApp) getCompTransceiverStateSupplyVoltageDbObj(ifName string) var compTransceiverStateSupplyVoltageDbObj CompTransceiverStateSupplyVoltageDb - transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry + transceiverDomSensorTable, ok := app.getTransceiverDomSensorEntry(ifName) + if !ok { + log.Warningf("getCompTransceiverStateSupplyVoltageDbObj: TRANSCEIVER_DOM_SENSOR entry missing for ifName=%s", ifName) + compTransceiverStateSupplyVoltageDbObj.voltage = math.NaN() + return compTransceiverStateSupplyVoltageDbObj + } if transceiverDomSensorTable.Get("voltage") != "N/A" { compTransceiverStateSupplyVoltageDbObj.voltage, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("voltage"), 64) } else { - compTransceiverStateSupplyVoltageDbObj.voltage, _ = strconv.ParseFloat("NaN", 64) + compTransceiverStateSupplyVoltageDbObj.voltage = math.NaN() } return compTransceiverStateSupplyVoltageDbObj @@ -723,12 +768,17 @@ func (app *PlatformApp) getCompTransceiverPhysicalChannelStateLaserTemperatureDb var compTransceiverPhysicalChannelStateLaserTemperatureDbObj CompTransceiverPhysicalChannelStateLaserTemperatureDb - transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry + transceiverDomSensorTable, ok := app.getTransceiverDomSensorEntry(ifName) + if !ok { + log.Warningf("getCompTransceiverPhysicalChannelStateLaserTemperatureDbObj: TRANSCEIVER_DOM_SENSOR entry missing for ifName=%s", ifName) + compTransceiverPhysicalChannelStateLaserTemperatureDbObj.temperature = math.NaN() + return compTransceiverPhysicalChannelStateLaserTemperatureDbObj + } if transceiverDomSensorTable.Get("temperature") != "N/A" { compTransceiverPhysicalChannelStateLaserTemperatureDbObj.temperature, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("temperature"), 64) } else { - compTransceiverPhysicalChannelStateLaserTemperatureDbObj.temperature, _ = strconv.ParseFloat("NaN", 64) + compTransceiverPhysicalChannelStateLaserTemperatureDbObj.temperature = math.NaN() } return compTransceiverPhysicalChannelStateLaserTemperatureDbObj @@ -762,7 +812,11 @@ func (app *PlatformApp) getCompTransceiverPhysicalChannelStateOutputPowerDbObj(i var compTransceiverPhysicalChannelStateOutputPowerDbObj CompTransceiverPhysicalChannelStateOutputPowerDb - transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry + transceiverDomSensorTable, ok := app.getTransceiverDomSensorEntry(ifName) + if !ok { + log.Warningf("getCompTransceiverPhysicalChannelStateOutputPowerDbObj: TRANSCEIVER_DOM_SENSOR entry missing for ifName=%s", ifName) + return compTransceiverPhysicalChannelStateOutputPowerDbObj + } for i := 0; i < 8; i++ { compTransceiverPhysicalChannelStateOutputPowerDbObj.TxPower[i], _ = strconv.ParseFloat(transceiverDomSensorTable.Get(fmt.Sprintf("tx%dpower", i+1)), 64) @@ -802,7 +856,11 @@ func (app *PlatformApp) getCompTransceiverPhysicalChannelStateInputPowerDbObj(if var compTransceiverPhysicalChannelStateInputPowerDbObj CompTransceiverPhysicalChannelStateInputPowerDb - transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry + transceiverDomSensorTable, ok := app.getTransceiverDomSensorEntry(ifName) + if !ok { + log.Warningf("getCompTransceiverPhysicalChannelStateInputPowerDbObj: TRANSCEIVER_DOM_SENSOR entry missing for ifName=%s", ifName) + return compTransceiverPhysicalChannelStateInputPowerDbObj + } for i := 0; i < 8; i++ { compTransceiverPhysicalChannelStateInputPowerDbObj.RxPower[i], _ = strconv.ParseFloat(transceiverDomSensorTable.Get(fmt.Sprintf("rx%dpower", i+1)), 64) @@ -842,7 +900,14 @@ func (app *PlatformApp) getCompTransceiverPhysicalChannelStateLaserBiasCurrentDb var compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj CompTransceiverPhysicalChannelStateLaserBiasCurrentDb - transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry + transceiverDomSensorTable, ok := app.getTransceiverDomSensorEntry(ifName) + if !ok { + log.Warningf("getCompTransceiverPhysicalChannelStateLaserBiasCurrentDbObj: TRANSCEIVER_DOM_SENSOR entry missing for ifName=%s", ifName) + for i := 0; i < 8; i++ { + compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj.TxBias[i] = math.NaN() + } + return compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj + } for i := 0; i < 8; i++ { field := fmt.Sprintf("tx%dbias", i+1) @@ -907,7 +972,11 @@ func (app *PlatformApp) getCompTransceiverThresholdStateDbObj(ifName string) Com var compTransceiverThresholdStateDbObj CompTransceiverThresholdStateDb - transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry + transceiverDomThresholdTable, ok := app.getTransceiverDomThresholdEntry(ifName) + if !ok { + log.Warningf("getCompTransceiverThresholdStateDbObj: TRANSCEIVER_DOM_THRESHOLD entry missing for ifName=%s", ifName) + return compTransceiverThresholdStateDbObj + } compTransceiverThresholdStateDbObj.TempHighAlarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("temphighalarm"), 64) compTransceiverThresholdStateDbObj.TempLowAlarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("templowalarm"), 64) @@ -1127,7 +1196,7 @@ func (app *PlatformApp) doGetPlatformInfo() error { break } ifName := strings.Replace(compName, "transceiver_", "", -1) - applPortTable := app.applPortTable[ifName].entry + applPortTable, _ := app.getApplPortEntry(ifName) pf_channel_0, _ := pf_comp.Transceiver.PhysicalChannels.NewChannel(0) if pf_channel_0 != nil { @@ -1185,7 +1254,7 @@ func (app *PlatformApp) doGetPlatformInfo() error { break } ifName := strings.Replace(compName, "transceiver_", "", -1) - applPortTable := app.applPortTable[ifName].entry + applPortTable, _ := app.getApplPortEntry(ifName) pf_channel_0, _ := pf_comp.Transceiver.PhysicalChannels.NewChannel(0) if pf_channel_0 != nil { @@ -1240,7 +1309,7 @@ func (app *PlatformApp) doGetPlatformInfo() error { break } ifName := strings.Replace(compName, "transceiver_", "", -1) - applPortTable := app.applPortTable[ifName].entry + applPortTable, _ := app.getApplPortEntry(ifName) pf_channel_0, _ := pf_comp.Transceiver.PhysicalChannels.NewChannel(0) if pf_channel_0 != nil { @@ -1310,7 +1379,7 @@ func (app *PlatformApp) doGetPlatformInfo() error { break } ifName := strings.Replace(compName, "transceiver_", "", -1) - applPortTable := app.applPortTable[ifName].entry + applPortTable, _ := app.getApplPortEntry(ifName) pf_channel_0, _ := pf_comp.Transceiver.PhysicalChannels.NewChannel(0) if pf_channel_0 != nil { @@ -1383,7 +1452,7 @@ func (app *PlatformApp) doGetPlatformInfo() error { if pf_comp != nil { ygot.BuildEmptyTree(pf_comp) ifName := strings.Replace(compName, "transceiver_", "", -1) - applPortTable := app.applPortTable[ifName].entry + applPortTable, _ := app.getApplPortEntry(ifName) pf_channel_0, _ := pf_comp.Transceiver.PhysicalChannels.NewChannel(0) if pf_channel_0 != nil { @@ -1426,7 +1495,7 @@ func (app *PlatformApp) doGetPlatformInfo() error { indexName := app.path.Var("index") if indexName == "" { ifName := strings.Replace(compName, "transceiver_", "", -1) - applPortTable := app.applPortTable[ifName].entry + applPortTable, _ := app.getApplPortEntry(ifName) pf_channel_0, _ := pf_comp.Transceiver.PhysicalChannels.NewChannel(0) if pf_channel_0 != nil { @@ -1457,7 +1526,7 @@ func (app *PlatformApp) doGetPlatformInfo() error { compIndex, _ := strconv.ParseUint(indexName, 10, 16) log.Info("compIndex =", compIndex) ifName := strings.Replace(compName, "transceiver_", "", -1) - applPortTable := app.applPortTable[ifName].entry + applPortTable, _ := app.getApplPortEntry(ifName) if compIndex == 0 { pf_channel := pf_comp.Transceiver.PhysicalChannels.Channel[uint16(compIndex)] @@ -1509,7 +1578,7 @@ func (app *PlatformApp) doGetPlatformInfo() error { compIndex, _ := strconv.ParseUint(app.path.Var("index"), 10, 16) log.Info("compIndex =", compIndex) ifName := strings.Replace(compName, "transceiver_", "", -1) - applPortTable := app.applPortTable[ifName].entry + applPortTable, _ := app.getApplPortEntry(ifName) if compIndex == 0 { pf_channel := pf_comp.Transceiver.PhysicalChannels.Channel[uint16(compIndex)] @@ -1587,7 +1656,7 @@ func (app *PlatformApp) doGetPlatformInfo() error { compIndex, _ := strconv.ParseUint(app.path.Var("index"), 10, 16) log.Info("compIndex =", compIndex) ifName := strings.Replace(compName, "transceiver_", "", -1) - applPortTable := app.applPortTable[ifName].entry + applPortTable, _ := app.getApplPortEntry(ifName) for index, lane := range strings.Split(applPortTable.Get("lanes"), ",") { laneNum, _ := strconv.ParseUint(lane, 10, 16) @@ -1620,7 +1689,7 @@ func (app *PlatformApp) doGetPlatformInfo() error { compIndex, _ := strconv.ParseUint(app.path.Var("index"), 10, 16) log.Info("compIndex =", compIndex) ifName := strings.Replace(compName, "transceiver_", "", -1) - applPortTable := app.applPortTable[ifName].entry + applPortTable, _ := app.getApplPortEntry(ifName) for index, lane := range strings.Split(applPortTable.Get("lanes"), ",") { laneNum, _ := strconv.ParseUint(lane, 10, 16) @@ -1653,7 +1722,7 @@ func (app *PlatformApp) doGetPlatformInfo() error { compIndex, _ := strconv.ParseUint(app.path.Var("index"), 10, 16) log.Info("compIndex =", compIndex) ifName := strings.Replace(compName, "transceiver_", "", -1) - applPortTable := app.applPortTable[ifName].entry + applPortTable, _ := app.getApplPortEntry(ifName) for index, lane := range strings.Split(applPortTable.Get("lanes"), ",") { laneNum, _ := strconv.ParseUint(lane, 10, 16) @@ -1791,7 +1860,7 @@ func (app *PlatformApp) doGetPlatformInfo() error { ygot.BuildEmptyTree(pf_comp) compIndex, _ := strconv.ParseUint(app.path.Var("index"), 10, 16) ifName := strings.Replace(compName, "transceiver_", "", -1) - applPortTable := app.applPortTable[ifName].entry + applPortTable, _ := app.getApplPortEntry(ifName) for index, lane := range strings.Split(applPortTable.Get("lanes"), ",") { laneNum, _ := strconv.ParseUint(lane, 10, 16) @@ -1822,7 +1891,7 @@ func (app *PlatformApp) doGetPlatformInfo() error { ygot.BuildEmptyTree(pf_comp) compIndex, _ := strconv.ParseUint(app.path.Var("index"), 10, 16) ifName := strings.Replace(compName, "transceiver_", "", -1) - applPortTable := app.applPortTable[ifName].entry + applPortTable, _ := app.getApplPortEntry(ifName) for index, lane := range strings.Split(applPortTable.Get("lanes"), ",") { laneNum, _ := strconv.ParseUint(lane, 10, 16) @@ -1853,7 +1922,7 @@ func (app *PlatformApp) doGetPlatformInfo() error { ygot.BuildEmptyTree(pf_comp) compIndex, _ := strconv.ParseUint(app.path.Var("index"), 10, 16) ifName := strings.Replace(compName, "transceiver_", "", -1) - applPortTable := app.applPortTable[ifName].entry + applPortTable, _ := app.getApplPortEntry(ifName) for index, lane := range strings.Split(applPortTable.Get("lanes"), ",") { laneNum, _ := strconv.ParseUint(lane, 10, 16) From 11bcd7d47a1063dd47ebafc7cfe7cf4cc22f1385 Mon Sep 17 00:00:00 2001 From: Kanji Nakano Date: Mon, 25 May 2026 18:32:30 +0900 Subject: [PATCH 08/12] translib: split transceiver getters into pfm_app_transceiver.go Address review comment on PR #201: pfm_app.go had grown to roughly 2100 lines, dominated by the OpenConfig Platform Transceiver getters that were appended for #201. Per the maintainer's note that breaking the new logic into separate files is acceptable, move the transceiver Db-struct types and getCompTransceiver* getters into a new translib/pfm_app_transceiver.go in the same package. What stays in pfm_app.go: - PlatformApp struct, init / translate* / process* - The four map-lookup helpers (getTransceiverInfoEntry, getTransceiverDomSensorEntry, getTransceiverDomThresholdEntry, getApplPortEntry) so callers across both files can share them - getCompStateDbObj / getCompStateFromDb (System Component state) - doGetPlatformInfo, which continues to be the single dispatch entry point and now calls into the transceiver getters located in the new file What moves to pfm_app_transceiver.go: - CompTransceiverStateDb / CompTransceiverStateSupplyVoltageDb / CompTransceiverPhysicalChannelState{Laser{Temperature, BiasCurrent}, OutputPower, InputPower}Db / CompTransceiverThresholdStateDb - getCompTransceiverStateDbObj / getCompTransceiverStateFromDb - getCompTransceiverStateSupplyVoltage{DbObj, FromDb} - getCompTransceiverPhysicalChannelStateLaserTemperature{DbObj, FromDb} - getCompTransceiverPhysicalChannelStateOutputPower{DbObj, FromDb} - getCompTransceiverPhysicalChannelStateInputPower{DbObj, FromDb} - getCompTransceiverPhysicalChannelStateLaserBiasCurrent{DbObj, FromDb} - getCompTransceiverThresholdState{DbObj, FromDb} This is purely a file-organisation change: no symbol is renamed, no logic is altered. pfm_app.go drops from ~1990 to ~1440 lines, and the new file is ~580 lines. Drop the now-unused math, regexp and (already-unused) reflect-adjacent imports from pfm_app.go's import block. pfm_app_transceiver.go has its own minimal import block (fmt, math, regexp, strconv, strings, ocbinds, glog). doGetPlatformInfo itself remains long; further extraction by URI pattern is out of scope for this patch and will be a follow-up. Signed-off-by: Kanji Nakano --- translib/pfm_app.go | 550 ------------------------------ translib/pfm_app_transceiver.go | 584 ++++++++++++++++++++++++++++++++ 2 files changed, 584 insertions(+), 550 deletions(-) create mode 100644 translib/pfm_app_transceiver.go diff --git a/translib/pfm_app.go b/translib/pfm_app.go index 65e48eab2..095d67e85 100644 --- a/translib/pfm_app.go +++ b/translib/pfm_app.go @@ -20,15 +20,12 @@ package translib import ( "errors" - "fmt" "github.com/Azure/sonic-mgmt-common/translib/db" "github.com/Azure/sonic-mgmt-common/translib/ocbinds" "github.com/Azure/sonic-mgmt-common/translib/tlerr" log "github.com/golang/glog" "github.com/openconfig/ygot/ygot" - "math" "reflect" - "regexp" "strconv" "strings" ) @@ -612,553 +609,6 @@ func (app *PlatformApp) getCompStateFromDb(oc_val *ocbinds.OpenconfigPlatform_Co return nil } -type CompTransceiverStateDb struct { - Connector string - Manufacturer string - VendorOui string - VendorRev string - Serial string - VendorDate string -} - -func (app *PlatformApp) getCompTransceiverStateDbObj(ifName string) CompTransceiverStateDb { - log.Infof("parseCompTransceiverStateDb Enter ifName=%s", ifName) - - var compTransceiverStateDbObj CompTransceiverStateDb - - transceiverInfoTable, ok := app.getTransceiverInfoEntry(ifName) - if !ok { - log.Warningf("getCompTransceiverStateDbObj: TRANSCEIVER_INFO entry missing for ifName=%s", ifName) - return compTransceiverStateDbObj - } - - compTransceiverStateDbObj.Connector = transceiverInfoTable.Get("connector") - compTransceiverStateDbObj.Manufacturer = transceiverInfoTable.Get("manufacturer") - compTransceiverStateDbObj.VendorOui = transceiverInfoTable.Get("vendor_oui") - compTransceiverStateDbObj.VendorRev = transceiverInfoTable.Get("vendor_rev") - compTransceiverStateDbObj.Serial = transceiverInfoTable.Get("serial") - compTransceiverStateDbObj.VendorDate = transceiverInfoTable.Get("vendor_date") - - return compTransceiverStateDbObj -} - -func (app *PlatformApp) getCompTransceiverStateFromDb(oc_val *ocbinds.OpenconfigPlatform_Components_Component_Transceiver_State, all bool, compName string) error { - log.Infof("getCompTransceiverStateFromDb Enter compName=%s", compName) - - ifName := strings.Replace(compName, "transceiver_", "", -1) - compTransceiverStateDb := app.getCompTransceiverStateDbObj(ifName) - - targetUriPath, _ := getYangPathFromUri(app.path.Path) - - if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/state/connector-type" { - transceiverInfoTable := app.transceiverInfoTable[ifName].entry - if transceiverInfoTable.Has("connector") { - if strings.HasPrefix(compTransceiverStateDb.Connector, "AOC") { - oc_val.ConnectorType = ocbinds.OpenconfigTransportTypes_FIBER_CONNECTOR_TYPE_AOC_CONNECTOR - } else if strings.HasPrefix(compTransceiverStateDb.Connector, "DAC") { - oc_val.ConnectorType = ocbinds.OpenconfigTransportTypes_FIBER_CONNECTOR_TYPE_DAC_CONNECTOR - } else if strings.HasPrefix(compTransceiverStateDb.Connector, "LC") { - oc_val.ConnectorType = ocbinds.OpenconfigTransportTypes_FIBER_CONNECTOR_TYPE_LC_CONNECTOR - } else if strings.HasPrefix(compTransceiverStateDb.Connector, "MPO") { - oc_val.ConnectorType = ocbinds.OpenconfigTransportTypes_FIBER_CONNECTOR_TYPE_MPO_CONNECTOR - } else if strings.HasPrefix(compTransceiverStateDb.Connector, "SC") { - oc_val.ConnectorType = ocbinds.OpenconfigTransportTypes_FIBER_CONNECTOR_TYPE_SC_CONNECTOR - } else { - oc_val.ConnectorType = ocbinds.OpenconfigTransportTypes_FIBER_CONNECTOR_TYPE_UNSET - } - } - } - if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/state/vendor" { - transceiverInfoTable := app.transceiverInfoTable[ifName].entry - if transceiverInfoTable.Has("manufacturer") { - oc_val.Vendor = &compTransceiverStateDb.Manufacturer - } - } - if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/state/vendor-part" { - transceiverInfoTable := app.transceiverInfoTable[ifName].entry - if transceiverInfoTable.Has("vendor_oui") { - // Per HLD (sonic-net/SONiC PR #1858, "Mapping between Openconfig - // YANG and Redis DB" Table 2): vendor-part is sourced from - // STATE_DB TRANSCEIVER_INFO.vendor_oui. - oc_val.VendorPart = &compTransceiverStateDb.VendorOui - } - } - if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/state/vendor-rev" { - transceiverInfoTable := app.transceiverInfoTable[ifName].entry - if transceiverInfoTable.Has("vendor_rev") { - oc_val.VendorRev = &compTransceiverStateDb.VendorRev - } - } - if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/state/serial-no" { - transceiverInfoTable := app.transceiverInfoTable[ifName].entry - if transceiverInfoTable.Has("serial") { - oc_val.SerialNo = &compTransceiverStateDb.Serial - } - } - if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/state/date-code" { - transceiverInfoTable := app.transceiverInfoTable[ifName].entry - if transceiverInfoTable.Has("vendor_date") { - rex := regexp.MustCompile("[0-9]+") - subMatchString := rex.FindAllString(compTransceiverStateDb.VendorDate, -1) - if len(subMatchString) >= 3 { - if len(subMatchString[0]) == 4 && len(subMatchString[1]) == 2 && len(subMatchString[2]) == 2 { - vendorDate := fmt.Sprintf("%s-%s-%sT00:00:00.000Z", subMatchString[0], subMatchString[1], subMatchString[2]) - formatMatch, _ := regexp.MatchString("[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])[Tt]00:00:00\\.000Z", vendorDate) - if formatMatch { - oc_val.DateCode = &vendorDate - } - } - } - } - } - - return nil -} - -type CompTransceiverStateSupplyVoltageDb struct { - voltage float64 -} - -func (app *PlatformApp) getCompTransceiverStateSupplyVoltageDbObj(ifName string) CompTransceiverStateSupplyVoltageDb { - log.Infof("parseCompTransceiverStateSupplyVoltageDb Enter ifName=%s", ifName) - - var compTransceiverStateSupplyVoltageDbObj CompTransceiverStateSupplyVoltageDb - - transceiverDomSensorTable, ok := app.getTransceiverDomSensorEntry(ifName) - if !ok { - log.Warningf("getCompTransceiverStateSupplyVoltageDbObj: TRANSCEIVER_DOM_SENSOR entry missing for ifName=%s", ifName) - compTransceiverStateSupplyVoltageDbObj.voltage = math.NaN() - return compTransceiverStateSupplyVoltageDbObj - } - - if transceiverDomSensorTable.Get("voltage") != "N/A" { - compTransceiverStateSupplyVoltageDbObj.voltage, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("voltage"), 64) - } else { - compTransceiverStateSupplyVoltageDbObj.voltage = math.NaN() - } - - return compTransceiverStateSupplyVoltageDbObj -} - -func (app *PlatformApp) getCompTransceiverStateSupplyVoltageFromDb(oc_val *ocbinds.OpenconfigPlatform_Components_Component_Transceiver_State_SupplyVoltage, all bool, compName string) error { - log.Infof("getCompTransceiverStateSupplyVoltageFromDb Enter compName=%s", compName) - - ifName := strings.Replace(compName, "transceiver_", "", -1) - compTransceiverStateSupplyVoltageDb := app.getCompTransceiverStateSupplyVoltageDbObj(ifName) - - targetUriPath, _ := getYangPathFromUri(app.path.Path) - - if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/state/supply-voltage/instant" { - transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry - if transceiverDomSensorTable.Has("voltage") { - voltage := math.Floor(compTransceiverStateSupplyVoltageDb.voltage*fractionDigits2) / fractionDigits2 - oc_val.Instant = &voltage - } - } - - return nil -} - -type CompTransceiverPhysicalChannelStateLaserTemperatureDb struct { - temperature float64 -} - -func (app *PlatformApp) getCompTransceiverPhysicalChannelStateLaserTemperatureDbObj(ifName string) CompTransceiverPhysicalChannelStateLaserTemperatureDb { - log.Infof("parseCompTransceiverPhysicalChannelStateLaserTemperatureDb Enter ifName=%s", ifName) - - var compTransceiverPhysicalChannelStateLaserTemperatureDbObj CompTransceiverPhysicalChannelStateLaserTemperatureDb - - transceiverDomSensorTable, ok := app.getTransceiverDomSensorEntry(ifName) - if !ok { - log.Warningf("getCompTransceiverPhysicalChannelStateLaserTemperatureDbObj: TRANSCEIVER_DOM_SENSOR entry missing for ifName=%s", ifName) - compTransceiverPhysicalChannelStateLaserTemperatureDbObj.temperature = math.NaN() - return compTransceiverPhysicalChannelStateLaserTemperatureDbObj - } - - if transceiverDomSensorTable.Get("temperature") != "N/A" { - compTransceiverPhysicalChannelStateLaserTemperatureDbObj.temperature, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("temperature"), 64) - } else { - compTransceiverPhysicalChannelStateLaserTemperatureDbObj.temperature = math.NaN() - } - - return compTransceiverPhysicalChannelStateLaserTemperatureDbObj -} - -func (app *PlatformApp) getCompTransceiverPhysicalChannelStateLaserTemperatureFromDb(oc_val *ocbinds.OpenconfigPlatform_Components_Component_Transceiver_PhysicalChannels_Channel_State_LaserTemperature, all bool, compName string) error { - log.Infof("getCompTransceiverPhysicalChannelStateLaserTemperatureFromDb Enter compName=%s", compName) - - ifName := strings.Replace(compName, "transceiver_", "", -1) - compTransceiverPhysicalChannelStateLaserTemperatureDb := app.getCompTransceiverPhysicalChannelStateLaserTemperatureDbObj(ifName) - - targetUriPath, _ := getYangPathFromUri(app.path.Path) - - if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/physical-channels/channel/state/laser-temperature/instant" { - transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry - if transceiverDomSensorTable.Has("temperature") { - temperature := math.Floor(compTransceiverPhysicalChannelStateLaserTemperatureDb.temperature*fractionDigits1) / fractionDigits1 - oc_val.Instant = &temperature - } - } - - return nil -} - -type CompTransceiverPhysicalChannelStateOutputPowerDb struct { - TxPower [8]float64 -} - -func (app *PlatformApp) getCompTransceiverPhysicalChannelStateOutputPowerDbObj(ifName string) CompTransceiverPhysicalChannelStateOutputPowerDb { - log.Infof("parseCompTransceiverPhysicalChannelStateOutputPowerDb Enter ifName=%s", ifName) - - var compTransceiverPhysicalChannelStateOutputPowerDbObj CompTransceiverPhysicalChannelStateOutputPowerDb - - transceiverDomSensorTable, ok := app.getTransceiverDomSensorEntry(ifName) - if !ok { - log.Warningf("getCompTransceiverPhysicalChannelStateOutputPowerDbObj: TRANSCEIVER_DOM_SENSOR entry missing for ifName=%s", ifName) - return compTransceiverPhysicalChannelStateOutputPowerDbObj - } - - for i := 0; i < 8; i++ { - compTransceiverPhysicalChannelStateOutputPowerDbObj.TxPower[i], _ = strconv.ParseFloat(transceiverDomSensorTable.Get(fmt.Sprintf("tx%dpower", i+1)), 64) - } - - return compTransceiverPhysicalChannelStateOutputPowerDbObj -} - -func (app *PlatformApp) getCompTransceiverPhysicalChannelStateOutputPowerFromDb(oc_val *ocbinds.OpenconfigPlatform_Components_Component_Transceiver_PhysicalChannels_Channel_State_OutputPower, all bool, compName string, laneIndex uint16) error { - log.Infof("getCompTransceiverPhysicalChannelStateOutputPowerFromDb Enter compName=%s laneIndex=%d", compName, laneIndex) - - ifName := strings.Replace(compName, "transceiver_", "", -1) - compTransceiverPhysicalChannelStateOutputPowerDb := app.getCompTransceiverPhysicalChannelStateOutputPowerDbObj(ifName) - - targetUriPath, _ := getYangPathFromUri(app.path.Path) - - if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/physical-channels/channel/state/output-power/instant" { - if int(laneIndex) < 8 { - fieldName := fmt.Sprintf("tx%dpower", laneIndex+1) - transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry - if transceiverDomSensorTable.Has(fieldName) { - txpower := math.Floor(compTransceiverPhysicalChannelStateOutputPowerDb.TxPower[laneIndex]*fractionDigits2) / fractionDigits2 - oc_val.Instant = &txpower - } - } - } - - return nil -} - -type CompTransceiverPhysicalChannelStateInputPowerDb struct { - RxPower [8]float64 -} - -func (app *PlatformApp) getCompTransceiverPhysicalChannelStateInputPowerDbObj(ifName string) CompTransceiverPhysicalChannelStateInputPowerDb { - log.Infof("parseCompTransceiverPhysicalChannelStateInputPowerDb Enter ifName=%s", ifName) - - var compTransceiverPhysicalChannelStateInputPowerDbObj CompTransceiverPhysicalChannelStateInputPowerDb - - transceiverDomSensorTable, ok := app.getTransceiverDomSensorEntry(ifName) - if !ok { - log.Warningf("getCompTransceiverPhysicalChannelStateInputPowerDbObj: TRANSCEIVER_DOM_SENSOR entry missing for ifName=%s", ifName) - return compTransceiverPhysicalChannelStateInputPowerDbObj - } - - for i := 0; i < 8; i++ { - compTransceiverPhysicalChannelStateInputPowerDbObj.RxPower[i], _ = strconv.ParseFloat(transceiverDomSensorTable.Get(fmt.Sprintf("rx%dpower", i+1)), 64) - } - - return compTransceiverPhysicalChannelStateInputPowerDbObj -} - -func (app *PlatformApp) getCompTransceiverPhysicalChannelStateInputPowerFromDb(oc_val *ocbinds.OpenconfigPlatform_Components_Component_Transceiver_PhysicalChannels_Channel_State_InputPower, all bool, compName string, laneIndex uint16) error { - log.Infof("getCompTransceiverPhysicalChannelStateInputPowerFromDb Enter compName=%s laneIndex=%d", compName, laneIndex) - - ifName := strings.Replace(compName, "transceiver_", "", -1) - compTransceiverPhysicalChannelStateInputPowerDb := app.getCompTransceiverPhysicalChannelStateInputPowerDbObj(ifName) - - targetUriPath, _ := getYangPathFromUri(app.path.Path) - - if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/physical-channels/channel/state/input-power/instant" { - if int(laneIndex) < 8 { - fieldName := fmt.Sprintf("rx%dpower", laneIndex+1) - transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry - if transceiverDomSensorTable.Has(fieldName) { - rxpower := math.Floor(compTransceiverPhysicalChannelStateInputPowerDb.RxPower[laneIndex]*fractionDigits2) / fractionDigits2 - oc_val.Instant = &rxpower - } - } - } - - return nil -} - -type CompTransceiverPhysicalChannelStateLaserBiasCurrentDb struct { - TxBias [8]float64 -} - -func (app *PlatformApp) getCompTransceiverPhysicalChannelStateLaserBiasCurrentDbObj(ifName string) CompTransceiverPhysicalChannelStateLaserBiasCurrentDb { - log.Infof("parseCompTransceiverPhysicalChannelStateLaserBiasCurrentDb Enter ifName=%s", ifName) - - var compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj CompTransceiverPhysicalChannelStateLaserBiasCurrentDb - - transceiverDomSensorTable, ok := app.getTransceiverDomSensorEntry(ifName) - if !ok { - log.Warningf("getCompTransceiverPhysicalChannelStateLaserBiasCurrentDbObj: TRANSCEIVER_DOM_SENSOR entry missing for ifName=%s", ifName) - for i := 0; i < 8; i++ { - compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj.TxBias[i] = math.NaN() - } - return compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj - } - - for i := 0; i < 8; i++ { - field := fmt.Sprintf("tx%dbias", i+1) - raw := transceiverDomSensorTable.Get(field) - if raw != "N/A" { - compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj.TxBias[i], _ = strconv.ParseFloat(raw, 64) - } else { - compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj.TxBias[i] = math.NaN() - } - } - - return compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj -} - -func (app *PlatformApp) getCompTransceiverPhysicalChannelStateLaserBiasCurrentFromDb(oc_val *ocbinds.OpenconfigPlatform_Components_Component_Transceiver_PhysicalChannels_Channel_State_LaserBiasCurrent, all bool, compName string, laneIndex uint16) error { - log.Infof("getCompTransceiverPhysicalChannelStateLaserBiasCurrentFromDb Enter compName=%s laneIndex=%d", compName, laneIndex) - - ifName := strings.Replace(compName, "transceiver_", "", -1) - compTransceiverPhysicalChannelStateLaserBiasCurrentDb := app.getCompTransceiverPhysicalChannelStateLaserBiasCurrentDbObj(ifName) - - targetUriPath, _ := getYangPathFromUri(app.path.Path) - - if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/physical-channels/channel/state/laser-bias-current/instant" { - if int(laneIndex) < 8 { - fieldName := fmt.Sprintf("tx%dbias", laneIndex+1) - transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry - if transceiverDomSensorTable.Has(fieldName) { - txbias := math.Floor(compTransceiverPhysicalChannelStateLaserBiasCurrentDb.TxBias[laneIndex]*fractionDigits2) / fractionDigits2 - oc_val.Instant = &txbias - } - } - } - - return nil -} - -type CompTransceiverThresholdStateDb struct { - TempHighAlarm float64 - TempLowAlarm float64 - VccHighAlarm float64 - VccLowAlarm float64 - TempHighWarning float64 - TempLowWarning float64 - VccHighWarning float64 - VccLowWarning float64 - TxPowerHighAlarm float64 - TxPowerLowAlarm float64 - RxPowerHighAlarm float64 - RxPowerLowAlarm float64 - TxBiasHighAlarm float64 - TxBiasLowAlarm float64 - TxPowerHighWarning float64 - TxPowerLowWarning float64 - RxPowerHighWarning float64 - RxPowerLowWarning float64 - TxBiasHighWarning float64 - TxBiasLowWarning float64 -} - -func (app *PlatformApp) getCompTransceiverThresholdStateDbObj(ifName string) CompTransceiverThresholdStateDb { - log.Infof("parseCompTransceiverThresholdStateDb Enter ifName=%s", ifName) - - var compTransceiverThresholdStateDbObj CompTransceiverThresholdStateDb - - transceiverDomThresholdTable, ok := app.getTransceiverDomThresholdEntry(ifName) - if !ok { - log.Warningf("getCompTransceiverThresholdStateDbObj: TRANSCEIVER_DOM_THRESHOLD entry missing for ifName=%s", ifName) - return compTransceiverThresholdStateDbObj - } - - compTransceiverThresholdStateDbObj.TempHighAlarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("temphighalarm"), 64) - compTransceiverThresholdStateDbObj.TempLowAlarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("templowalarm"), 64) - compTransceiverThresholdStateDbObj.VccHighAlarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("vcchighalarm"), 64) - compTransceiverThresholdStateDbObj.VccLowAlarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("vcclowalarm"), 64) - compTransceiverThresholdStateDbObj.TempHighWarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("temphighwarning"), 64) - compTransceiverThresholdStateDbObj.TempLowWarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("templowwarning"), 64) - compTransceiverThresholdStateDbObj.VccHighWarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("vcchighwarning"), 64) - compTransceiverThresholdStateDbObj.VccLowWarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("vcclowwarning"), 64) - compTransceiverThresholdStateDbObj.TxPowerHighAlarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("txpowerhighalarm"), 64) - compTransceiverThresholdStateDbObj.TxPowerLowAlarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("txpowerlowalarm"), 64) - compTransceiverThresholdStateDbObj.RxPowerHighAlarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("rxpowerhighalarm"), 64) - compTransceiverThresholdStateDbObj.RxPowerLowAlarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("rxpowerlowalarm"), 64) - compTransceiverThresholdStateDbObj.TxBiasHighAlarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("txbiashighalarm"), 64) - compTransceiverThresholdStateDbObj.TxBiasLowAlarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("txbiaslowalarm"), 64) - compTransceiverThresholdStateDbObj.TxPowerHighWarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("txpowerhighwarning"), 64) - compTransceiverThresholdStateDbObj.TxPowerLowWarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("txpowerlowwarning"), 64) - compTransceiverThresholdStateDbObj.RxPowerHighWarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("rxpowerhighwarning"), 64) - compTransceiverThresholdStateDbObj.RxPowerLowWarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("rxpowerlowwarning"), 64) - compTransceiverThresholdStateDbObj.TxBiasHighWarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("txbiashighwarning"), 64) - compTransceiverThresholdStateDbObj.TxBiasLowWarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("txbiaslowwarning"), 64) - - return compTransceiverThresholdStateDbObj -} - -func (app *PlatformApp) getCompTransceiverThresholdStateFromDb(oc_val *ocbinds.OpenconfigPlatform_Components_Component_Transceiver_Thresholds_Threshold_State, all bool, compName string, severityName string) error { - log.Infof("getCompTransceiverThresholdStateFromDb Enter compName=%s severityName=%s", compName, severityName) - - ifName := strings.Replace(compName, "transceiver_", "", -1) - compTransceiverThresholdStateDb := app.getCompTransceiverThresholdStateDbObj(ifName) - - targetUriPath, _ := getYangPathFromUri(app.path.Path) - - if severityName == "CRITICAL" { - if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/laser-temperature-upper" { - transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry - if transceiverDomThresholdTable.Has("temphighalarm") { - temphighalarm := math.Floor(compTransceiverThresholdStateDb.TempHighAlarm*fractionDigits1) / fractionDigits1 - oc_val.LaserTemperatureUpper = &temphighalarm - } - } - if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/laser-temperature-lower" { - transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry - if transceiverDomThresholdTable.Has("templowalarm") { - templowalarm := math.Floor(compTransceiverThresholdStateDb.TempLowAlarm*fractionDigits1) / fractionDigits1 - oc_val.LaserTemperatureLower = &templowalarm - } - } - if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/supply-voltage-upper" { - transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry - if transceiverDomThresholdTable.Has("vcchighalarm") { - vcchighalarm := math.Floor(compTransceiverThresholdStateDb.VccHighAlarm*fractionDigits2) / fractionDigits2 - oc_val.SupplyVoltageUpper = &vcchighalarm - } - } - if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/supply-voltage-lower" { - transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry - if transceiverDomThresholdTable.Has("vcclowalarm") { - vcclowalarm := math.Floor(compTransceiverThresholdStateDb.VccLowAlarm*fractionDigits2) / fractionDigits2 - oc_val.SupplyVoltageLower = &vcclowalarm - } - } - if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/output-power-upper" { - transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry - if transceiverDomThresholdTable.Has("txpowerhighalarm") { - txpowerhighalarm := math.Floor(compTransceiverThresholdStateDb.TxPowerHighAlarm*fractionDigits2) / fractionDigits2 - oc_val.OutputPowerUpper = &txpowerhighalarm - } - } - if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/output-power-lower" { - transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry - if transceiverDomThresholdTable.Has("txpowerlowalarm") { - txpowerlowalarm := math.Floor(compTransceiverThresholdStateDb.TxPowerLowAlarm*fractionDigits2) / fractionDigits2 - oc_val.OutputPowerLower = &txpowerlowalarm - } - } - if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/input-power-upper" { - transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry - if transceiverDomThresholdTable.Has("rxpowerhighalarm") { - rxpowerhighalarm := math.Floor(compTransceiverThresholdStateDb.RxPowerHighAlarm*fractionDigits2) / fractionDigits2 - oc_val.InputPowerUpper = &rxpowerhighalarm - } - } - if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/input-power-lower" { - transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry - if transceiverDomThresholdTable.Has("rxpowerlowalarm") { - rxpowerlowalarm := math.Floor(compTransceiverThresholdStateDb.RxPowerLowAlarm*fractionDigits2) / fractionDigits2 - oc_val.InputPowerLower = &rxpowerlowalarm - } - } - if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/laser-bias-current-upper" { - transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry - if transceiverDomThresholdTable.Has("txbiashighalarm") { - txbiashighalarm := math.Floor(compTransceiverThresholdStateDb.TxBiasHighAlarm*fractionDigits2) / fractionDigits2 - oc_val.LaserBiasCurrentUpper = &txbiashighalarm - } - } - if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/laser-bias-current-lower" { - transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry - if transceiverDomThresholdTable.Has("txbiaslowalarm") { - txbiaslowalarm := math.Floor(compTransceiverThresholdStateDb.TxBiasLowAlarm*fractionDigits2) / fractionDigits2 - oc_val.LaserBiasCurrentLower = &txbiaslowalarm - } - } - } - - if severityName == "WARNING" { - if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/laser-temperature-upper" { - transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry - if transceiverDomThresholdTable.Has("temphighwarning") { - temphighwarning := math.Floor(compTransceiverThresholdStateDb.TempHighWarning*fractionDigits1) / fractionDigits1 - oc_val.LaserTemperatureUpper = &temphighwarning - } - } - if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/laser-temperature-lower" { - transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry - if transceiverDomThresholdTable.Has("templowwarning") { - templowwarning := math.Floor(compTransceiverThresholdStateDb.TempLowWarning*fractionDigits1) / fractionDigits1 - oc_val.LaserTemperatureLower = &templowwarning - } - } - if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/supply-voltage-upper" { - transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry - if transceiverDomThresholdTable.Has("vcchighwarning") { - vcchighwarning := math.Floor(compTransceiverThresholdStateDb.VccHighWarning*fractionDigits2) / fractionDigits2 - oc_val.SupplyVoltageUpper = &vcchighwarning - } - } - if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/supply-voltage-lower" { - transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry - if transceiverDomThresholdTable.Has("vcclowwarning") { - vcclowwarning := math.Floor(compTransceiverThresholdStateDb.VccLowWarning*fractionDigits2) / fractionDigits2 - oc_val.SupplyVoltageLower = &vcclowwarning - } - } - if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/output-power-upper" { - transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry - if transceiverDomThresholdTable.Has("txpowerhighwarning") { - v := math.Floor(compTransceiverThresholdStateDb.TxPowerHighWarning*fractionDigits2) / fractionDigits2 - oc_val.OutputPowerUpper = &v - } - } - if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/output-power-lower" { - transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry - if transceiverDomThresholdTable.Has("txpowerlowwarning") { - v := math.Floor(compTransceiverThresholdStateDb.TxPowerLowWarning*fractionDigits2) / fractionDigits2 - oc_val.OutputPowerLower = &v - } - } - if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/input-power-upper" { - transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry - if transceiverDomThresholdTable.Has("rxpowerhighwarning") { - v := math.Floor(compTransceiverThresholdStateDb.RxPowerHighWarning*fractionDigits2) / fractionDigits2 - oc_val.InputPowerUpper = &v - } - } - if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/input-power-lower" { - transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry - if transceiverDomThresholdTable.Has("rxpowerlowwarning") { - v := math.Floor(compTransceiverThresholdStateDb.RxPowerLowWarning*fractionDigits2) / fractionDigits2 - oc_val.InputPowerLower = &v - } - } - if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/laser-bias-current-upper" { - transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry - if transceiverDomThresholdTable.Has("txbiashighwarning") { - v := math.Floor(compTransceiverThresholdStateDb.TxBiasHighWarning*fractionDigits2) / fractionDigits2 - oc_val.LaserBiasCurrentUpper = &v - } - } - if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/laser-bias-current-lower" { - transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry - if transceiverDomThresholdTable.Has("txbiaslowwarning") { - v := math.Floor(compTransceiverThresholdStateDb.TxBiasLowWarning*fractionDigits2) / fractionDigits2 - oc_val.LaserBiasCurrentLower = &v - } - } - } - - return nil -} - func (app *PlatformApp) doGetPlatformInfo() error { log.Infof("Preparing collection for platform info") diff --git a/translib/pfm_app_transceiver.go b/translib/pfm_app_transceiver.go new file mode 100644 index 000000000..bc406b6e9 --- /dev/null +++ b/translib/pfm_app_transceiver.go @@ -0,0 +1,584 @@ +////////////////////////////////////////////////////////////////////////// +// +// Copyright 2019 Dell, Inc. +// +// 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. +// +////////////////////////////////////////////////////////////////////////// + +// pfm_app_transceiver.go holds the per-component OpenConfig Platform +// Transceiver getters and their STATE_DB-backed Db structs. The code was +// moved out of pfm_app.go to keep that file focused on the PlatformApp +// lifecycle (init / translate* / process* / doGetPlatformInfo) and the +// non-transceiver Component-state path. doGetPlatformInfo continues to be +// the single entry point that dispatches GETs to these getters. + +package translib + +import ( + "fmt" + "math" + "regexp" + "strconv" + "strings" + + "github.com/Azure/sonic-mgmt-common/translib/ocbinds" + log "github.com/golang/glog" +) + +type CompTransceiverStateDb struct { + Connector string + Manufacturer string + VendorOui string + VendorRev string + Serial string + VendorDate string +} + +func (app *PlatformApp) getCompTransceiverStateDbObj(ifName string) CompTransceiverStateDb { + log.Infof("parseCompTransceiverStateDb Enter ifName=%s", ifName) + + var compTransceiverStateDbObj CompTransceiverStateDb + + transceiverInfoTable, ok := app.getTransceiverInfoEntry(ifName) + if !ok { + log.Warningf("getCompTransceiverStateDbObj: TRANSCEIVER_INFO entry missing for ifName=%s", ifName) + return compTransceiverStateDbObj + } + + compTransceiverStateDbObj.Connector = transceiverInfoTable.Get("connector") + compTransceiverStateDbObj.Manufacturer = transceiverInfoTable.Get("manufacturer") + compTransceiverStateDbObj.VendorOui = transceiverInfoTable.Get("vendor_oui") + compTransceiverStateDbObj.VendorRev = transceiverInfoTable.Get("vendor_rev") + compTransceiverStateDbObj.Serial = transceiverInfoTable.Get("serial") + compTransceiverStateDbObj.VendorDate = transceiverInfoTable.Get("vendor_date") + + return compTransceiverStateDbObj +} + +func (app *PlatformApp) getCompTransceiverStateFromDb(oc_val *ocbinds.OpenconfigPlatform_Components_Component_Transceiver_State, all bool, compName string) error { + log.Infof("getCompTransceiverStateFromDb Enter compName=%s", compName) + + ifName := strings.Replace(compName, "transceiver_", "", -1) + compTransceiverStateDb := app.getCompTransceiverStateDbObj(ifName) + + targetUriPath, _ := getYangPathFromUri(app.path.Path) + + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/state/connector-type" { + transceiverInfoTable := app.transceiverInfoTable[ifName].entry + if transceiverInfoTable.Has("connector") { + if strings.HasPrefix(compTransceiverStateDb.Connector, "AOC") { + oc_val.ConnectorType = ocbinds.OpenconfigTransportTypes_FIBER_CONNECTOR_TYPE_AOC_CONNECTOR + } else if strings.HasPrefix(compTransceiverStateDb.Connector, "DAC") { + oc_val.ConnectorType = ocbinds.OpenconfigTransportTypes_FIBER_CONNECTOR_TYPE_DAC_CONNECTOR + } else if strings.HasPrefix(compTransceiverStateDb.Connector, "LC") { + oc_val.ConnectorType = ocbinds.OpenconfigTransportTypes_FIBER_CONNECTOR_TYPE_LC_CONNECTOR + } else if strings.HasPrefix(compTransceiverStateDb.Connector, "MPO") { + oc_val.ConnectorType = ocbinds.OpenconfigTransportTypes_FIBER_CONNECTOR_TYPE_MPO_CONNECTOR + } else if strings.HasPrefix(compTransceiverStateDb.Connector, "SC") { + oc_val.ConnectorType = ocbinds.OpenconfigTransportTypes_FIBER_CONNECTOR_TYPE_SC_CONNECTOR + } else { + oc_val.ConnectorType = ocbinds.OpenconfigTransportTypes_FIBER_CONNECTOR_TYPE_UNSET + } + } + } + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/state/vendor" { + transceiverInfoTable := app.transceiverInfoTable[ifName].entry + if transceiverInfoTable.Has("manufacturer") { + oc_val.Vendor = &compTransceiverStateDb.Manufacturer + } + } + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/state/vendor-part" { + transceiverInfoTable := app.transceiverInfoTable[ifName].entry + if transceiverInfoTable.Has("vendor_oui") { + // Per HLD (sonic-net/SONiC PR #1858, "Mapping between Openconfig + // YANG and Redis DB" Table 2): vendor-part is sourced from + // STATE_DB TRANSCEIVER_INFO.vendor_oui. + oc_val.VendorPart = &compTransceiverStateDb.VendorOui + } + } + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/state/vendor-rev" { + transceiverInfoTable := app.transceiverInfoTable[ifName].entry + if transceiverInfoTable.Has("vendor_rev") { + oc_val.VendorRev = &compTransceiverStateDb.VendorRev + } + } + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/state/serial-no" { + transceiverInfoTable := app.transceiverInfoTable[ifName].entry + if transceiverInfoTable.Has("serial") { + oc_val.SerialNo = &compTransceiverStateDb.Serial + } + } + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/state/date-code" { + transceiverInfoTable := app.transceiverInfoTable[ifName].entry + if transceiverInfoTable.Has("vendor_date") { + rex := regexp.MustCompile("[0-9]+") + subMatchString := rex.FindAllString(compTransceiverStateDb.VendorDate, -1) + if len(subMatchString) >= 3 { + if len(subMatchString[0]) == 4 && len(subMatchString[1]) == 2 && len(subMatchString[2]) == 2 { + vendorDate := fmt.Sprintf("%s-%s-%sT00:00:00.000Z", subMatchString[0], subMatchString[1], subMatchString[2]) + formatMatch, _ := regexp.MatchString("[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])[Tt]00:00:00\\.000Z", vendorDate) + if formatMatch { + oc_val.DateCode = &vendorDate + } + } + } + } + } + + return nil +} + +type CompTransceiverStateSupplyVoltageDb struct { + voltage float64 +} + +func (app *PlatformApp) getCompTransceiverStateSupplyVoltageDbObj(ifName string) CompTransceiverStateSupplyVoltageDb { + log.Infof("parseCompTransceiverStateSupplyVoltageDb Enter ifName=%s", ifName) + + var compTransceiverStateSupplyVoltageDbObj CompTransceiverStateSupplyVoltageDb + + transceiverDomSensorTable, ok := app.getTransceiverDomSensorEntry(ifName) + if !ok { + log.Warningf("getCompTransceiverStateSupplyVoltageDbObj: TRANSCEIVER_DOM_SENSOR entry missing for ifName=%s", ifName) + compTransceiverStateSupplyVoltageDbObj.voltage = math.NaN() + return compTransceiverStateSupplyVoltageDbObj + } + + if transceiverDomSensorTable.Get("voltage") != "N/A" { + compTransceiverStateSupplyVoltageDbObj.voltage, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("voltage"), 64) + } else { + compTransceiverStateSupplyVoltageDbObj.voltage = math.NaN() + } + + return compTransceiverStateSupplyVoltageDbObj +} + +func (app *PlatformApp) getCompTransceiverStateSupplyVoltageFromDb(oc_val *ocbinds.OpenconfigPlatform_Components_Component_Transceiver_State_SupplyVoltage, all bool, compName string) error { + log.Infof("getCompTransceiverStateSupplyVoltageFromDb Enter compName=%s", compName) + + ifName := strings.Replace(compName, "transceiver_", "", -1) + compTransceiverStateSupplyVoltageDb := app.getCompTransceiverStateSupplyVoltageDbObj(ifName) + + targetUriPath, _ := getYangPathFromUri(app.path.Path) + + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/state/supply-voltage/instant" { + transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry + if transceiverDomSensorTable.Has("voltage") { + voltage := math.Floor(compTransceiverStateSupplyVoltageDb.voltage*fractionDigits2) / fractionDigits2 + oc_val.Instant = &voltage + } + } + + return nil +} + +type CompTransceiverPhysicalChannelStateLaserTemperatureDb struct { + temperature float64 +} + +func (app *PlatformApp) getCompTransceiverPhysicalChannelStateLaserTemperatureDbObj(ifName string) CompTransceiverPhysicalChannelStateLaserTemperatureDb { + log.Infof("parseCompTransceiverPhysicalChannelStateLaserTemperatureDb Enter ifName=%s", ifName) + + var compTransceiverPhysicalChannelStateLaserTemperatureDbObj CompTransceiverPhysicalChannelStateLaserTemperatureDb + + transceiverDomSensorTable, ok := app.getTransceiverDomSensorEntry(ifName) + if !ok { + log.Warningf("getCompTransceiverPhysicalChannelStateLaserTemperatureDbObj: TRANSCEIVER_DOM_SENSOR entry missing for ifName=%s", ifName) + compTransceiverPhysicalChannelStateLaserTemperatureDbObj.temperature = math.NaN() + return compTransceiverPhysicalChannelStateLaserTemperatureDbObj + } + + if transceiverDomSensorTable.Get("temperature") != "N/A" { + compTransceiverPhysicalChannelStateLaserTemperatureDbObj.temperature, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("temperature"), 64) + } else { + compTransceiverPhysicalChannelStateLaserTemperatureDbObj.temperature = math.NaN() + } + + return compTransceiverPhysicalChannelStateLaserTemperatureDbObj +} + +func (app *PlatformApp) getCompTransceiverPhysicalChannelStateLaserTemperatureFromDb(oc_val *ocbinds.OpenconfigPlatform_Components_Component_Transceiver_PhysicalChannels_Channel_State_LaserTemperature, all bool, compName string) error { + log.Infof("getCompTransceiverPhysicalChannelStateLaserTemperatureFromDb Enter compName=%s", compName) + + ifName := strings.Replace(compName, "transceiver_", "", -1) + compTransceiverPhysicalChannelStateLaserTemperatureDb := app.getCompTransceiverPhysicalChannelStateLaserTemperatureDbObj(ifName) + + targetUriPath, _ := getYangPathFromUri(app.path.Path) + + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/physical-channels/channel/state/laser-temperature/instant" { + transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry + if transceiverDomSensorTable.Has("temperature") { + temperature := math.Floor(compTransceiverPhysicalChannelStateLaserTemperatureDb.temperature*fractionDigits1) / fractionDigits1 + oc_val.Instant = &temperature + } + } + + return nil +} + +type CompTransceiverPhysicalChannelStateOutputPowerDb struct { + TxPower [8]float64 +} + +func (app *PlatformApp) getCompTransceiverPhysicalChannelStateOutputPowerDbObj(ifName string) CompTransceiverPhysicalChannelStateOutputPowerDb { + log.Infof("parseCompTransceiverPhysicalChannelStateOutputPowerDb Enter ifName=%s", ifName) + + var compTransceiverPhysicalChannelStateOutputPowerDbObj CompTransceiverPhysicalChannelStateOutputPowerDb + + transceiverDomSensorTable, ok := app.getTransceiverDomSensorEntry(ifName) + if !ok { + log.Warningf("getCompTransceiverPhysicalChannelStateOutputPowerDbObj: TRANSCEIVER_DOM_SENSOR entry missing for ifName=%s", ifName) + return compTransceiverPhysicalChannelStateOutputPowerDbObj + } + + for i := 0; i < 8; i++ { + compTransceiverPhysicalChannelStateOutputPowerDbObj.TxPower[i], _ = strconv.ParseFloat(transceiverDomSensorTable.Get(fmt.Sprintf("tx%dpower", i+1)), 64) + } + + return compTransceiverPhysicalChannelStateOutputPowerDbObj +} + +func (app *PlatformApp) getCompTransceiverPhysicalChannelStateOutputPowerFromDb(oc_val *ocbinds.OpenconfigPlatform_Components_Component_Transceiver_PhysicalChannels_Channel_State_OutputPower, all bool, compName string, laneIndex uint16) error { + log.Infof("getCompTransceiverPhysicalChannelStateOutputPowerFromDb Enter compName=%s laneIndex=%d", compName, laneIndex) + + ifName := strings.Replace(compName, "transceiver_", "", -1) + compTransceiverPhysicalChannelStateOutputPowerDb := app.getCompTransceiverPhysicalChannelStateOutputPowerDbObj(ifName) + + targetUriPath, _ := getYangPathFromUri(app.path.Path) + + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/physical-channels/channel/state/output-power/instant" { + if int(laneIndex) < 8 { + fieldName := fmt.Sprintf("tx%dpower", laneIndex+1) + transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry + if transceiverDomSensorTable.Has(fieldName) { + txpower := math.Floor(compTransceiverPhysicalChannelStateOutputPowerDb.TxPower[laneIndex]*fractionDigits2) / fractionDigits2 + oc_val.Instant = &txpower + } + } + } + + return nil +} + +type CompTransceiverPhysicalChannelStateInputPowerDb struct { + RxPower [8]float64 +} + +func (app *PlatformApp) getCompTransceiverPhysicalChannelStateInputPowerDbObj(ifName string) CompTransceiverPhysicalChannelStateInputPowerDb { + log.Infof("parseCompTransceiverPhysicalChannelStateInputPowerDb Enter ifName=%s", ifName) + + var compTransceiverPhysicalChannelStateInputPowerDbObj CompTransceiverPhysicalChannelStateInputPowerDb + + transceiverDomSensorTable, ok := app.getTransceiverDomSensorEntry(ifName) + if !ok { + log.Warningf("getCompTransceiverPhysicalChannelStateInputPowerDbObj: TRANSCEIVER_DOM_SENSOR entry missing for ifName=%s", ifName) + return compTransceiverPhysicalChannelStateInputPowerDbObj + } + + for i := 0; i < 8; i++ { + compTransceiverPhysicalChannelStateInputPowerDbObj.RxPower[i], _ = strconv.ParseFloat(transceiverDomSensorTable.Get(fmt.Sprintf("rx%dpower", i+1)), 64) + } + + return compTransceiverPhysicalChannelStateInputPowerDbObj +} + +func (app *PlatformApp) getCompTransceiverPhysicalChannelStateInputPowerFromDb(oc_val *ocbinds.OpenconfigPlatform_Components_Component_Transceiver_PhysicalChannels_Channel_State_InputPower, all bool, compName string, laneIndex uint16) error { + log.Infof("getCompTransceiverPhysicalChannelStateInputPowerFromDb Enter compName=%s laneIndex=%d", compName, laneIndex) + + ifName := strings.Replace(compName, "transceiver_", "", -1) + compTransceiverPhysicalChannelStateInputPowerDb := app.getCompTransceiverPhysicalChannelStateInputPowerDbObj(ifName) + + targetUriPath, _ := getYangPathFromUri(app.path.Path) + + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/physical-channels/channel/state/input-power/instant" { + if int(laneIndex) < 8 { + fieldName := fmt.Sprintf("rx%dpower", laneIndex+1) + transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry + if transceiverDomSensorTable.Has(fieldName) { + rxpower := math.Floor(compTransceiverPhysicalChannelStateInputPowerDb.RxPower[laneIndex]*fractionDigits2) / fractionDigits2 + oc_val.Instant = &rxpower + } + } + } + + return nil +} + +type CompTransceiverPhysicalChannelStateLaserBiasCurrentDb struct { + TxBias [8]float64 +} + +func (app *PlatformApp) getCompTransceiverPhysicalChannelStateLaserBiasCurrentDbObj(ifName string) CompTransceiverPhysicalChannelStateLaserBiasCurrentDb { + log.Infof("parseCompTransceiverPhysicalChannelStateLaserBiasCurrentDb Enter ifName=%s", ifName) + + var compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj CompTransceiverPhysicalChannelStateLaserBiasCurrentDb + + transceiverDomSensorTable, ok := app.getTransceiverDomSensorEntry(ifName) + if !ok { + log.Warningf("getCompTransceiverPhysicalChannelStateLaserBiasCurrentDbObj: TRANSCEIVER_DOM_SENSOR entry missing for ifName=%s", ifName) + for i := 0; i < 8; i++ { + compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj.TxBias[i] = math.NaN() + } + return compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj + } + + for i := 0; i < 8; i++ { + field := fmt.Sprintf("tx%dbias", i+1) + raw := transceiverDomSensorTable.Get(field) + if raw != "N/A" { + compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj.TxBias[i], _ = strconv.ParseFloat(raw, 64) + } else { + compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj.TxBias[i] = math.NaN() + } + } + + return compTransceiverPhysicalChannelStateLaserBiasCurrentDbObj +} + +func (app *PlatformApp) getCompTransceiverPhysicalChannelStateLaserBiasCurrentFromDb(oc_val *ocbinds.OpenconfigPlatform_Components_Component_Transceiver_PhysicalChannels_Channel_State_LaserBiasCurrent, all bool, compName string, laneIndex uint16) error { + log.Infof("getCompTransceiverPhysicalChannelStateLaserBiasCurrentFromDb Enter compName=%s laneIndex=%d", compName, laneIndex) + + ifName := strings.Replace(compName, "transceiver_", "", -1) + compTransceiverPhysicalChannelStateLaserBiasCurrentDb := app.getCompTransceiverPhysicalChannelStateLaserBiasCurrentDbObj(ifName) + + targetUriPath, _ := getYangPathFromUri(app.path.Path) + + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/physical-channels/channel/state/laser-bias-current/instant" { + if int(laneIndex) < 8 { + fieldName := fmt.Sprintf("tx%dbias", laneIndex+1) + transceiverDomSensorTable := app.transceiverDomSensorTable[ifName].entry + if transceiverDomSensorTable.Has(fieldName) { + txbias := math.Floor(compTransceiverPhysicalChannelStateLaserBiasCurrentDb.TxBias[laneIndex]*fractionDigits2) / fractionDigits2 + oc_val.Instant = &txbias + } + } + } + + return nil +} + +type CompTransceiverThresholdStateDb struct { + TempHighAlarm float64 + TempLowAlarm float64 + VccHighAlarm float64 + VccLowAlarm float64 + TempHighWarning float64 + TempLowWarning float64 + VccHighWarning float64 + VccLowWarning float64 + TxPowerHighAlarm float64 + TxPowerLowAlarm float64 + RxPowerHighAlarm float64 + RxPowerLowAlarm float64 + TxBiasHighAlarm float64 + TxBiasLowAlarm float64 + TxPowerHighWarning float64 + TxPowerLowWarning float64 + RxPowerHighWarning float64 + RxPowerLowWarning float64 + TxBiasHighWarning float64 + TxBiasLowWarning float64 +} + +func (app *PlatformApp) getCompTransceiverThresholdStateDbObj(ifName string) CompTransceiverThresholdStateDb { + log.Infof("parseCompTransceiverThresholdStateDb Enter ifName=%s", ifName) + + var compTransceiverThresholdStateDbObj CompTransceiverThresholdStateDb + + transceiverDomThresholdTable, ok := app.getTransceiverDomThresholdEntry(ifName) + if !ok { + log.Warningf("getCompTransceiverThresholdStateDbObj: TRANSCEIVER_DOM_THRESHOLD entry missing for ifName=%s", ifName) + return compTransceiverThresholdStateDbObj + } + + compTransceiverThresholdStateDbObj.TempHighAlarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("temphighalarm"), 64) + compTransceiverThresholdStateDbObj.TempLowAlarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("templowalarm"), 64) + compTransceiverThresholdStateDbObj.VccHighAlarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("vcchighalarm"), 64) + compTransceiverThresholdStateDbObj.VccLowAlarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("vcclowalarm"), 64) + compTransceiverThresholdStateDbObj.TempHighWarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("temphighwarning"), 64) + compTransceiverThresholdStateDbObj.TempLowWarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("templowwarning"), 64) + compTransceiverThresholdStateDbObj.VccHighWarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("vcchighwarning"), 64) + compTransceiverThresholdStateDbObj.VccLowWarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("vcclowwarning"), 64) + compTransceiverThresholdStateDbObj.TxPowerHighAlarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("txpowerhighalarm"), 64) + compTransceiverThresholdStateDbObj.TxPowerLowAlarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("txpowerlowalarm"), 64) + compTransceiverThresholdStateDbObj.RxPowerHighAlarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("rxpowerhighalarm"), 64) + compTransceiverThresholdStateDbObj.RxPowerLowAlarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("rxpowerlowalarm"), 64) + compTransceiverThresholdStateDbObj.TxBiasHighAlarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("txbiashighalarm"), 64) + compTransceiverThresholdStateDbObj.TxBiasLowAlarm, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("txbiaslowalarm"), 64) + compTransceiverThresholdStateDbObj.TxPowerHighWarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("txpowerhighwarning"), 64) + compTransceiverThresholdStateDbObj.TxPowerLowWarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("txpowerlowwarning"), 64) + compTransceiverThresholdStateDbObj.RxPowerHighWarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("rxpowerhighwarning"), 64) + compTransceiverThresholdStateDbObj.RxPowerLowWarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("rxpowerlowwarning"), 64) + compTransceiverThresholdStateDbObj.TxBiasHighWarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("txbiashighwarning"), 64) + compTransceiverThresholdStateDbObj.TxBiasLowWarning, _ = strconv.ParseFloat(transceiverDomThresholdTable.Get("txbiaslowwarning"), 64) + + return compTransceiverThresholdStateDbObj +} + +func (app *PlatformApp) getCompTransceiverThresholdStateFromDb(oc_val *ocbinds.OpenconfigPlatform_Components_Component_Transceiver_Thresholds_Threshold_State, all bool, compName string, severityName string) error { + log.Infof("getCompTransceiverThresholdStateFromDb Enter compName=%s severityName=%s", compName, severityName) + + ifName := strings.Replace(compName, "transceiver_", "", -1) + compTransceiverThresholdStateDb := app.getCompTransceiverThresholdStateDbObj(ifName) + + targetUriPath, _ := getYangPathFromUri(app.path.Path) + + if severityName == "CRITICAL" { + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/laser-temperature-upper" { + transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry + if transceiverDomThresholdTable.Has("temphighalarm") { + temphighalarm := math.Floor(compTransceiverThresholdStateDb.TempHighAlarm*fractionDigits1) / fractionDigits1 + oc_val.LaserTemperatureUpper = &temphighalarm + } + } + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/laser-temperature-lower" { + transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry + if transceiverDomThresholdTable.Has("templowalarm") { + templowalarm := math.Floor(compTransceiverThresholdStateDb.TempLowAlarm*fractionDigits1) / fractionDigits1 + oc_val.LaserTemperatureLower = &templowalarm + } + } + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/supply-voltage-upper" { + transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry + if transceiverDomThresholdTable.Has("vcchighalarm") { + vcchighalarm := math.Floor(compTransceiverThresholdStateDb.VccHighAlarm*fractionDigits2) / fractionDigits2 + oc_val.SupplyVoltageUpper = &vcchighalarm + } + } + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/supply-voltage-lower" { + transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry + if transceiverDomThresholdTable.Has("vcclowalarm") { + vcclowalarm := math.Floor(compTransceiverThresholdStateDb.VccLowAlarm*fractionDigits2) / fractionDigits2 + oc_val.SupplyVoltageLower = &vcclowalarm + } + } + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/output-power-upper" { + transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry + if transceiverDomThresholdTable.Has("txpowerhighalarm") { + txpowerhighalarm := math.Floor(compTransceiverThresholdStateDb.TxPowerHighAlarm*fractionDigits2) / fractionDigits2 + oc_val.OutputPowerUpper = &txpowerhighalarm + } + } + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/output-power-lower" { + transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry + if transceiverDomThresholdTable.Has("txpowerlowalarm") { + txpowerlowalarm := math.Floor(compTransceiverThresholdStateDb.TxPowerLowAlarm*fractionDigits2) / fractionDigits2 + oc_val.OutputPowerLower = &txpowerlowalarm + } + } + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/input-power-upper" { + transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry + if transceiverDomThresholdTable.Has("rxpowerhighalarm") { + rxpowerhighalarm := math.Floor(compTransceiverThresholdStateDb.RxPowerHighAlarm*fractionDigits2) / fractionDigits2 + oc_val.InputPowerUpper = &rxpowerhighalarm + } + } + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/input-power-lower" { + transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry + if transceiverDomThresholdTable.Has("rxpowerlowalarm") { + rxpowerlowalarm := math.Floor(compTransceiverThresholdStateDb.RxPowerLowAlarm*fractionDigits2) / fractionDigits2 + oc_val.InputPowerLower = &rxpowerlowalarm + } + } + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/laser-bias-current-upper" { + transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry + if transceiverDomThresholdTable.Has("txbiashighalarm") { + txbiashighalarm := math.Floor(compTransceiverThresholdStateDb.TxBiasHighAlarm*fractionDigits2) / fractionDigits2 + oc_val.LaserBiasCurrentUpper = &txbiashighalarm + } + } + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/laser-bias-current-lower" { + transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry + if transceiverDomThresholdTable.Has("txbiaslowalarm") { + txbiaslowalarm := math.Floor(compTransceiverThresholdStateDb.TxBiasLowAlarm*fractionDigits2) / fractionDigits2 + oc_val.LaserBiasCurrentLower = &txbiaslowalarm + } + } + } + + if severityName == "WARNING" { + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/laser-temperature-upper" { + transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry + if transceiverDomThresholdTable.Has("temphighwarning") { + temphighwarning := math.Floor(compTransceiverThresholdStateDb.TempHighWarning*fractionDigits1) / fractionDigits1 + oc_val.LaserTemperatureUpper = &temphighwarning + } + } + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/laser-temperature-lower" { + transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry + if transceiverDomThresholdTable.Has("templowwarning") { + templowwarning := math.Floor(compTransceiverThresholdStateDb.TempLowWarning*fractionDigits1) / fractionDigits1 + oc_val.LaserTemperatureLower = &templowwarning + } + } + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/supply-voltage-upper" { + transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry + if transceiverDomThresholdTable.Has("vcchighwarning") { + vcchighwarning := math.Floor(compTransceiverThresholdStateDb.VccHighWarning*fractionDigits2) / fractionDigits2 + oc_val.SupplyVoltageUpper = &vcchighwarning + } + } + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/supply-voltage-lower" { + transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry + if transceiverDomThresholdTable.Has("vcclowwarning") { + vcclowwarning := math.Floor(compTransceiverThresholdStateDb.VccLowWarning*fractionDigits2) / fractionDigits2 + oc_val.SupplyVoltageLower = &vcclowwarning + } + } + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/output-power-upper" { + transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry + if transceiverDomThresholdTable.Has("txpowerhighwarning") { + v := math.Floor(compTransceiverThresholdStateDb.TxPowerHighWarning*fractionDigits2) / fractionDigits2 + oc_val.OutputPowerUpper = &v + } + } + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/output-power-lower" { + transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry + if transceiverDomThresholdTable.Has("txpowerlowwarning") { + v := math.Floor(compTransceiverThresholdStateDb.TxPowerLowWarning*fractionDigits2) / fractionDigits2 + oc_val.OutputPowerLower = &v + } + } + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/input-power-upper" { + transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry + if transceiverDomThresholdTable.Has("rxpowerhighwarning") { + v := math.Floor(compTransceiverThresholdStateDb.RxPowerHighWarning*fractionDigits2) / fractionDigits2 + oc_val.InputPowerUpper = &v + } + } + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/input-power-lower" { + transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry + if transceiverDomThresholdTable.Has("rxpowerlowwarning") { + v := math.Floor(compTransceiverThresholdStateDb.RxPowerLowWarning*fractionDigits2) / fractionDigits2 + oc_val.InputPowerLower = &v + } + } + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/laser-bias-current-upper" { + transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry + if transceiverDomThresholdTable.Has("txbiashighwarning") { + v := math.Floor(compTransceiverThresholdStateDb.TxBiasHighWarning*fractionDigits2) / fractionDigits2 + oc_val.LaserBiasCurrentUpper = &v + } + } + if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/thresholds/threshold/state/laser-bias-current-lower" { + transceiverDomThresholdTable := app.transceiverDomThresholdTable[ifName].entry + if transceiverDomThresholdTable.Has("txbiaslowwarning") { + v := math.Floor(compTransceiverThresholdStateDb.TxBiasLowWarning*fractionDigits2) / fractionDigits2 + oc_val.LaserBiasCurrentLower = &v + } + } + } + + return nil +} From 63425ec03fbc3191703b09eb3a3e7d1be5090103 Mon Sep 17 00:00:00 2001 From: Kanji Nakano Date: Mon, 25 May 2026 18:34:52 +0900 Subject: [PATCH 09/12] translib/pfm_app_transceiver: log voltage/temperature parse errors Address review comments on PR #201 (C07 line 689, C09 line 726): SupplyVoltage and LaserTemperature DbObj parsers ignored the error returned by strconv.ParseFloat, so a malformed STATE_DB value (anything that is not "N/A" but also not a parseable float) silently became the float64 zero value and was indistinguishable from a real 0.0 V / 0.0 C reading. Switch both parsers to the explicit form Copilot suggested: when parsing fails, log a Warning with the offending value and store math.NaN(). The "N/A" sentinel still maps directly to NaN as before, matching the FromDb consumer's existing Has() guard. Signed-off-by: Kanji Nakano --- translib/pfm_app_transceiver.go | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/translib/pfm_app_transceiver.go b/translib/pfm_app_transceiver.go index bc406b6e9..69354f03f 100644 --- a/translib/pfm_app_transceiver.go +++ b/translib/pfm_app_transceiver.go @@ -155,9 +155,13 @@ func (app *PlatformApp) getCompTransceiverStateSupplyVoltageDbObj(ifName string) return compTransceiverStateSupplyVoltageDbObj } - if transceiverDomSensorTable.Get("voltage") != "N/A" { - compTransceiverStateSupplyVoltageDbObj.voltage, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("voltage"), 64) + v := transceiverDomSensorTable.Get("voltage") + if v == "N/A" { + compTransceiverStateSupplyVoltageDbObj.voltage = math.NaN() + } else if parsed, err := strconv.ParseFloat(v, 64); err == nil { + compTransceiverStateSupplyVoltageDbObj.voltage = parsed } else { + log.Warningf("getCompTransceiverStateSupplyVoltageDbObj: ifName=%s field=voltage value=%q parse error: %v", ifName, v, err) compTransceiverStateSupplyVoltageDbObj.voltage = math.NaN() } @@ -199,9 +203,13 @@ func (app *PlatformApp) getCompTransceiverPhysicalChannelStateLaserTemperatureDb return compTransceiverPhysicalChannelStateLaserTemperatureDbObj } - if transceiverDomSensorTable.Get("temperature") != "N/A" { - compTransceiverPhysicalChannelStateLaserTemperatureDbObj.temperature, _ = strconv.ParseFloat(transceiverDomSensorTable.Get("temperature"), 64) + v := transceiverDomSensorTable.Get("temperature") + if v == "N/A" { + compTransceiverPhysicalChannelStateLaserTemperatureDbObj.temperature = math.NaN() + } else if parsed, err := strconv.ParseFloat(v, 64); err == nil { + compTransceiverPhysicalChannelStateLaserTemperatureDbObj.temperature = parsed } else { + log.Warningf("getCompTransceiverPhysicalChannelStateLaserTemperatureDbObj: ifName=%s field=temperature value=%q parse error: %v", ifName, v, err) compTransceiverPhysicalChannelStateLaserTemperatureDbObj.temperature = math.NaN() } From 2a55ec63d9477b2d6cca66688eedc0a67fe761d1 Mon Sep 17 00:00:00 2001 From: Kanji Nakano Date: Mon, 25 May 2026 18:37:12 +0900 Subject: [PATCH 10/12] translib/pfm_app: warn and skip on malformed lane id Address review comments on PR #201 (C20 line 1326, C21 line 1327): fourteen sites in doGetPlatformInfo iterate the comma-separated APPL_DB PORT_TABLE.lanes value and call strconv.ParseUint(lane, 10, 16) with the error discarded. On a malformed lane string the call returns 0, which the existing code then maps to lane index 0 and silently mis-attributes channel data to the wrong physical channel. An empty PORT_TABLE.lanes value (strings.Split returns [""]) hits the same path and ParseUint("") fails for the same reason. Capture ParseUint's error into a fresh local parseErr (not the function-level err, which the surrounding loop body uses to propagate FromDb failures via break), log it with the offending lane and ifName, and continue to the next entry. Empty-lanes is implicitly covered by the same continue (ParseUint on "" fails). Signed-off-by: Kanji Nakano --- translib/pfm_app.go | 84 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 70 insertions(+), 14 deletions(-) diff --git a/translib/pfm_app.go b/translib/pfm_app.go index 095d67e85..acb164e32 100644 --- a/translib/pfm_app.go +++ b/translib/pfm_app.go @@ -658,7 +658,11 @@ func (app *PlatformApp) doGetPlatformInfo() error { } for index, lane := range strings.Split(applPortTable.Get("lanes"), ",") { - laneNum, _ := strconv.ParseUint(lane, 10, 16) + laneNum, parseErr := strconv.ParseUint(lane, 10, 16) + if parseErr != nil { + log.Warningf("doGetPlatformInfo: invalid lane %q for ifName=%s: %v", lane, ifName, parseErr) + continue + } pf_channel, _ := pf_comp.Transceiver.PhysicalChannels.NewChannel(uint16(laneNum)) if pf_channel != nil { ygot.BuildEmptyTree(pf_channel) @@ -716,7 +720,11 @@ func (app *PlatformApp) doGetPlatformInfo() error { } for index, lane := range strings.Split(applPortTable.Get("lanes"), ",") { - laneNum, _ := strconv.ParseUint(lane, 10, 16) + laneNum, parseErr := strconv.ParseUint(lane, 10, 16) + if parseErr != nil { + log.Warningf("doGetPlatformInfo: invalid lane %q for ifName=%s: %v", lane, ifName, parseErr) + continue + } pf_channel, _ := pf_comp.Transceiver.PhysicalChannels.NewChannel(uint16(laneNum)) if pf_channel != nil { ygot.BuildEmptyTree(pf_channel) @@ -771,7 +779,11 @@ func (app *PlatformApp) doGetPlatformInfo() error { } for index, lane := range strings.Split(applPortTable.Get("lanes"), ",") { - laneNum, _ := strconv.ParseUint(lane, 10, 16) + laneNum, parseErr := strconv.ParseUint(lane, 10, 16) + if parseErr != nil { + log.Warningf("doGetPlatformInfo: invalid lane %q for ifName=%s: %v", lane, ifName, parseErr) + continue + } pf_channel, _ := pf_comp.Transceiver.PhysicalChannels.NewChannel(uint16(laneNum)) if pf_channel != nil { ygot.BuildEmptyTree(pf_channel) @@ -841,7 +853,11 @@ func (app *PlatformApp) doGetPlatformInfo() error { } for index, lane := range strings.Split(applPortTable.Get("lanes"), ",") { - laneNum, _ := strconv.ParseUint(lane, 10, 16) + laneNum, parseErr := strconv.ParseUint(lane, 10, 16) + if parseErr != nil { + log.Warningf("doGetPlatformInfo: invalid lane %q for ifName=%s: %v", lane, ifName, parseErr) + continue + } pf_channel, _ := pf_comp.Transceiver.PhysicalChannels.NewChannel(uint16(laneNum)) if pf_channel != nil { ygot.BuildEmptyTree(pf_channel) @@ -914,7 +930,11 @@ func (app *PlatformApp) doGetPlatformInfo() error { } for index, lane := range strings.Split(applPortTable.Get("lanes"), ",") { - laneNum, _ := strconv.ParseUint(lane, 10, 16) + laneNum, parseErr := strconv.ParseUint(lane, 10, 16) + if parseErr != nil { + log.Warningf("doGetPlatformInfo: invalid lane %q for ifName=%s: %v", lane, ifName, parseErr) + continue + } pf_channel, _ := pf_comp.Transceiver.PhysicalChannels.NewChannel(uint16(laneNum)) if pf_channel != nil { ygot.BuildEmptyTree(pf_channel) @@ -957,7 +977,11 @@ func (app *PlatformApp) doGetPlatformInfo() error { } for index, lane := range strings.Split(applPortTable.Get("lanes"), ",") { - laneNum, _ := strconv.ParseUint(lane, 10, 16) + laneNum, parseErr := strconv.ParseUint(lane, 10, 16) + if parseErr != nil { + log.Warningf("doGetPlatformInfo: invalid lane %q for ifName=%s: %v", lane, ifName, parseErr) + continue + } pf_channel, _ := pf_comp.Transceiver.PhysicalChannels.NewChannel(uint16(laneNum)) if pf_channel != nil { ygot.BuildEmptyTree(pf_channel) @@ -988,7 +1012,11 @@ func (app *PlatformApp) doGetPlatformInfo() error { } } else { for index, lane := range strings.Split(applPortTable.Get("lanes"), ",") { - laneNum, _ := strconv.ParseUint(lane, 10, 16) + laneNum, parseErr := strconv.ParseUint(lane, 10, 16) + if parseErr != nil { + log.Warningf("doGetPlatformInfo: invalid lane %q for ifName=%s: %v", lane, ifName, parseErr) + continue + } if uint16(laneNum) == uint16(compIndex) { pf_channel := pf_comp.Transceiver.PhysicalChannels.Channel[uint16(compIndex)] if pf_channel != nil { @@ -1040,7 +1068,11 @@ func (app *PlatformApp) doGetPlatformInfo() error { } } else { for index, lane := range strings.Split(applPortTable.Get("lanes"), ",") { - laneNum, _ := strconv.ParseUint(lane, 10, 16) + laneNum, parseErr := strconv.ParseUint(lane, 10, 16) + if parseErr != nil { + log.Warningf("doGetPlatformInfo: invalid lane %q for ifName=%s: %v", lane, ifName, parseErr) + continue + } if uint16(laneNum) == uint16(compIndex) { pf_channel := pf_comp.Transceiver.PhysicalChannels.Channel[uint16(compIndex)] if pf_channel != nil { @@ -1109,7 +1141,11 @@ func (app *PlatformApp) doGetPlatformInfo() error { applPortTable, _ := app.getApplPortEntry(ifName) for index, lane := range strings.Split(applPortTable.Get("lanes"), ",") { - laneNum, _ := strconv.ParseUint(lane, 10, 16) + laneNum, parseErr := strconv.ParseUint(lane, 10, 16) + if parseErr != nil { + log.Warningf("doGetPlatformInfo: invalid lane %q for ifName=%s: %v", lane, ifName, parseErr) + continue + } if uint16(laneNum) == uint16(compIndex) { pf_channel := pf_comp.Transceiver.PhysicalChannels.Channel[uint16(compIndex)] if pf_channel != nil { @@ -1142,7 +1178,11 @@ func (app *PlatformApp) doGetPlatformInfo() error { applPortTable, _ := app.getApplPortEntry(ifName) for index, lane := range strings.Split(applPortTable.Get("lanes"), ",") { - laneNum, _ := strconv.ParseUint(lane, 10, 16) + laneNum, parseErr := strconv.ParseUint(lane, 10, 16) + if parseErr != nil { + log.Warningf("doGetPlatformInfo: invalid lane %q for ifName=%s: %v", lane, ifName, parseErr) + continue + } if uint16(laneNum) == uint16(compIndex) { pf_channel := pf_comp.Transceiver.PhysicalChannels.Channel[uint16(compIndex)] if pf_channel != nil { @@ -1175,7 +1215,11 @@ func (app *PlatformApp) doGetPlatformInfo() error { applPortTable, _ := app.getApplPortEntry(ifName) for index, lane := range strings.Split(applPortTable.Get("lanes"), ",") { - laneNum, _ := strconv.ParseUint(lane, 10, 16) + laneNum, parseErr := strconv.ParseUint(lane, 10, 16) + if parseErr != nil { + log.Warningf("doGetPlatformInfo: invalid lane %q for ifName=%s: %v", lane, ifName, parseErr) + continue + } if uint16(laneNum) == uint16(compIndex) { pf_channel := pf_comp.Transceiver.PhysicalChannels.Channel[uint16(compIndex)] if pf_channel != nil { @@ -1313,7 +1357,11 @@ func (app *PlatformApp) doGetPlatformInfo() error { applPortTable, _ := app.getApplPortEntry(ifName) for index, lane := range strings.Split(applPortTable.Get("lanes"), ",") { - laneNum, _ := strconv.ParseUint(lane, 10, 16) + laneNum, parseErr := strconv.ParseUint(lane, 10, 16) + if parseErr != nil { + log.Warningf("doGetPlatformInfo: invalid lane %q for ifName=%s: %v", lane, ifName, parseErr) + continue + } if uint16(laneNum) == uint16(compIndex) { pf_channel := pf_comp.Transceiver.PhysicalChannels.Channel[uint16(compIndex)] if pf_channel != nil { @@ -1344,7 +1392,11 @@ func (app *PlatformApp) doGetPlatformInfo() error { applPortTable, _ := app.getApplPortEntry(ifName) for index, lane := range strings.Split(applPortTable.Get("lanes"), ",") { - laneNum, _ := strconv.ParseUint(lane, 10, 16) + laneNum, parseErr := strconv.ParseUint(lane, 10, 16) + if parseErr != nil { + log.Warningf("doGetPlatformInfo: invalid lane %q for ifName=%s: %v", lane, ifName, parseErr) + continue + } if uint16(laneNum) == uint16(compIndex) { pf_channel := pf_comp.Transceiver.PhysicalChannels.Channel[uint16(compIndex)] if pf_channel != nil { @@ -1375,7 +1427,11 @@ func (app *PlatformApp) doGetPlatformInfo() error { applPortTable, _ := app.getApplPortEntry(ifName) for index, lane := range strings.Split(applPortTable.Get("lanes"), ",") { - laneNum, _ := strconv.ParseUint(lane, 10, 16) + laneNum, parseErr := strconv.ParseUint(lane, 10, 16) + if parseErr != nil { + log.Warningf("doGetPlatformInfo: invalid lane %q for ifName=%s: %v", lane, ifName, parseErr) + continue + } if uint16(laneNum) == uint16(compIndex) { pf_channel := pf_comp.Transceiver.PhysicalChannels.Channel[uint16(compIndex)] if pf_channel != nil { From af589d20ed07c71ddfd1f51183bdeab8fac1ac2c Mon Sep 17 00:00:00 2001 From: Kanji Nakano Date: Mon, 25 May 2026 18:38:14 +0900 Subject: [PATCH 11/12] translib/pfm_app: propagate LaserBiasCurrent FromDb error Address review comment on PR #201 (C22): in doGetPlatformInfo the ten call sites of getCompTransceiverPhysicalChannelStateLaserBiasCurrentFromDb ignored the returned error, while the preceding calls to *OutputPower* and *InputPower* checked the same return and broke out of the enclosing loop. The asymmetry meant a bias-current fetch failure would silently leave the per-lane oc_val partially populated and let the outer for loop continue with stale or empty data. Mirror the existing pattern by checking err and breaking from the enclosing for loop on failure, so all three physical-channel getters now propagate errors consistently. Signed-off-by: Kanji Nakano --- translib/pfm_app.go | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/translib/pfm_app.go b/translib/pfm_app.go index acb164e32..6a1cc9b9e 100644 --- a/translib/pfm_app.go +++ b/translib/pfm_app.go @@ -675,6 +675,9 @@ func (app *PlatformApp) doGetPlatformInfo() error { break } err = app.getCompTransceiverPhysicalChannelStateLaserBiasCurrentFromDb(pf_channel.State.LaserBiasCurrent, true, compName, uint16(index)) + if err != nil { + break + } } } } @@ -737,6 +740,9 @@ func (app *PlatformApp) doGetPlatformInfo() error { break } err = app.getCompTransceiverPhysicalChannelStateLaserBiasCurrentFromDb(pf_channel.State.LaserBiasCurrent, true, compName, uint16(index)) + if err != nil { + break + } } } } @@ -796,6 +802,9 @@ func (app *PlatformApp) doGetPlatformInfo() error { break } err = app.getCompTransceiverPhysicalChannelStateLaserBiasCurrentFromDb(pf_channel.State.LaserBiasCurrent, true, compName, uint16(index)) + if err != nil { + break + } } } } @@ -870,6 +879,9 @@ func (app *PlatformApp) doGetPlatformInfo() error { break } err = app.getCompTransceiverPhysicalChannelStateLaserBiasCurrentFromDb(pf_channel.State.LaserBiasCurrent, true, compName, uint16(index)) + if err != nil { + break + } } } } else { @@ -947,6 +959,9 @@ func (app *PlatformApp) doGetPlatformInfo() error { break } err = app.getCompTransceiverPhysicalChannelStateLaserBiasCurrentFromDb(pf_channel.State.LaserBiasCurrent, true, compName, uint16(index)) + if err != nil { + break + } } } } else { @@ -994,6 +1009,9 @@ func (app *PlatformApp) doGetPlatformInfo() error { break } err = app.getCompTransceiverPhysicalChannelStateLaserBiasCurrentFromDb(pf_channel.State.LaserBiasCurrent, true, compName, uint16(index)) + if err != nil { + break + } } } } else { @@ -1030,6 +1048,9 @@ func (app *PlatformApp) doGetPlatformInfo() error { break } err = app.getCompTransceiverPhysicalChannelStateLaserBiasCurrentFromDb(pf_channel.State.LaserBiasCurrent, true, compName, uint16(index)) + if err != nil { + break + } } else { err = errors.New("Invalid input component index") } @@ -1086,6 +1107,9 @@ func (app *PlatformApp) doGetPlatformInfo() error { break } err = app.getCompTransceiverPhysicalChannelStateLaserBiasCurrentFromDb(pf_channel.State.LaserBiasCurrent, true, compName, uint16(index)) + if err != nil { + break + } } else { err = errors.New("Invalid input component index") } @@ -1225,6 +1249,9 @@ func (app *PlatformApp) doGetPlatformInfo() error { if pf_channel != nil { ygot.BuildEmptyTree(pf_channel.State) err = app.getCompTransceiverPhysicalChannelStateLaserBiasCurrentFromDb(pf_channel.State.LaserBiasCurrent, true, compName, uint16(index)) + if err != nil { + break + } } else { err = errors.New("Invalid input component index") } @@ -1437,6 +1464,9 @@ func (app *PlatformApp) doGetPlatformInfo() error { if pf_channel != nil { ygot.BuildEmptyTree(pf_channel.State) err = app.getCompTransceiverPhysicalChannelStateLaserBiasCurrentFromDb(pf_channel.State.LaserBiasCurrent, false, compName, uint16(index)) + if err != nil { + break + } } else { err = errors.New("Invalid input component index") } From 19d9ab6dad7b072bab40991a291bc23dd9b4cac0 Mon Sep 17 00:00:00 2001 From: Kanji Nakano Date: Mon, 25 May 2026 18:39:13 +0900 Subject: [PATCH 12/12] translib/pfm_app_transceiver: validate date-code via time.Parse Address review comment on PR #201 (C05): the date-code extractor applied a YYYY-MM-DD regex that constrained month to 01-12 and day to 01-31 but did NOT validate the day against the actual length of the month. Calendar impossibilities such as 2024-02-30 or 2024-04-31 passed validation and were emitted unchanged to oc_val.DateCode. Replace the second regex-based validation with time.Parse on the "2006-01-02" layout, which natively rejects month/day combinations that do not exist. On success, reformat to the existing RFC 3339-ish output (...T00:00:00.000Z); on failure log a warning with the original string and skip the field, matching the prior behavior of leaving DateCode unset for unparseable input. The leading regex that extracts three digit groups from the raw STATE_DB value is retained because xcvrd writes vendor_date with a trailing time portion (e.g. "2024-01-01 00:00:00") and the extraction is the simplest tolerant way to pick out the date prefix. Signed-off-by: Kanji Nakano --- translib/pfm_app_transceiver.go | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/translib/pfm_app_transceiver.go b/translib/pfm_app_transceiver.go index 69354f03f..d0191cc79 100644 --- a/translib/pfm_app_transceiver.go +++ b/translib/pfm_app_transceiver.go @@ -31,6 +31,7 @@ import ( "regexp" "strconv" "strings" + "time" "github.com/Azure/sonic-mgmt-common/translib/ocbinds" log "github.com/golang/glog" @@ -122,15 +123,20 @@ func (app *PlatformApp) getCompTransceiverStateFromDb(oc_val *ocbinds.Openconfig if all || targetUriPath == "/openconfig-platform:components/component/openconfig-platform-transceiver:transceiver/state/date-code" { transceiverInfoTable := app.transceiverInfoTable[ifName].entry if transceiverInfoTable.Has("vendor_date") { + // xcvrd writes vendor_date as a string with a YYYY-MM-DD prefix + // (followed by an optional time portion). Pull the leading three + // digit groups and feed them through time.Parse so a calendar + // impossibility such as Feb 30 is rejected rather than passed + // through the previous regex which accepted any 30/31-day month. rex := regexp.MustCompile("[0-9]+") subMatchString := rex.FindAllString(compTransceiverStateDb.VendorDate, -1) - if len(subMatchString) >= 3 { - if len(subMatchString[0]) == 4 && len(subMatchString[1]) == 2 && len(subMatchString[2]) == 2 { - vendorDate := fmt.Sprintf("%s-%s-%sT00:00:00.000Z", subMatchString[0], subMatchString[1], subMatchString[2]) - formatMatch, _ := regexp.MatchString("[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])[Tt]00:00:00\\.000Z", vendorDate) - if formatMatch { - oc_val.DateCode = &vendorDate - } + if len(subMatchString) >= 3 && len(subMatchString[0]) == 4 && len(subMatchString[1]) == 2 && len(subMatchString[2]) == 2 { + rawDate := fmt.Sprintf("%s-%s-%s", subMatchString[0], subMatchString[1], subMatchString[2]) + if t, err := time.Parse("2006-01-02", rawDate); err == nil { + vendorDate := t.UTC().Format("2006-01-02T15:04:05.000Z") + oc_val.DateCode = &vendorDate + } else { + log.Warningf("getCompTransceiverStateFromDb: invalid date-code %q for ifName=%s: %v", compTransceiverStateDb.VendorDate, ifName, err) } } }