This primarily helps with simplifying the ubus APIs.
blobmsg header presence is indicated by the BLOB_ATTR_EXTENDED bit in
the id_len field.
This changes the format ABI, but not the API.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
void
blob_set_raw_len(struct blob_attr *attr, unsigned int len)
{
- int id = blob_id(attr);
len &= BLOB_ATTR_LEN_MASK;
- len |= (id << BLOB_ATTR_ID_SHIFT) & BLOB_ATTR_ID_MASK;
- attr->id_len = cpu_to_be32(len);
+ attr->id_len &= ~cpu_to_be32(BLOB_ATTR_LEN_MASK);
+ attr->id_len |= cpu_to_be32(len);
}
struct blob_attr *
BLOB_ATTR_LAST
};
-#define BLOB_ATTR_ID_MASK 0xff000000
+#define BLOB_ATTR_ID_MASK 0x7f000000
#define BLOB_ATTR_ID_SHIFT 24
#define BLOB_ATTR_LEN_MASK 0x00ffffff
#define BLOB_ATTR_ALIGN 4
+#define BLOB_ATTR_EXTENDED 0x80000000
struct blob_attr {
uint32_t id_len;
return id;
}
+static inline bool
+blob_is_extended(const struct blob_attr *attr)
+{
+ return !!(attr->id_len & cpu_to_be32(BLOB_ATTR_EXTENDED));
+}
+
/*
* blob_len: returns the length of the attribute's payload
*/
if (!attr)
return NULL;
+ attr->id_len |= be32_to_cpu(BLOB_ATTR_EXTENDED);
hdr = blob_data(attr);
hdr->namelen = cpu_to_be16(namelen);
strcpy((char *) hdr->name, (const char *)name);
static inline void *blobmsg_data(const struct blob_attr *attr)
{
struct blobmsg_hdr *hdr = (struct blobmsg_hdr *) blob_data(attr);
- return (char *) hdr + blobmsg_hdrlen(be16_to_cpu(hdr->namelen));
+ char *data = blob_data(attr);
+
+ if (blob_is_extended(attr))
+ data += blobmsg_hdrlen(be16_to_cpu(hdr->namelen));
+
+ return data;
}
static inline int blobmsg_data_len(const struct blob_attr *attr)