unsigned int extra : 1; //!< really "subtype is used by dict, not by protocol"
- uint8_t subtype; //!< for FR_TYPE_STRING encoding
+ uint8_t subtype; //!< protocol-specific values, OR key fields
uint8_t length; //!< length of the attribute
+
+ /*
+ * TLVs: 1, 2, or 4.
+ * date / time types: fr_time_res_t, which has 4 possible values.
+ * bit fields: offset in the byte where this bit field ends.
+ */
uint8_t type_size; //!< For TLV2 and root attributes.
} fr_dict_attr_flags_t;
#define flag_time_res type_size
+#define flag_byte_offset type_size
+#define flag_struct_offset type_size
/** subtype values for the dictionary when extra=1
*
/*
* We track where on a byte boundary this bit field ends.
*/
- flags->type_size = length;
+ flags->flag_byte_offset = length;
} else {
fr_strerror_const("Only 'octets' types can have a 'length' parameter");
* located.
*/
if (flags.extra && (flags.subtype == FLAG_BIT_FIELD)) {
- flags.type_size += previous->flags.type_size;
- flags.type_size &= 0x07;
+ flags.flag_byte_offset += previous->flags.flag_byte_offset;
+ flags.flag_byte_offset &= 0x07;
} else {
- if (previous->flags.type_size != 0) {
+ if (previous->flags.flag_byte_offset != 0) {
fr_strerror_printf("Previous bitfield %s did not end on a byte boundary",
previous->name);
return -1;
}
/*
- * Length isn't set, set it and type_size from
- * the parent.
+ * Find an appropriate parent to copy the
+ * TLV-specific fields from.
*/
for (v = parent; v != NULL; v = v->parent) {
if ((v->type == FR_TYPE_TLV) || (v->type == FR_TYPE_VENDOR)) {
* that the encoder doesn't have to do complex
* checks.
*/
- if (*attr >= (1 << (8 * parent->flags.type_size))) flags->internal = true;
+ if ((uint64_t) *attr >= (((uint64_t)1) << (8 * parent->flags.type_size))) flags->internal = true;
}
/*
if ((*attr > UINT8_MAX) && !flags->internal) {
for (v = parent; v != NULL; v = v->parent) {
if ((v->type == FR_TYPE_TLV) || (v->type == FR_TYPE_VENDOR)) {
- if ((v->flags.type_size < 4) &&
- (*attr >= (1 << (8 * v->flags.type_size)))) {
- fr_strerror_printf("Attributes must have value between 1..%u",
- (1 << (8 * v->flags.type_size)) - 1);
+ if ((uint64_t) *attr >= (((uint64_t) 1) << (8 * v->flags.type_size))) {
+ fr_strerror_printf("Attributes must have value between 1..%llu",
+ (((uint64_t) 1) << (8 * v->flags.type_size)) - 1);
return false;
}
break;