summaryrefslogtreecommitdiffstats
path: root/lib/pb-protocol
diff options
context:
space:
mode:
authorJeremy Kerr <jk@ozlabs.org>2013-10-09 12:02:08 +0800
committerJeremy Kerr <jk@ozlabs.org>2013-10-09 17:40:04 +0800
commitbc4114e2235163bd88456c25cc0a908d86151f93 (patch)
tree47e7e1674e33a5f138ed3a390c3dc02e2d9f3133 /lib/pb-protocol
parentab7076882bc49d895209bf0ecb84e4003e034dd9 (diff)
downloadtalos-petitboot-bc4114e2235163bd88456c25cc0a908d86151f93.tar.gz
talos-petitboot-bc4114e2235163bd88456c25cc0a908d86151f93.zip
Add system info messages
Add a little infrastructure for communicating information about the system to the petitboot UIs. We just send some identifying info (type and identifier), as well as the interfaces. Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Diffstat (limited to 'lib/pb-protocol')
-rw-r--r--lib/pb-protocol/pb-protocol.c110
-rw-r--r--lib/pb-protocol/pb-protocol.h7
2 files changed, 117 insertions, 0 deletions
diff --git a/lib/pb-protocol/pb-protocol.c b/lib/pb-protocol/pb-protocol.c
index 681b250..46f1add 100644
--- a/lib/pb-protocol/pb-protocol.c
+++ b/lib/pb-protocol/pb-protocol.c
@@ -141,6 +141,18 @@ static int read_string(void *ctx, const char **pos, unsigned int *len,
return 0;
}
+static int read_u32(const char **pos, unsigned int *len, unsigned int *p)
+{
+ if (*len < sizeof(uint32_t))
+ return -1;
+
+ *p = (unsigned int)__be32_to_cpu(*(uint32_t *)(*pos));
+ *pos += sizeof(uint32_t);
+ *len -= sizeof(uint32_t);
+
+ return 0;
+}
+
char *pb_protocol_deserialise_string(void *ctx,
const struct pb_protocol_message *message)
{
@@ -205,6 +217,23 @@ int pb_protocol_boot_status_len(const struct boot_status *status)
4;
}
+int pb_protocol_system_info_len(const struct system_info *sysinfo)
+{
+ unsigned int len, i;
+
+ len = 4 + optional_strlen(sysinfo->type) +
+ 4 + optional_strlen(sysinfo->identifier) +
+ 4;
+
+ for (i = 0; i < sysinfo->n_interfaces; i++) {
+ struct interface_info *if_info = sysinfo->interfaces[i];
+ len += 4 + if_info->hwaddr_size +
+ 4 + optional_strlen(if_info->name);
+ }
+
+ return len;
+}
+
int pb_protocol_serialise_device(const struct device *dev,
char *buf, int buf_len)
{
@@ -284,6 +313,36 @@ int pb_protocol_serialise_boot_status(const struct boot_status *status,
return 0;
}
+int pb_protocol_serialise_system_info(const struct system_info *sysinfo,
+ char *buf, int buf_len)
+{
+ char *pos = buf;
+ unsigned int i;
+
+ pos += pb_protocol_serialise_string(pos, sysinfo->type);
+ pos += pb_protocol_serialise_string(pos, sysinfo->identifier);
+
+ *(uint32_t *)pos = __cpu_to_be32(sysinfo->n_interfaces);
+ pos += sizeof(uint32_t);
+
+ for (i = 0; i < sysinfo->n_interfaces; i++) {
+ struct interface_info *if_info = sysinfo->interfaces[i];
+
+ *(uint32_t *)pos = __cpu_to_be32(if_info->hwaddr_size);
+ pos += sizeof(uint32_t);
+
+ memcpy(pos, if_info->hwaddr, if_info->hwaddr_size);
+ pos += if_info->hwaddr_size;
+
+ pos += pb_protocol_serialise_string(pos, if_info->name);
+ }
+
+ assert(pos <= buf + buf_len);
+ (void)buf_len;
+
+ return 0;
+}
+
int pb_protocol_write_message(int fd, struct pb_protocol_message *message)
{
int total_len, rc;
@@ -536,3 +595,54 @@ int pb_protocol_deserialise_boot_status(struct boot_status *status,
out:
return rc;
}
+
+int pb_protocol_deserialise_system_info(struct system_info *sysinfo,
+ const struct pb_protocol_message *message)
+{
+ unsigned int len, i;
+ const char *pos;
+ int rc = -1;
+
+ len = message->payload_len;
+ pos = message->payload;
+
+ /* type and identifier strings */
+ if (read_string(sysinfo, &pos, &len, &sysinfo->type))
+ goto out;
+
+ if (read_string(sysinfo, &pos, &len, &sysinfo->identifier))
+ goto out;
+
+ /* number of interfaces */
+ if (read_u32(&pos, &len, &sysinfo->n_interfaces))
+ goto out;
+
+ sysinfo->interfaces = talloc_array(sysinfo, struct interface_info *,
+ sysinfo->n_interfaces);
+
+ for (i = 0; i < sysinfo->n_interfaces; i++) {
+ struct interface_info *if_info = talloc(sysinfo,
+ struct interface_info);
+
+ if (read_u32(&pos, &len, &if_info->hwaddr_size))
+ goto out;
+
+ if (len < if_info->hwaddr_size)
+ goto out;
+
+ if_info->hwaddr = talloc_memdup(if_info, pos,
+ if_info->hwaddr_size);
+ pos += if_info->hwaddr_size;
+ len -= if_info->hwaddr_size;
+
+ if (read_string(if_info, &pos, &len, &if_info->name))
+ goto out;
+
+ sysinfo->interfaces[i] = if_info;
+ }
+
+ rc = 0;
+
+out:
+ return rc;
+}
diff --git a/lib/pb-protocol/pb-protocol.h b/lib/pb-protocol/pb-protocol.h
index aa79e66..5df7c7f 100644
--- a/lib/pb-protocol/pb-protocol.h
+++ b/lib/pb-protocol/pb-protocol.h
@@ -19,6 +19,7 @@ enum pb_protocol_action {
PB_PROTOCOL_ACTION_BOOT = 0x5,
PB_PROTOCOL_ACTION_STATUS = 0x6,
PB_PROTOCOL_ACTION_CANCEL_DEFAULT = 0x7,
+ PB_PROTOCOL_ACTION_SYSTEM_INFO = 0x8,
};
struct pb_protocol_message {
@@ -33,6 +34,7 @@ int pb_protocol_device_len(const struct device *dev);
int pb_protocol_boot_option_len(const struct boot_option *opt);
int pb_protocol_boot_len(const struct boot_command *boot);
int pb_protocol_boot_status_len(const struct boot_status *status);
+int pb_protocol_system_info_len(const struct system_info *sysinfo);
int pb_protocol_device_cmp(const struct device *a, const struct device *b);
int pb_protocol_boot_option_cmp(const struct boot_option *a,
@@ -50,6 +52,8 @@ int pb_protocol_serialise_boot_command(const struct boot_command *boot,
char *buf, int buf_len);
int pb_protocol_serialise_boot_status(const struct boot_status *status,
char *buf, int buf_len);
+int pb_protocol_serialise_system_info(const struct system_info *sysinfo,
+ char *buf, int buf_len);
int pb_protocol_write_message(int fd, struct pb_protocol_message *message);
@@ -70,4 +74,7 @@ int pb_protocol_deserialise_boot_command(struct boot_command *cmd,
int pb_protocol_deserialise_boot_status(struct boot_status *status,
const struct pb_protocol_message *message);
+int pb_protocol_deserialise_system_info(struct system_info *sysinfo,
+ const struct pb_protocol_message *message);
+
#endif /* _PB_PROTOCOL_H */
OpenPOWER on IntegriCloud