VOL-4337: Code upgrade for 3/2020 G.988 support and remaining Extended Message Set support
Change-Id: I6c5e1a167216ad9b51e9da89460e9909465ae1bc
diff --git a/generated/attribute.go b/generated/attribute.go
index 58bd6cf..de20130 100644
--- a/generated/attribute.go
+++ b/generated/attribute.go
@@ -52,7 +52,7 @@
CounterAttributeType // Incrementing counter
)
-// AttributeDefinitionMap is a map of attribute definitions with the attribute index (0..15)
+// AttributeDefinitionMap is a map of attribute definitions with the attribute index (0..16)
// as the key
type AttributeDefinitionMap map[uint]AttributeDefinition
@@ -72,6 +72,12 @@
Deprecated bool // If true, attribute is deprecated
}
+// TableRows is used by the SetTable request/response
+type TableRows struct {
+ NumRows int // Number of rows of 'AttributeDefinition.Size' length
+ Rows []byte // 0..NumRows rows of attribute data of size 'AttributeDefinition.Size'
+}
+
func (attr *AttributeDefinition) String() string {
return fmt.Sprintf("AttributeDefinition: %v (%v/%v): Size: %v, Default: %v, Access: %v",
attr.GetName(), attr.AttributeType, attr.GetIndex(), attr.GetSize(), attr.GetDefault(), attr.GetAccess())
@@ -80,7 +86,7 @@
// GetName returns the attribute's name
func (attr AttributeDefinition) GetName() string { return attr.Name }
-// GetIndex returns the attribute index )0..15)
+// GetIndex returns the attribute index )0..16)
func (attr AttributeDefinition) GetIndex() uint { return attr.Index }
// GetDefault provides the default value for an attribute if not specified
@@ -392,14 +398,32 @@
if size != 0 && len(data) < attr.GetSize() {
df.SetTruncated()
return nil, NewMessageTruncatedError("packet too small for field")
- } else if size == 0 {
+ }
+ if size == 0 {
return nil, NewProcessingError("table attributes with no size are not supported: %v", attr.Name)
}
return data, nil
case byte(SetTable) | AR: // Set Table Request
- // TODO: Only baseline supported at this time
- return nil, errors.New("attribute encode for set-table-request not yet supported")
+ // SetTableRequestType will be composed of zero or more row of a fixed size (based on ME)
+ // and will be saved to a TableRow struct for the consumer's use
+ size := attr.GetSize()
+ if size == 0 {
+ return nil, NewProcessingError("table attributes with no size are not supported: %v", attr.Name)
+ }
+ if len(data)%size != 0 {
+ df.SetTruncated()
+ return nil, NewMessageTruncatedError("packet does not contain an integral number of rows")
+ }
+ if len(data) == 0 {
+ return TableRows{}, nil
+ }
+ rows := TableRows{
+ NumRows: len(data) / size,
+ Rows: make([]byte, len(data)),
+ }
+ copy(rows.Rows, data)
+ return rows, nil
}
}
@@ -449,8 +473,22 @@
break
case byte(SetTable) | AR: // Set Table Request
- // TODO: Only baseline supported at this time
- return 0, errors.New("attribute encode for set-table-request not yet supported")
+ if rows, ok := value.(TableRows); ok {
+ size := attr.GetSize()
+ if size != 0 && len(rows.Rows)%size != 0 {
+ return 0, NewMessageTruncatedError("packet does not contain an integral number of rows")
+ }
+ if bytesAvailable < len(rows.Rows) {
+ return 0, NewMessageTruncatedError(fmt.Sprintf("not enough space for attribute: %v", attr.Name))
+ }
+ bytes, err := b.AppendBytes(len(rows.Rows))
+ if err != nil {
+ return 0, err
+ }
+ copy(bytes, rows.Rows)
+ return len(rows.Rows), nil
+ }
+ return 0, errors.New("unexpected type for table serialization")
}
size := attr.GetSize()
if bytesAvailable < size {
@@ -774,3 +812,25 @@
}
return err
}
+
+// AttributeValueMapBufferSize will determine how much space is needed to encode all
+// of the attributes
+func AttributeValueMapBufferSize(classID ClassID, attributes AttributeValueMap, msgType uint8) (int, error) {
+ attrDefs, err := GetAttributesDefinitions(classID)
+ if err.StatusCode() != Success {
+ return 0, err
+ } else if attributes == nil {
+ return 0, NewProcessingError("Invalid (nil) Attribute Value Map referenced")
+ }
+ bufferSize := 0
+ isGetResponse := msgType == 0x29
+
+ for _, attrDef := range attrDefs {
+ if isGetResponse && attrDef.IsTableAttribute() {
+ bufferSize += 4
+ } else {
+ bufferSize += attrDef.GetSize()
+ }
+ }
+ return bufferSize, nil
+}