VOL-4029 fetch extended pm counters

Change-Id: Ic5e0624a47c4f35a0013045722a25693bcd8f008
diff --git a/VERSION b/VERSION
index d8c5e72..15d45d4 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.6.8
+1.6.9
diff --git a/internal/pkg/commands/devices.go b/internal/pkg/commands/devices.go
index dd687a1..0bcda77 100644
--- a/internal/pkg/commands/devices.go
+++ b/internal/pkg/commands/devices.go
@@ -79,6 +79,34 @@
 	STATUS: {{.Status}}
 	FAIL_REASON: {{.FailReason}}
 	RX_POWER : {{.RxPower}}`
+	DEFAULT_ETHERNET_FRAME_EXTENDED_PM_COUNTERS_FORMAT = `Upstream_Drop_Events:	        {{.UDropEvents}}
+Upstream_Octets:	        {{.UOctets}}
+UFrames:	                {{.UFrames}}
+UBroadcastFrames:	        {{.UBroadcastFrames}}
+UMulticastFrames:	        {{.UMulticastFrames}}
+UCrcErroredFrames:	        {{.UCrcErroredFrames}}
+UUndersizeFrames:	        {{.UUndersizeFrames}}
+UOversizeFrames:	        {{.UOversizeFrames}}
+UFrames_64Octets:	        {{.UFrames_64Octets}}
+UFrames_65To_127Octets:	        {{.UFrames_65To_127Octets}}
+UFrames_128To_255Octets:	{{.UFrames_128To_255Octets}}
+UFrames_256To_511Octets:	{{.UFrames_256To_511Octets}}
+UFrames_512To_1023Octets:	{{.UFrames_512To_1023Octets}}
+UFrames_1024To_1518Octets:	{{.UFrames_1024To_1518Octets}}
+DDropEvents:	                {{.DDropEvents}}
+DOctets:	                {{.DOctets}}
+DFrames:	                {{.DFrames}}
+DBroadcastFrames:	        {{.DBroadcastFrames}}
+DMulticastFrames:	        {{.DMulticastFrames}}
+DCrcErroredFrames:	        {{.DCrcErroredFrames}}
+DUndersizeFrames:	        {{.DUndersizeFrames}}
+DOversizeFrames:	        {{.DOversizeFrames}}
+DFrames_64Octets:	        {{.DFrames_64Octets}}
+DFrames_65To_127Octets:	        {{.DFrames_65To_127Octets}}
+DFrames_128To_255Octets:	{{.DFrames_128To_255Octets}}
+DFrames_256To_511Octets:	{{.DFrames_256To_511Octets}}
+DFrames_512To_1023Octets:	{{.DFrames_512To_1023Octets}}
+DFrames_1024To_1518Octets:	{{.DFrames_1024To_1518Octets}}`
 )
 
 type DeviceList struct {
@@ -368,6 +396,13 @@
 	} `positional-args:"yes"`
 }
 
+type GetOnuEthernetFrameExtendedPmCounters struct {
+	ListOutputOptions
+	Args struct {
+		Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
+	} `positional-args:"yes"`
+}
+
 type RxPower struct {
 	ListOutputOptions
 	Args struct {
@@ -432,11 +467,12 @@
 		List         OnuListImages        `command:"list" `
 	} `command:"onuimage"`
 	GetExtVal struct {
-		Stats       DeviceGetPortStats `command:"portstats"`
-		UniStatus   UniStatus          `command:"unistatus"`
-		OpticalInfo OnuPonOpticalInfo  `command:"onu_pon_optical_info"`
-		OnuStats    GetOnuStats        `command:"onu_stats"`
-		RxPower     RxPower            `command:"rxpower"`
+		Stats                   DeviceGetPortStats                    `command:"portstats"`
+		UniStatus               UniStatus                             `command:"unistatus"`
+		OpticalInfo             OnuPonOpticalInfo                     `command:"onu_pon_optical_info"`
+		OnuStats                GetOnuStats                           `command:"onu_stats"`
+		EthernetFrameExtendedPm GetOnuEthernetFrameExtendedPmCounters `command:"ethernet_frame_extended_pm"`
+		RxPower                 RxPower                               `command:"rxpower"`
 	} `command:"getextval"`
 }
 
@@ -2013,7 +2049,50 @@
 	if outputFormat == "" {
 		outputFormat = GetCommandOptionWithDefault("device-get-onu-status", "format", formatStr)
 	}
+	result := CommandResult{
+		Format:    format.Format(outputFormat),
+		OutputAs:  toOutputType(options.OutputAs),
+		NameLimit: options.NameLimit,
+		Data:      data,
+	}
+	GenerateOutput(&result)
+	return nil
+}
 
+func (options *GetOnuEthernetFrameExtendedPmCounters) Execute(args []string) error {
+	conn, err := NewConnection()
+	if err != nil {
+		return err
+	}
+	defer conn.Close()
+	client := extension.NewExtensionClient(conn)
+
+	singleGetValReq := extension.SingleGetValueRequest{
+		TargetId: string(options.Args.Id),
+		Request: &extension.GetValueRequest{
+			Request: &extension.GetValueRequest_OnuInfo{
+				OnuInfo: &extension.GetOmciEthernetFrameExtendedPmRequest{
+					OnuDeviceId: string(options.Args.Id),
+				},
+			},
+		},
+	}
+	ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
+	defer cancel()
+	rv, err := client.GetExtValue(ctx, &singleGetValReq)
+	if err != nil {
+		Error.Printf("Error getting value on device Id %s,err=%s\n", options.Args.Id, ErrorToString(err))
+		return err
+	}
+
+	if rv.Response.Status != extension.GetValueResponse_OK {
+		return fmt.Errorf("failed to get ethernet frame extended pm counters %v", rv.Response.ErrReason.String())
+	}
+	outputFormat := CharReplacer.Replace(options.Format)
+	data := buildOnuEthernetFrameExtendedPmOutputFormat(rv.GetResponse().GetOnuCounters())
+	if outputFormat == "" {
+		outputFormat = GetCommandOptionWithDefault("device-get-onu-status", "format", DEFAULT_ETHERNET_FRAME_EXTENDED_PM_COUNTERS_FORMAT)
+	}
 	result := CommandResult{
 		Format:    format.Format(outputFormat),
 		OutputAs:  toOutputType(options.OutputAs),
diff --git a/internal/pkg/commands/stats.go b/internal/pkg/commands/stats.go
index e77aa75..8b84a0a 100644
--- a/internal/pkg/commands/stats.go
+++ b/internal/pkg/commands/stats.go
@@ -16,6 +16,7 @@
 package commands
 
 import (
+	"fmt"
 	"github.com/opencord/voltctl/pkg/model"
 	"github.com/opencord/voltha-protos/v4/go/extension"
 	"strings"
@@ -37,16 +38,15 @@
 }
 func (t *tagBuilder) addFieldInFormat(name string) {
 	if !t.firstField {
-		t.tag.WriteString("\t")
+		t.tag.WriteString("\n")
 	}
 	t.firstField = false
+	str := fmt.Sprintf("%s:    ", name)
+	t.tag.WriteString(str)
 	t.tag.WriteString("{{.")
 	t.tag.WriteString(name)
 	t.tag.WriteString("}}")
 }
-func (t *tagBuilder) addTableInFormat() {
-	t.tag.WriteString("table")
-}
 
 /*
  * Construct a template format string based on the fields required by the
@@ -55,7 +55,6 @@
 func buildOnuStatsOutputFormat(counters *extension.GetOnuCountersResponse) (model.OnuStats, string) {
 	onuStats := model.OnuStats{}
 	tagBuilder := NewTagBuilder()
-	tagBuilder.addTableInFormat()
 	if counters.IsIntfId != nil {
 		intfId := counters.GetIntfId()
 		onuStats.IntfId = &intfId
@@ -193,3 +192,96 @@
 	}
 	return onuStats, tagBuilder.buildOutputString()
 }
+
+/*
+ * Construct a template format string based on the fields required by the
+ * results.
+ */
+func buildOnuEthernetFrameExtendedPmOutputFormat(counters *extension.GetOmciEthernetFrameExtendedPmResponse) model.OnuEthernetFrameExtendedPm {
+	onuStats := model.OnuEthernetFrameExtendedPm{}
+
+	dropEvents := counters.Upstream.GetDropEvents()
+	onuStats.UDropEvents = &dropEvents
+
+	octets := counters.Upstream.GetOctets()
+	onuStats.UOctets = &octets
+
+	frames := counters.Upstream.GetFrames()
+	onuStats.UFrames = &frames
+
+	broadcastFrames := counters.Upstream.GetBroadcastFrames()
+	onuStats.UBroadcastFrames = &broadcastFrames
+
+	multicastFrames := counters.Upstream.GetMulticastFrames()
+	onuStats.UMulticastFrames = &multicastFrames
+
+	crcErroredFrames := counters.Upstream.GetCrcErroredFrames()
+	onuStats.UCrcErroredFrames = &crcErroredFrames
+
+	undersizeFrames := counters.Upstream.GetUndersizeFrames()
+	onuStats.UUndersizeFrames = &undersizeFrames
+
+	oversizeFrames := counters.Upstream.GetOversizeFrames()
+	onuStats.UOversizeFrames = &oversizeFrames
+
+	frames_64Octets := counters.Upstream.GetFrames_64Octets()
+	onuStats.UFrames_64Octets = &frames_64Octets
+
+	frames_65To_127Octets := counters.Upstream.GetFrames_65To_127Octets()
+	onuStats.UFrames_65To_127Octets = &frames_65To_127Octets
+
+	frames_128To_255Octets := counters.Upstream.GetFrames_128To_255Octets()
+	onuStats.UFrames_128To_255Octets = &frames_128To_255Octets
+
+	frames_256To_511Octets := counters.Upstream.GetFrames_256To_511Octets()
+	onuStats.UFrames_256To_511Octets = &frames_256To_511Octets
+
+	frames_512To_1023Octets := counters.Upstream.GetFrames_512To_1023Octets()
+	onuStats.UFrames_512To_1023Octets = &frames_512To_1023Octets
+
+	frames_1024To_1518Octets := counters.Upstream.GetFrames_1024To_1518Octets()
+	onuStats.UFrames_1024To_1518Octets = &frames_1024To_1518Octets
+
+	dDropEvents := counters.Downstream.GetDropEvents()
+	onuStats.DDropEvents = &dDropEvents
+
+	dOctets := counters.Downstream.GetOctets()
+	onuStats.DOctets = &dOctets
+
+	dFrames := counters.Downstream.GetFrames()
+	onuStats.DFrames = &dFrames
+
+	dBroadcastFrames := counters.Downstream.GetBroadcastFrames()
+	onuStats.DBroadcastFrames = &dBroadcastFrames
+
+	dMulticastFrames := counters.Downstream.GetMulticastFrames()
+	onuStats.DMulticastFrames = &dMulticastFrames
+
+	dCrcErroredFrames := counters.Downstream.GetCrcErroredFrames()
+	onuStats.DCrcErroredFrames = &dCrcErroredFrames
+
+	dUndersizeFrames := counters.Downstream.GetUndersizeFrames()
+	onuStats.DUndersizeFrames = &dUndersizeFrames
+
+	dOversizeFrames := counters.Downstream.GetOversizeFrames()
+	onuStats.DOversizeFrames = &dOversizeFrames
+
+	dFrames_64Octets := counters.Downstream.GetFrames_64Octets()
+	onuStats.DFrames_64Octets = &dFrames_64Octets
+
+	dFrames_65To_127Octets := counters.Downstream.GetFrames_65To_127Octets()
+	onuStats.DFrames_65To_127Octets = &dFrames_65To_127Octets
+
+	dFrames_128To_255Octets := counters.Downstream.GetFrames_128To_255Octets()
+	onuStats.DFrames_128To_255Octets = &dFrames_128To_255Octets
+
+	dFrames_256To_511Octets := counters.Downstream.GetFrames_256To_511Octets()
+	onuStats.DFrames_256To_511Octets = &dFrames_256To_511Octets
+
+	dFrames_512To_1023Octets := counters.Downstream.GetFrames_512To_1023Octets()
+	onuStats.DFrames_512To_1023Octets = &dFrames_512To_1023Octets
+
+	dFrames_1024To_1518Octets := counters.Downstream.GetFrames_1024To_1518Octets()
+	onuStats.DFrames_1024To_1518Octets = &dFrames_1024To_1518Octets
+	return onuStats
+}
diff --git a/pkg/model/stats.go b/pkg/model/stats.go
index d798af6..621775a 100644
--- a/pkg/model/stats.go
+++ b/pkg/model/stats.go
@@ -45,3 +45,34 @@
 	// reported timestamp in seconds since epoch
 	Timestamp *uint32 `json:"timestamp,omitempty"`
 }
+
+type OnuEthernetFrameExtendedPm struct {
+	UDropEvents               *uint64 `json:"upstream_drop_events,omitempty"`
+	UOctets                   *uint64 `json:"upstream_octets,omitempty"`
+	UFrames                   *uint64 `json:"upstream_frames,omitempty"`
+	UBroadcastFrames          *uint64 `json:"upstream_broadcast_frames,omitempty"`
+	UMulticastFrames          *uint64 `json:"upstream_multicast_frames,omitempty"`
+	UCrcErroredFrames         *uint64 `json:"upstream_crc_errored_frames,omitempty"`
+	UUndersizeFrames          *uint64 `json:"upstream_undersize_frames,omitempty"`
+	UOversizeFrames           *uint64 `json:"upstream_oversize_frames,omitempty"`
+	UFrames_64Octets          *uint64 `json:"upstream_frames_64_octets,omitempty"`
+	UFrames_65To_127Octets    *uint64 `json:"upstream_frames_65_to_127_octets,omitempty"`
+	UFrames_128To_255Octets   *uint64 `json:"upstream_frames_128_to_255_octets,omitempty"`
+	UFrames_256To_511Octets   *uint64 `json:"upstream_frames_256_to_511_octets,omitempty"`
+	UFrames_512To_1023Octets  *uint64 `json:"upstream_frames_512_to_1023_octets,omitempty"`
+	UFrames_1024To_1518Octets *uint64 `json:"upstream_frames_1024_to_1518_octets,omitempty"`
+	DDropEvents               *uint64 `json:"downstream_drop_events,omitempty"`
+	DOctets                   *uint64 `json:"downstream_octets,omitempty"`
+	DFrames                   *uint64 `json:"downstream_frames,omitempty"`
+	DBroadcastFrames          *uint64 `json:"downstream_broadcast_frames,omitempty"`
+	DMulticastFrames          *uint64 `json:"downstream_multicast_frames,omitempty"`
+	DCrcErroredFrames         *uint64 `json:"downstream_crc_errored_frames,omitempty"`
+	DUndersizeFrames          *uint64 `json:"downstream_undersize_frames,omitempty"`
+	DOversizeFrames           *uint64 `json:"downstream_oversize_frames,omitempty"`
+	DFrames_64Octets          *uint64 `json:"downstream_frames_64_octets,omitempty"`
+	DFrames_65To_127Octets    *uint64 `json:"downstream_frames_65_to_127_octets,omitempty"`
+	DFrames_128To_255Octets   *uint64 `json:"downstream_frames_128_to_255_octets,omitempty"`
+	DFrames_256To_511Octets   *uint64 `json:"downstream_frames_256_to_511_octets,omitempty"`
+	DFrames_512To_1023Octets  *uint64 `json:"downstream_frames_512_to_1023_octets,omitempty"`
+	DFrames_1024To_1518Octets *uint64 `json:"downstream_frames_1024_to_1518_octets,omitempty"`
+}