[VOL-4773] openonuAdapterGo: voltctl command to show ONU OMCI counter statistics
Change-Id: Id42a414333e293e4347e3e76d652fc1ec90723fe
diff --git a/internal/pkg/common/omci_cc.go b/internal/pkg/common/omci_cc.go
index a47ca1a..60d37e5 100755
--- a/internal/pkg/common/omci_cc.go
+++ b/internal/pkg/common/omci_cc.go
@@ -40,6 +40,7 @@
"github.com/opencord/voltha-lib-go/v7/pkg/log"
"github.com/opencord/voltha-protos/v5/go/common"
+ "github.com/opencord/voltha-protos/v5/go/extension"
ia "github.com/opencord/voltha-protos/v5/go/inter_adapter"
)
@@ -99,6 +100,13 @@
OnuSwWindow *ia.OmciMessages
}
+type txRxCounters struct {
+ txArFrames uint32
+ txNoArFrames uint32
+ rxAkFrames uint32
+ rxNoAkFrames uint32
+}
+
//OmciCC structure holds information needed for OMCI communication (to/from OLT Adapter)
type OmciCC struct {
enabled bool
@@ -110,8 +118,11 @@
supportExtMsg bool
rxOmciFrameError tOmciReceiveError
- txFrames, txOnuFrames uint32
- rxFrames, rxOnuFrames, rxOnuDiscards uint32
+ mutexCounters sync.RWMutex
+ countersBase txRxCounters
+ countersExt txRxCounters
+ txRetries uint32
+ txTimeouts uint32
// OMCI params
mutexTid sync.Mutex
@@ -157,11 +168,10 @@
omciCC.coreClient = coreClient
omciCC.supportExtMsg = false
omciCC.rxOmciFrameError = cOmciMessageReceiveNoError
- omciCC.txFrames = 0
- omciCC.txOnuFrames = 0
- omciCC.rxFrames = 0
- omciCC.rxOnuFrames = 0
- omciCC.rxOnuDiscards = 0
+ omciCC.countersBase = txRxCounters{0, 0, 0, 0}
+ omciCC.countersExt = txRxCounters{0, 0, 0, 0}
+ omciCC.txRetries = 0
+ omciCC.txTimeouts = 0
omciCC.tid = 0x1
omciCC.hpTid = 0x8000
omciCC.UploadSequNo = 0
@@ -204,13 +214,14 @@
oo.UploadSequNo = 0
oo.UploadNoOfCmds = 0
oo.rxOmciFrameError = cOmciMessageReceiveNoError
- //reset the stats counter - which might be topic of discussion ...
- oo.txFrames = 0
- oo.txOnuFrames = 0
- oo.rxFrames = 0
- oo.rxOnuFrames = 0
- oo.rxOnuDiscards = 0
+ //reset the stats counter
+ oo.mutexCounters.Lock()
+ oo.countersBase = txRxCounters{0, 0, 0, 0}
+ oo.countersExt = txRxCounters{0, 0, 0, 0}
+ oo.txRetries = 0
+ oo.txTimeouts = 0
+ oo.mutexCounters.Unlock()
return nil
}
@@ -389,6 +400,11 @@
oo.printRxMessage(ctx, rxMsg)
logger.Debugw(ctx, "RxMsg is no Omci Response Message", log.Fields{"device-id": oo.deviceID})
if omciMsg.TransactionID == 0 {
+ if rxMsg[cOmciDeviceIdentifierPos] == byte(omci.BaselineIdent) {
+ oo.incrementBaseRxNoAkFrames()
+ } else {
+ oo.incrementExtRxNoAkFrames()
+ }
return oo.receiveOnuMessage(ctx, omciMsg, &packet)
}
logger.Errorw(ctx, "Unexpected TransCorrId != 0 not accepted for autonomous messages",
@@ -403,6 +419,11 @@
if rxCallbackEntry.FramePrint {
oo.printRxMessage(ctx, rxMsg)
}
+ if rxMsg[cOmciDeviceIdentifierPos] == byte(omci.BaselineIdent) {
+ oo.incrementBaseRxAkFrames()
+ } else {
+ oo.incrementExtRxAkFrames()
+ }
//disadvantage of decoupling: error verification made difficult, but anyway the question is
// how to react on erroneous frame reception, maybe can simply be ignored
go rxCallbackEntry.CbFunction(ctx, omciMsg, &packet, rxCallbackEntry.CbRespChannel)
@@ -688,6 +709,11 @@
logger.Errorw(ctx, "send omci request error", log.Fields{"device-id": oo.deviceID, "ChildId": oo.deviceID, "error": sendErr})
return sendErr
}
+ if omciTxRequest.txFrame[cOmciDeviceIdentifierPos] == byte(omci.BaselineIdent) {
+ oo.incrementBaseTxArFrames()
+ } else {
+ oo.incrementExtTxArFrames()
+ }
return nil
}
@@ -4440,10 +4466,12 @@
logger.Errorw(ctx, "reqMon: timeout waiting for response - no of max retries reached - send ONU device event!",
log.Fields{"tid": tid, "retries": retryCounter, "device-id": oo.deviceID})
oo.pOnuDeviceEntry.SendOnuDeviceEvent(ctx, OnuOmciCommunicationFailureSwUpgrade, OnuOmciCommunicationFailureSwUpgradeDesc)
+ oo.incrementTxTimesouts()
break loop
} else {
logger.Infow(ctx, "reqMon: timeout waiting for response - retry",
log.Fields{"tid": tid, "retries": retryCounter, "device-id": oo.deviceID})
+ oo.incrementTxRetries()
}
}
retryCounter++
@@ -4454,9 +4482,15 @@
}
func (oo *OmciCC) sendOnuSwSectionsOfWindow(ctx context.Context, omciTxRequest OmciTransferStructure) error {
- if omciTxRequest.withFramePrint && omciTxRequest.OnuSwWindow != nil {
- lastSection := omciTxRequest.OnuSwWindow.Messages[len(omciTxRequest.OnuSwWindow.Messages)-1]
- logger.Debugw(ctx, "omci-message-to-send:", log.Fields{
+ var lastSection []byte
+ if omciTxRequest.OnuSwWindow != nil {
+ lastSection = omciTxRequest.OnuSwWindow.Messages[len(omciTxRequest.OnuSwWindow.Messages)-1]
+ } else {
+ logger.Errorw(ctx, "invalid sw window received", log.Fields{"device-id": oo.deviceID})
+ return fmt.Errorf("invalid sw window received")
+ }
+ if omciTxRequest.withFramePrint {
+ logger.Debugw(ctx, "sw-section-omci-message-to-send:", log.Fields{
"TxOmciMessage": hex.EncodeToString(lastSection),
"device-id": oo.deviceID,
"toDeviceType": oo.pBaseDeviceHandler.GetProxyAddressType(),
@@ -4465,9 +4499,17 @@
}
sendErr := oo.pBaseDeviceHandler.SendOnuSwSectionsOfWindow(ctx, oo.pBaseDeviceHandler.GetProxyAddress().AdapterEndpoint, omciTxRequest.OnuSwWindow)
if sendErr != nil {
- logger.Errorw(ctx, "send onu sw sections omci request error", log.Fields{"ChildId": oo.deviceID, "error": sendErr})
+ logger.Errorw(ctx, "send onu sw sections omci request error", log.Fields{"device-id": oo.deviceID, "error": sendErr})
return sendErr
}
+ numberOfNoArSections := len(omciTxRequest.OnuSwWindow.Messages) - 1 // last section of window is sent with AR expected
+ if lastSection[cOmciDeviceIdentifierPos] == byte(omci.BaselineIdent) {
+ oo.increaseBaseTxNoArFramesBy(ctx, uint32(numberOfNoArSections))
+ oo.incrementBaseTxArFrames()
+ } else {
+ oo.increaseExtTxNoArFramesBy(ctx, uint32(numberOfNoArSections))
+ oo.incrementExtTxArFrames()
+ }
return nil
}
@@ -4927,10 +4969,12 @@
logger.Errorw(ctx, "reqMon: timeout waiting for response - no of max retries reached - send ONU device event!",
log.Fields{"tid": tid, "retries": retryCounter, "device-id": oo.deviceID})
oo.pOnuDeviceEntry.SendOnuDeviceEvent(ctx, OnuOmciCommunicationFailureConfig, OnuOmciCommunicationFailureConfigDesc)
+ oo.incrementTxTimesouts()
break loop
} else {
logger.Infow(ctx, "reqMon: timeout waiting for response - retry",
log.Fields{"tid": tid, "retries": retryCounter, "device-id": oo.deviceID})
+ oo.incrementTxRetries()
}
}
retryCounter++
@@ -5102,3 +5146,90 @@
oo.pOnuDeviceEntry = nil
oo.pOnuAlarmManager = nil
}
+
+// GetOmciCounters - TODO: add comment
+func (oo *OmciCC) GetOmciCounters() *extension.SingleGetValueResponse {
+ oo.mutexCounters.RLock()
+ defer oo.mutexCounters.RUnlock()
+ resp := extension.SingleGetValueResponse{
+ Response: &extension.GetValueResponse{
+ Status: extension.GetValueResponse_OK,
+ Response: &extension.GetValueResponse_OnuOmciStats{
+ OnuOmciStats: &extension.GetOnuOmciTxRxStatsResponse{},
+ },
+ },
+ }
+ resp.Response.GetOnuOmciStats().BaseTxArFrames = oo.countersBase.txArFrames
+ resp.Response.GetOnuOmciStats().BaseTxNoArFrames = oo.countersBase.txNoArFrames
+ resp.Response.GetOnuOmciStats().BaseRxAkFrames = oo.countersBase.rxAkFrames
+ resp.Response.GetOnuOmciStats().BaseRxNoAkFrames = oo.countersBase.rxNoAkFrames
+ resp.Response.GetOnuOmciStats().ExtTxArFrames = oo.countersExt.txArFrames
+ resp.Response.GetOnuOmciStats().ExtTxNoArFrames = oo.countersExt.txNoArFrames
+ resp.Response.GetOnuOmciStats().ExtRxAkFrames = oo.countersExt.rxAkFrames
+ resp.Response.GetOnuOmciStats().ExtRxNoAkFrames = oo.countersExt.rxNoAkFrames
+ resp.Response.GetOnuOmciStats().TxOmciCounterRetries = oo.txRetries
+ resp.Response.GetOnuOmciStats().TxOmciCounterTimeouts = oo.txTimeouts
+ return &resp
+}
+
+// For more speed, separate functions for each counter
+
+func (oo *OmciCC) incrementBaseTxArFrames() {
+ oo.mutexCounters.Lock()
+ defer oo.mutexCounters.Unlock()
+ oo.countersBase.txArFrames++
+}
+
+func (oo *OmciCC) incrementExtTxArFrames() {
+ oo.mutexCounters.Lock()
+ defer oo.mutexCounters.Unlock()
+ oo.countersExt.txArFrames++
+}
+
+func (oo *OmciCC) incrementBaseRxAkFrames() {
+ oo.mutexCounters.Lock()
+ defer oo.mutexCounters.Unlock()
+ oo.countersBase.rxAkFrames++
+}
+
+func (oo *OmciCC) incrementExtRxAkFrames() {
+ oo.mutexCounters.Lock()
+ defer oo.mutexCounters.Unlock()
+ oo.countersExt.rxAkFrames++
+}
+
+func (oo *OmciCC) increaseBaseTxNoArFramesBy(ctx context.Context, value uint32) {
+ oo.mutexCounters.Lock()
+ defer oo.mutexCounters.Unlock()
+ oo.countersBase.txNoArFrames += value
+}
+
+func (oo *OmciCC) increaseExtTxNoArFramesBy(ctx context.Context, value uint32) {
+ oo.mutexCounters.Lock()
+ defer oo.mutexCounters.Unlock()
+ oo.countersExt.txNoArFrames += value
+}
+
+func (oo *OmciCC) incrementBaseRxNoAkFrames() {
+ oo.mutexCounters.Lock()
+ defer oo.mutexCounters.Unlock()
+ oo.countersBase.rxNoAkFrames++
+}
+
+func (oo *OmciCC) incrementExtRxNoAkFrames() {
+ oo.mutexCounters.Lock()
+ defer oo.mutexCounters.Unlock()
+ oo.countersExt.rxNoAkFrames++
+}
+
+func (oo *OmciCC) incrementTxRetries() {
+ oo.mutexCounters.Lock()
+ defer oo.mutexCounters.Unlock()
+ oo.txRetries++
+}
+
+func (oo *OmciCC) incrementTxTimesouts() {
+ oo.mutexCounters.Lock()
+ defer oo.mutexCounters.Unlock()
+ oo.txTimeouts++
+}
diff --git a/internal/pkg/core/device_handler.go b/internal/pkg/core/device_handler.go
index e6236fc..ddbfe7a 100755
--- a/internal/pkg/core/device_handler.go
+++ b/internal/pkg/core/device_handler.go
@@ -3825,6 +3825,32 @@
return resp
}
+func (dh *deviceHandler) getOnuOMCIStats(ctx context.Context) (*extension.SingleGetValueResponse, error) {
+
+ var err error
+ var pDevOmciCC *cmn.OmciCC
+ if dh.pOnuOmciDevice == nil {
+ logger.Errorw(ctx, "No valid DeviceEntry", log.Fields{"device-id": dh.DeviceID})
+ err = fmt.Errorf("no-valid-DeviceEntry-%s", dh.DeviceID)
+ } else {
+ pDevOmciCC = dh.pOnuOmciDevice.GetDevOmciCC()
+ if pDevOmciCC == nil {
+ logger.Errorw(ctx, "No valid DeviceOmciCCEntry", log.Fields{"device-id": dh.DeviceID})
+ err = fmt.Errorf("no-valid-DeviceOmciCCEntry-%s", dh.DeviceID)
+ }
+ }
+ if err != nil {
+ return &extension.SingleGetValueResponse{
+ Response: &extension.GetValueResponse{
+ Status: extension.GetValueResponse_ERROR,
+ ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
+ },
+ },
+ err
+ }
+ return pDevOmciCC.GetOmciCounters(), nil
+}
+
func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, PFsm *fsm.FSM, wantedState string) bool {
if PFsm == nil {
return true //FSM not active - so there is no activity on omci
diff --git a/internal/pkg/core/openonu.go b/internal/pkg/core/openonu.go
index 96c13aa..1995a9a 100755
--- a/internal/pkg/core/openonu.go
+++ b/internal/pkg/core/openonu.go
@@ -483,9 +483,10 @@
return &resp, nil
case *extension.GetValueRequest_OnuInfo:
return handler.getOnuOMCICounters(ctx, reqType.OnuInfo), nil
+ case *extension.GetValueRequest_OnuOmciStats:
+ return handler.getOnuOMCIStats(ctx)
default:
return uniprt.PostUniStatusErrResponse(extension.GetValueResponse_UNSUPPORTED), nil
-
}
}
logger.Errorw(ctx, "Single_get_value_request failed ", log.Fields{"request": request})
diff --git a/internal/pkg/mib/onu_device_entry.go b/internal/pkg/mib/onu_device_entry.go
index ff12c1c..0f39467 100755
--- a/internal/pkg/mib/onu_device_entry.go
+++ b/internal/pkg/mib/onu_device_entry.go
@@ -544,7 +544,8 @@
oo.MutexPersOnuConfig.Lock()
defer oo.MutexPersOnuConfig.Unlock()
oo.SOnuPersistentData =
- onuPersistentData{0, 0, "", "", "", "", "", false, "", "", "", false, false, oo.mibAuditInterval, 0, 0, make([]uniPersConfig, 0), oo.alarmAuditInterval, make(map[uint16]uint16)}
+ onuPersistentData{0, 0, "", "", "", "", "", false, "", "", "", false, false, oo.mibAuditInterval, 0, 0,
+ make([]uniPersConfig, 0), oo.alarmAuditInterval, make(map[uint16]uint16)}
oo.mutexOnuKVStore.RLock()
Value, err := oo.onuKVStore.Get(ctx, oo.onuKVStorePath)
oo.mutexOnuKVStore.RUnlock()
@@ -599,7 +600,8 @@
oo.SOnuPersistentData.PersUniConfig = nil //releasing all UniConfig entries to garbage collector default entry
oo.SOnuPersistentData =
- onuPersistentData{0, 0, "", "", "", "", "", false, "", "", "", false, false, oo.mibAuditInterval, 0, 0, make([]uniPersConfig, 0), oo.alarmAuditInterval, make(map[uint16]uint16)}
+ onuPersistentData{0, 0, "", "", "", "", "", false, "", "", "", false, false, oo.mibAuditInterval, 0, 0,
+ make([]uniPersConfig, 0), oo.alarmAuditInterval, make(map[uint16]uint16)}
logger.Debugw(ctx, "delete ONU-data from KVStore", log.Fields{"device-id": oo.deviceID})
oo.mutexOnuKVStore.Lock()
err := oo.onuKVStore.Delete(ctx, oo.onuKVStorePath)