fix for profiles in voltha1.7

Change-Id: Id6d7c38ae38460e879d99f63f8db07321e07cf21
diff --git a/omci_anig.go b/omci_anig.go
new file mode 100644
index 0000000..99ebca7
--- /dev/null
+++ b/omci_anig.go
@@ -0,0 +1,168 @@
+package core
+
+type AniGAttributes int
+const (
+	_								= iota
+	SRIndication  				AniGAttributes	= 0x8000
+	TotalTcontNumber 			AniGAttributes	= 0x4000
+	GEMBlockLength				AniGAttributes	= 0x2000
+	PiggybackDBAReporting 		AniGAttributes	= 0x1000
+	WholeONTDBAReporting		AniGAttributes	= 0x0800
+	SFThreshold					AniGAttributes	= 0x0400
+	SDThreshold					AniGAttributes	= 0x0200
+	ARC							AniGAttributes	= 0x0100
+	ARCInterval					AniGAttributes	= 0x0080
+	OpticalSignalLevel			AniGAttributes	= 0x0040
+	LowerOpticalThreshold		AniGAttributes	= 0x0020
+	UpperOpticalThreshold		AniGAttributes	= 0x0010
+	ONTResponseTime				AniGAttributes	= 0x0008
+	TransmitOpticalLeval		AniGAttributes	= 0x0004
+	LowerTransmitPowerThreshold	AniGAttributes	= 0x0002
+	UpperTransmitPowerThreshold	AniGAttributes	= 0x0001
+)
+
+type ANIGAttributeHandler func(*uint, []byte) ([]byte, error)
+
+var ANIGAttributeHandlers = map[AniGAttributes]ANIGAttributeHandler{
+	SRIndication: GetSRIndication,
+	OpticalSignalLevel: GetOpticalSignalLevel,
+	LowerOpticalThreshold: GetLowerOpticalThreshold,
+	UpperOpticalThreshold: GetUpperOpticalThreshold,
+	TotalTcontNumber: GetTotalTcontNumber,
+	GEMBlockLength: GetGEMBlockLength,
+	PiggybackDBAReporting: GetPiggybackDBAReporting,
+	WholeONTDBAReporting: GetWholeONTDBAReporting,
+	SFThreshold: GetSFThreshold,
+	SDThreshold: GetSDThreshold,
+	ARC: GetARC,
+	ARCInterval: GetARCInterval,
+	ONTResponseTime: GetONTResponseTime,
+	TransmitOpticalLeval: GetTransmitOpticalLeval,
+	LowerTransmitPowerThreshold: GetLowerTransmitPowerThreshold,
+	UpperTransmitPowerThreshold: GetUpperTransmitPowerThreshold,
+}
+
+
+func GetANIGAttributes(pos *uint, pkt []byte, content OmciContent) ([]byte, error) {
+	AttributesMask := getAttributeMask(content)
+
+	for index := uint(16); index>=1 ; index-- {
+		Attribute := 1 << (index - 1)
+		reqAttribute := Attribute & AttributesMask
+
+		if reqAttribute != 0 {
+			pkt, _ = ANIGAttributeHandlers[AniGAttributes(reqAttribute)](pos, pkt)
+		}
+	}
+
+	pkt[8] = 0x00 // Command Processed Successfully
+	pkt[9] = uint8(AttributesMask >> 8)
+	pkt[10] = uint8(AttributesMask & 0x00FF)
+
+	return pkt, nil
+
+}
+
+
+func GetSRIndication(pos *uint, pkt []byte) ([]byte, error) {
+	pkt[*pos] = 0x01
+	*pos++
+	return pkt, nil
+}
+
+func GetOpticalSignalLevel(pos *uint, pkt []byte) ([]byte, error) {
+	pkt[*pos] = 0xd7
+	*pos++
+	pkt[*pos] = 0xa9
+	*pos++
+	return pkt, nil
+}
+
+func GetTotalTcontNumber(pos *uint, pkt []byte) ([]byte, error) {
+	pkt[*pos] = 0x08
+	*pos++
+	return pkt, nil
+}
+
+func GetGEMBlockLength(pos *uint, pkt []byte) ([]byte, error) {
+	pkt[*pos] = 0x00
+	*pos++
+	pkt[*pos] = 0x30
+	return pkt, nil
+}
+
+func GetPiggybackDBAReporting (pos *uint, pkt []byte) ([]byte, error) {
+	pkt[*pos] = 0x00
+	*pos++
+	return pkt, nil
+}
+
+func GetWholeONTDBAReporting(pos *uint, pkt []byte) ([]byte, error) {
+	pkt[*pos] = 0x00
+	*pos++
+	return pkt, nil
+}
+
+func GetUpperOpticalThreshold(pos *uint, pkt []byte) ([]byte, error) {
+	pkt[*pos] = 0xff
+	*pos++
+	return pkt, nil
+}
+
+func GetSFThreshold(pos *uint, pkt []byte) ([]byte, error) {
+	pkt[*pos] = 0x03
+	*pos++
+	return pkt, nil
+}
+
+func GetSDThreshold(pos *uint, pkt []byte) ([]byte, error) {
+	pkt[*pos] = 0x05
+	*pos++
+	return pkt, nil
+}
+
+func GetARC(pos *uint, pkt []byte) ([]byte, error) {
+	pkt[*pos] = 0x00
+	*pos++
+	return pkt, nil
+}
+
+func GetARCInterval(pos *uint, pkt []byte) ([]byte, error) {
+	pkt[*pos] = 0x00
+	*pos++
+	return pkt, nil
+}
+
+func GetONTResponseTime(pos *uint, pkt []byte) ([]byte, error) {
+	pkt[*pos] = 0x00
+	*pos++
+	pkt[*pos] = 0x00
+	*pos++
+	return pkt, nil
+}
+
+func GetLowerOpticalThreshold(pos *uint, pkt []byte) ([]byte, error) {
+	pkt[*pos] = 0xff
+	*pos++
+	return pkt, nil
+}
+
+func GetTransmitOpticalLeval(pos *uint, pkt []byte) ([]byte, error) {
+	pkt[*pos] = 0x07
+	*pos++
+	pkt[*pos] = 0x1e
+	*pos++
+	return pkt, nil
+}
+
+func GetLowerTransmitPowerThreshold(pos *uint, pkt []byte) ([]byte, error) {
+	pkt[*pos] = 0x81
+	*pos++
+	return pkt, nil
+}
+
+func GetUpperTransmitPowerThreshold(pos *uint, pkt []byte) ([]byte, error) {
+	pkt[*pos] = 0x81
+	*pos++
+	return pkt, nil
+}
\ No newline at end of file
diff --git a/omci_common.go b/omci_common.go
index 2a478ce..223fe0e 100644
--- a/omci_common.go
+++ b/omci_common.go
@@ -16,7 +16,10 @@
 
 package core
 
-import "fmt"
+import (
+	"fmt"
+	"log"
+)
 
 type OmciError struct {
 	Msg string
@@ -33,3 +36,36 @@
 func (k OnuKey) String() string {
 	return fmt.Sprintf("Onu {intfid:%d, onuid:%d}", k.IntfId, k.OnuId)
 }
+
+func GetAttributes(class OmciClass, content OmciContent, key OnuKey, pkt []byte) []byte {
+	log.Printf("GetAttributes() invoked with onu key: %+v\n", key)
+
+	switch class {
+	case ANIG:
+		pos := uint(11)
+		pkt, _ = GetANIGAttributes(&pos, pkt, content)
+		return pkt
+
+	case EthernetPMHistoryData:
+		pos := uint(11)
+		pkt, _ = GetEthernetPMHistoryDataAttributes(&pos, pkt, content)
+		return pkt
+	default:
+		// For unimplemented MEs, just fill in the attribute mask and return 0 values for the requested attributes
+		// TODO implement Get for unimplemented MEs as well
+		log.Printf("Unimplemeted GetAttributes for ME Class: %v " +
+		    "Filling with zero value for the requested attributes", class)
+		AttributesMask := getAttributeMask(content)
+		pkt[8] = 0x00 // Command Processed Successfully
+		pkt[9] = uint8(AttributesMask >> 8)
+		pkt[10] = uint8(AttributesMask & 0xFF)
+
+		return pkt
+	}
+}
+
+func getAttributeMask(content OmciContent) int {
+	// mask is present in pkt[8] and pkt[9]
+	log.Printf("GetAttributeMask() invoked\n content[0] , content[1]: %+v, %+v", content[0], content[1])
+	return (int(content[0]) << 8) | int(content[1])
+}
diff --git a/omci_defs.go b/omci_defs.go
index 594ab00..e278d9b 100644
--- a/omci_defs.go
+++ b/omci_defs.go
@@ -59,8 +59,10 @@
 
 const (
 	// Managed Entity Class values
-	GEMPortNetworkCTP OmciClass = 268
-	ONUG              OmciClass = 256
+	EthernetPMHistoryData OmciClass = 24
+	ONUG                  OmciClass = 256
+	ANIG                  OmciClass = 263
+	GEMPortNetworkCTP     OmciClass = 268
 )
 
 // OMCI Managed Entity Class
diff --git a/omci_handlers.go b/omci_handlers.go
index e9847ca..1ebaaea 100644
--- a/omci_handlers.go
+++ b/omci_handlers.go
@@ -71,7 +71,8 @@
 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
 
-	pkt[9] = NumMibUploads // Number of subsequent MibUploadNext cmds
+	pkt[8] = NumMibUploadsHigherByte
+	pkt[9] = NumMibUploadsLowerByte
 
 	return pkt, nil
 }
@@ -82,13 +83,13 @@
 	state := OnuOmciStateMap[key]
 
 	// commandNumber is the "Command number" attribute received in "MIB Upload Next" OMCI message
-	commandNumber := ( (uint16(content[1])) | (uint16(content[0])<<8) )
+	commandNumber := (uint16(content[1])) | (uint16(content[0])<<8)
 	log.Printf("%v - Omci MibUploadNext %d", key, commandNumber)
 
 	switch commandNumber {
 	case 0:
 		// ONT Data (2)
-		log.Println("ONT DATA")
+		// log.Println("ONT DATA")
 		pkt = []byte{
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
 			0x00, 0x02, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
@@ -98,7 +99,7 @@
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
 	case 1:
 		// Circuit Pack (6) - #1
-		log.Println("Circuit Pack")
+		// log.Println("Circuit Pack")
 		pkt = []byte{
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
 			0x00, 0x06, 0x01, 0x01, 0xf0, 0x00, 0x2f, 0x04,
@@ -108,7 +109,7 @@
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
 	case 2:
 		// Circuit Pack (6) - #2
-		log.Println("Circuit Pack")
+		// log.Println("Circuit Pack")
 		pkt = []byte{
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
 			0x00, 0x06, 0x01, 0x01, 0x0f, 0x00, 0x42, 0x52,
@@ -118,7 +119,7 @@
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
 	case 3:
 		// Circuit Pack (6) - #3
-		log.Println("Circuit Pack")
+		// log.Println("Circuit Pack")
 		pkt = []byte{
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
 			0x00, 0x06, 0x01, 0x01, 0x00, 0xf8, 0x20, 0x20,
@@ -128,7 +129,7 @@
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
 	case 4:
 		// Circuit Pack (6) - #4
-		log.Println("Circuit Pack")
+		// log.Println("Circuit Pack")
 		pkt = []byte{
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
 			0x00, 0x06, 0x01, 0x01, 0x00, 0x04, 0x00, 0x00,
@@ -138,7 +139,7 @@
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
 	case 5:
 		// Circuit Pack (6) - #5
-		log.Println("Circuit Pack")
+		// log.Println("Circuit Pack")
 		pkt = []byte{
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
 			0x00, 0x06, 0x01, 0x80, 0xf0, 0x00, 0xee, 0x01,
@@ -148,7 +149,7 @@
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
 	case 6:
 		// Circuit Pack (6) - #6
-		log.Println("Circuit Pack")
+		// log.Println("Circuit Pack")
 		pkt = []byte{
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
 			0x00, 0x06, 0x01, 0x80, 0x0f, 0x00, 0x42, 0x52,
@@ -158,7 +159,7 @@
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
 	case 7:
 		// Circuit Pack (6) - #7
-		log.Println("Circuit Pack")
+		// log.Println("Circuit Pack")
 		pkt = []byte{
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
 			0x00, 0x06, 0x01, 0x80, 0x00, 0xf8, 0x20, 0x20,
@@ -168,7 +169,7 @@
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
 	case 8:
 		// Circuit Pack (6) - #8
-		log.Println("Circuit Pack")
+		// log.Println("Circuit Pack")
 		pkt = []byte{
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
 			0x00, 0x06, 0x01, 0x80, 0x00, 0x04, 0x00, 0x00,
@@ -178,7 +179,7 @@
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
 	case 9, 10, 11, 12:
 		// PPTP (11)
-		log.Println("PPTP")
+		// log.Println("PPTP")
 		pkt = []byte{
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
 			0x00, 0x0b, 0x01, 0x01, 0xff, 0xfe, 0x00, 0x2f,
@@ -190,7 +191,7 @@
 		state.pptpInstance++
 	case 13, 14, 15, 16, 17, 18, 19, 20:
 		// T-CONT (262)
-		log.Println("T-CONT")
+		// log.Println("T-CONT")
 		pkt = []byte{
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
 			0x01, 0x06, 0x80, 0x00, 0xe0, 0x00, 0xff, 0xff,
@@ -198,11 +199,13 @@
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
-		pkt[11] = state.tcontInstance // TCONT ME Instance
+
 		state.tcontInstance++
+		pkt[11] = state.tcontInstance // TCONT ME Instance
+
 	case 21:
 		// ANI-G (263)
-		log.Println("ANI-G")
+		// log.Println("ANI-G")
 		pkt = []byte{
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
 			0x01, 0x07, 0x80, 0x01, 0xff, 0xff, 0x01, 0x00,
@@ -212,7 +215,7 @@
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
 	case 22, 23, 24, 25:
 		// UNI-G (264)
-		log.Println("UNI-G")
+		// log.Println("UNI-G")
 		pkt = []byte{
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
 			0x01, 0x08, 0x01, 0x01, 0xf8, 0x00, 0x00, 0x00,
@@ -223,7 +226,14 @@
 		pkt[11] = state.uniGInstance // UNI-G ME Instance
 		state.uniGInstance++
 
-	case 26, 30, 34, 38, 42, 46, 50, 54:
+	case 26,  30,  34,  38,  42, 46, 50, 54,
+	     58,  62,  66,  70,  74, 78, 82, 86,
+	     90,  94,  98,  102, 106, 110, 114, 118,
+	     122, 126, 130, 134, 138, 142, 146, 150,
+	     154, 158, 162, 166, 170, 174, 178, 182,
+	     186, 190, 194, 198, 202, 206, 210, 214,
+	     218, 222, 226, 230, 234, 238, 242, 246,
+	     250, 254, 258, 262, 266, 270, 274, 278:
 		// Prior-Q with mask downstream
 		log.Println("Mib-upload for prior-q with mask")
 		// For downstream PQ, pkt[10] is 0x00
@@ -239,9 +249,16 @@
 		state.priorQInstance++
 		pkt[11] = state.priorQInstance
 
-	case 27, 31, 35, 39, 43, 47, 51, 55:
+	case 27,  31,  35,  39,  43,  47, 51, 55,
+	     59,  63,  67,  71,  75,  79, 83, 87,
+	     91,  95,  99,  103, 107, 111, 115, 119,
+	     123, 127, 131, 135, 139, 143, 147, 151,
+	     155, 159, 163, 167, 171, 175, 179, 183,
+	     187, 191, 195, 199, 203, 207, 211, 215,
+	     219, 223, 227, 231, 235, 239, 243, 247,
+	     251, 255, 259, 263, 267, 271, 275, 279:
 		// Prior-Q with attribute list downstream
-		log.Println("Mib-upload for prior-q with attribute list")
+		// log.Println("Mib-upload for prior-q with attribute list")
 		pkt = []byte{
 			0x00, 0x43, 0x2e, 0x0a, 0x00, 0x02, 0x00, 0x00,
 			0x01, 0x15, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x01,
@@ -252,13 +269,33 @@
 		}
 
 		pkt[11] = state.priorQInstance
-		state.tcontInstance--
-		pkt[24] = state.tcontInstance // related port points to tcont
+
+		// Group 8 PriorQ to point to a particular TCONT
+		// Priority for each group of PriorQ is 0 - 7
+		if state.priorQPriority % NumPriorQPerTcont == 0 {
+			state.tcontPointer++
+		}
+
+		// Only for verification. To be removed
+		if state.tcontPointer > state.tcontInstance {
+			log.Println("Error: Invalid TcontPointer")
+			break
+		}
+
+		pkt[24] = state.tcontPointer
+		pkt[26] = state.priorQPriority % NumPriorQPerTcont
 		pkt[28] = state.tcontInstance
 
-	case 28, 32, 36, 40, 44, 48, 52, 56:
+	case 28,  32,  36,  40,  44, 48, 52, 56,
+	     60,  64,  68,  72,  76, 80, 84, 88,
+	     92,  96,  100, 104, 108, 112, 116, 120,
+	     124, 128, 132, 136, 140, 144, 148, 152,
+	     156, 160, 164, 168, 172, 176, 180, 184,
+	     188, 192, 196, 200, 204, 208, 212, 216,
+	     220, 224, 228, 232, 236, 240, 244, 248,
+	     252, 256, 260, 264, 268, 272, 276, 280:
 		// Prior-Q with mask upstream
-		log.Println("Mib-upload for prior-q with mask")
+		// log.Println("Mib-upload for prior-q with mask")
 		pkt = []byte{
 			0x00, 0x42, 0x2e, 0x0a, 0x00, 0x02, 0x00, 0x00,
 			0x01, 0x15, 0x80, 0x00, 0x00, 0x0f, 0xff, 0xff,
@@ -269,9 +306,16 @@
 		}
 		pkt[11] = state.priorQInstance
 
-	case 29, 33, 37, 41, 45, 49, 53, 57:
+	case 29,  33,  37, 41, 45, 49, 53, 57,
+	     61,  65,  69, 73, 77, 81, 85, 89,
+	     93, 97,  101, 105, 109, 113, 117, 121,
+	     125, 129, 133, 137, 141, 145, 149, 153,
+	     157, 161, 165, 169, 173, 177, 181, 185,
+	     189, 193, 197, 201, 205, 209, 213, 217,
+	     221, 225, 229, 233, 237, 241, 245, 249,
+	     253, 257, 261, 265, 269, 273, 277, 281:
 		// Prior-Q with attribute list upstream
-		log.Println("Mib-upload for prior-q with attribute list")
+		// log.Println("Mib-upload for prior-q with attribute list")
 		// For upstream pkt[10] is fixed as 80
 		// So for upstream PQ, instanceId will be like 0x8001, 0x8002 ... etc
 		pkt = []byte{
@@ -284,12 +328,15 @@
 		}
 
 		pkt[11] = state.priorQInstance
-		pkt[24] = state.tcontInstance // related port points to tcont
+		pkt[24] = state.tcontPointer
+		pkt[26] = state.priorQPriority % NumPriorQPerTcont // Priority of this PriorQ
 		pkt[28] = state.tcontInstance
+		state.priorQPriority++
 
-	case 58, 59, 60, 61, 62, 63, 64, 65:
+
+	case 282, 283, 284, 285, 286, 287, 288, 289:
 		// Traffic Scheduler
-		log.Println("Traffic Scheduler")
+		// log.Println("Traffic Scheduler")
 		pkt = []byte{
 			0x02, 0xa4, 0x2e, 0x0a, 0x00, 0x02, 0x00, 0x00,
 			0x01, 0x16, 0x80, 0x00, 0xf0, 0x00, 0x80, 0x00,
@@ -302,9 +349,9 @@
 		pkt[15] = state.tcontInstance
 		state.tcontInstance++
 
-	case 66:
+	case 290:
 		// ONT-2G
-		log.Println("ONT-2G")
+		// log.Println("ONT-2G")
 		pkt = []byte{
 			0x00, 0x16, 0x2e, 0x0a, 0x00, 0x02, 0x00, 0x00,
 			0x01, 0x01, 0x00, 0x00, 0x07, 0xfc, 0x00, 0x40,
@@ -379,8 +426,9 @@
 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
 
-	log.Printf("%v - Omci Get", key)
+	pkt = GetAttributes(class, content, key, pkt)
 
+	log.Printf("%v - Omci Get", key)
 	return pkt, nil
 }
 
@@ -421,7 +469,7 @@
 
 	pkt = []byte{
 		0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
-		0x00, 0x0b, 0x01, 0x02, 0x80, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -461,3 +509,4 @@
 	log.Printf("%v - Omci Reboot", key)
 	return pkt, nil
 }
+
diff --git a/omci_mib.go b/omci_mib.go
index fa5943c..b8d2cdc 100644
--- a/omci_mib.go
+++ b/omci_mib.go
@@ -16,4 +16,7 @@
 
 package core
 
-const NumMibUploads byte = 0x43 // NumMibUploads is the number of mibs to be sent in subsequent mibuploadnext
+const NumMibUploadsHigherByte byte = 0x01
+const NumMibUploadsLowerByte byte = 0x23
+const NumPriorQPerTcont = 0x08 // NumPriorQPerTcont is the number of priority queues associated with a single tcont
+
diff --git a/omci_pm_history_data.go b/omci_pm_history_data.go
new file mode 100644
index 0000000..15188fa
--- /dev/null
+++ b/omci_pm_history_data.go
@@ -0,0 +1,191 @@
+package core
+
+type PerformanceMonitoringHistoryData int
+
+const (
+	_                                                                = iota
+	IntervalEndTime                 PerformanceMonitoringHistoryData = 0x8000
+	ThresholdDataId                 PerformanceMonitoringHistoryData = 0x4000
+	FCSErrors                       PerformanceMonitoringHistoryData = 0x2000
+	ExcessiveCollisionCounter       PerformanceMonitoringHistoryData = 0x1000
+	LateCollisionCounter            PerformanceMonitoringHistoryData = 0x0800
+	FrameTooLong                    PerformanceMonitoringHistoryData = 0x0400
+	BufferOverflowOnReceive         PerformanceMonitoringHistoryData = 0x0200
+	BufferOverflowOnTransmit        PerformanceMonitoringHistoryData = 0x0100
+	SingleCollisionFrameCounter     PerformanceMonitoringHistoryData = 0x0080
+	MultipleCollisionFrameCounter   PerformanceMonitoringHistoryData = 0x0040
+	SQECounter                      PerformanceMonitoringHistoryData = 0x0020
+	DeferredTransmissionCounter     PerformanceMonitoringHistoryData = 0x0010
+	InternalMACTransmitErrorCounter PerformanceMonitoringHistoryData = 0x0008
+	CarrierSenseErrorCounter        PerformanceMonitoringHistoryData = 0x0004
+	AllignmentErrorCounter          PerformanceMonitoringHistoryData = 0x0002
+	InternalMACReceiveErrorCounter  PerformanceMonitoringHistoryData = 0x0001
+)
+
+type PMHistoryAttributeHandler func(*uint, []byte) ([]byte, error)
+
+var PMHistoryAttributeHandlers = map[PerformanceMonitoringHistoryData]ANIGAttributeHandler{
+	IntervalEndTime :                GetIntervalEndTime,
+	ThresholdDataId:                 GetThresholdDataId,
+	FCSErrors:                       GetFCSErrors,
+	ExcessiveCollisionCounter:       GetExcessiveCollisionCounter,
+	LateCollisionCounter:            GetLateCollisionCounter,
+	FrameTooLong:                    GetFrameTooLong,
+	BufferOverflowOnReceive:         GetBufferOverflowOnReceive,
+	BufferOverflowOnTransmit:        GetBufferOverflowOnTransmit,
+	SingleCollisionFrameCounter:     GetSingleCollisionFrameCounter,
+	MultipleCollisionFrameCounter:   GetMultipleCollisionFrameCounter,
+	SQECounter:                      GetSQECounter,
+	DeferredTransmissionCounter:     GetDeferredTransmissionCounter,
+	InternalMACTransmitErrorCounter: GetInternalMACTransmitErrorCounter,
+	CarrierSenseErrorCounter:        GetCarrierSenseErrorCounter,
+	AllignmentErrorCounter:          GetAllignmentErrorCounter,
+	InternalMACReceiveErrorCounter:  GetInternalMACReceiveErrorCounter,
+}
+
+func GetEthernetPMHistoryDataAttributes(pos *uint, pkt []byte, content OmciContent) ([]byte, error) {
+	AttributesMask := getAttributeMask(content)
+
+	for index := uint(16); index>=1 ; index-- {
+		Attribute := 1 << (index - 1)
+		reqAttribute := Attribute & AttributesMask
+
+		if reqAttribute != 0 {
+			pkt, _ = PMHistoryAttributeHandlers[PerformanceMonitoringHistoryData(reqAttribute)](pos, pkt)
+		}
+	}
+
+	pkt[8] = 0x00 // Command Processed Successfully
+	pkt[9] = uint8(AttributesMask >> 8)
+	pkt[10] = uint8(AttributesMask & 0x00FF)
+
+	return pkt, nil
+
+}
+
+func GetIntervalEndTime(pos *uint, pkt []byte) ([]byte, error) {
+	// With the hardware, it is seen that all attributes are 0x00
+	// Nevertheless these functions are made to provide specific values in future if required
+	*pos++
+	return pkt, nil
+}
+
+func GetThresholdDataId(pos *uint, pkt []byte) ([]byte, error) {
+	*pos++
+	*pos++
+	return pkt, nil
+}
+
+func GetFCSErrors(pos *uint, pkt []byte) ([]byte, error) {
+	*pos++
+	*pos++
+	*pos++
+	*pos++
+	return pkt, nil
+}
+
+func GetExcessiveCollisionCounter(pos *uint, pkt []byte) ([]byte, error) {
+	*pos++
+	*pos++
+	*pos++
+	*pos++
+	return pkt, nil
+}
+
+func GetLateCollisionCounter(pos *uint, pkt []byte) ([]byte, error) {
+	*pos++
+	*pos++
+	*pos++
+	*pos++
+	return pkt, nil
+}
+
+func GetFrameTooLong(pos *uint, pkt []byte) ([]byte, error) {
+	*pos++
+	*pos++
+	*pos++
+	*pos++
+	return pkt, nil
+}
+
+func GetBufferOverflowOnReceive(pos *uint, pkt []byte) ([]byte, error) {
+	*pos++
+	*pos++
+	*pos++
+	*pos++
+	return pkt, nil
+}
+
+func GetBufferOverflowOnTransmit(pos *uint, pkt []byte) ([]byte, error) {
+	*pos++
+	*pos++
+	*pos++
+	*pos++
+	return pkt, nil
+}
+
+func GetSingleCollisionFrameCounter(pos *uint, pkt []byte) ([]byte, error) {
+	*pos++
+	*pos++
+	*pos++
+	*pos++
+	return pkt, nil
+}
+
+func GetMultipleCollisionFrameCounter(pos *uint, pkt []byte) ([]byte, error) {
+	*pos++
+	*pos++
+	*pos++
+	*pos++
+	return pkt, nil
+}
+
+func GetSQECounter(pos *uint, pkt []byte) ([]byte, error) {
+	*pos++
+	*pos++
+	*pos++
+	*pos++
+	return pkt, nil
+}
+
+func GetDeferredTransmissionCounter(pos *uint, pkt []byte) ([]byte, error) {
+	*pos++
+	*pos++
+	*pos++
+	*pos++
+	return pkt, nil
+}
+
+func GetInternalMACTransmitErrorCounter(pos *uint, pkt []byte) ([]byte, error) {
+	*pos++
+	*pos++
+	*pos++
+	*pos++
+	return pkt, nil
+}
+
+func GetCarrierSenseErrorCounter(pos *uint, pkt []byte) ([]byte, error) {
+	*pos++
+	*pos++
+	*pos++
+	*pos++
+	return pkt, nil
+}
+
+func GetAllignmentErrorCounter(pos *uint, pkt []byte) ([]byte, error) {
+	*pos++
+	*pos++
+	*pos++
+	*pos++
+	return pkt, nil
+}
+
+func GetInternalMACReceiveErrorCounter(pos *uint, pkt []byte) ([]byte, error) {
+	*pos++
+	*pos++
+	*pos++
+	*pos++
+	return pkt, nil
+}
+
+
diff --git a/omci_sim.go b/omci_sim.go
index b6ebe30..63b18af 100644
--- a/omci_sim.go
+++ b/omci_sim.go
@@ -17,13 +17,16 @@
 package core
 
 import "log"
+import logs "gerrit.opencord.org/voltha-bbsim/common/logger"
+
+var logger = logs.DefaultLogger
 
 func OmciSim(intfId uint32, onuId uint32, request []byte) ([]byte, error) {
 	var resp []byte
 
 	transactionId, deviceId, msgType, class, instance, content, err := ParsePkt(request)
 	if err != nil {
-		log.Printf("ONU {intfid:%d, onuid:%d} - Cannot parse omci msg", intfId, onuId)
+		logger.Error("ONU {intfid:%d, onuid:%d} - Cannot parse omci msg", intfId, onuId)
 		return resp, &OmciError{"Cannot parse omci msg"}
 	}
 
@@ -42,7 +45,7 @@
 
 	resp, err = Handlers[msgType](class, content, key)
 	if err != nil {
-		log.Println("ONU {intfid:%d, onuid:%d} - Unable to send a successful response, error:%s", intfId, onuId, err)
+		log.Printf("ONU {intfid:%d, onuid:%d} - Unable to send a successful response, error:%s", intfId, onuId, err)
 		return resp, nil
 	}
 
diff --git a/omci_state.go b/omci_state.go
index 4050b22..6af433f 100644
--- a/omci_state.go
+++ b/omci_state.go
@@ -23,11 +23,13 @@
 type OnuOmciState struct {
 	gemPortId         uint16
 	mibUploadCtr      uint16
-	extraMibUploadCtr uint16 //this is only for debug purposes, will be removed in the future
+	extraMibUploadCtr uint16 // this is only for debug purposes, will be removed in the future
 	uniGInstance      uint8
 	tcontInstance     uint8
 	pptpInstance      uint8
-	priorQInstance    uint8 //To assign incrementing value to PQ instance-Id
+	priorQInstance    uint8 // To assign incrementing value to PQ instance-Id
+	priorQPriority	  uint8 // Priority of the PriorityQueueG (0-7)
+	tcontPointer      uint8 // Tcont Pointer for PriorQ
 	state             istate
 }
 
@@ -45,12 +47,15 @@
 	return &OnuOmciState{gemPortId: 0, mibUploadCtr: 0, uniGInstance: 1, tcontInstance: 0, pptpInstance: 1}
 }
 func (s *OnuOmciState) ResetOnuOmciState() {
+	// Resetting the counters  
 	s.mibUploadCtr = 0
 	s.extraMibUploadCtr = 0
 	s.gemPortId = 0
 	s.uniGInstance = 1
 	s.tcontInstance = 0
 	s.pptpInstance = 1
+	s.tcontPointer = 0
+	s.priorQPriority = 0
 }
 func GetOnuOmciState(intfId uint32, onuId uint32) istate {
 	key := OnuKey{intfId, onuId}