+ struct pb_protocol_message *message;
+ int len;
+
+ len = pb_protocol_boot_status_len(status);
+
+ message = pb_protocol_create_message(client,
+ PB_PROTOCOL_ACTION_STATUS, len);
+ if (!message)
+ return -1;
+
+ pb_protocol_serialise_boot_status(status, message->payload, len);
+
+ return client_write_message(server, client, message);
+}
+
+static int write_system_info_message(struct discover_server *server,
+ struct client *client, const struct system_info *sysinfo)
+{
+ struct pb_protocol_message *message;
+ int len;
+
+ len = pb_protocol_system_info_len(sysinfo);
+
+ message = pb_protocol_create_message(client,
+ PB_PROTOCOL_ACTION_SYSTEM_INFO, len);
+ if (!message)
+ return -1;
+
+ pb_protocol_serialise_system_info(sysinfo, message->payload, len);
+
+ return client_write_message(server, client, message);
+}
+
+static int write_config_message(struct discover_server *server,
+ struct client *client, const struct config *config)
+{
+ struct pb_protocol_message *message;
+ int len;
+
+ len = pb_protocol_config_len(config);
+
+ message = pb_protocol_create_message(client,
+ PB_PROTOCOL_ACTION_CONFIG, len);
+ if (!message)
+ return -1;
+
+ pb_protocol_serialise_config(config, message->payload, len);
+
+ return client_write_message(server, client, message);
+}
+
+static int discover_server_process_message(void *arg)
+{
+ struct pb_protocol_message *message;
+ struct boot_command *boot_command;
+ struct client *client = arg;
+ struct config *config;
+ char *url;
+ int rc;
+
+ message = pb_protocol_read_message(client, client->fd);
+
+ if (!message) {
+ talloc_free(client);
+ return 0;
+ }
+
+
+ switch (message->action) {
+ case PB_PROTOCOL_ACTION_BOOT:
+ boot_command = talloc(client, struct boot_command);
+
+ rc = pb_protocol_deserialise_boot_command(boot_command,
+ message);
+ if (rc) {
+ pb_log("%s: no boot command?", __func__);
+ return 0;
+ }
+
+ device_handler_boot(client->server->device_handler,
+ boot_command);
+ break;
+
+ case PB_PROTOCOL_ACTION_CANCEL_DEFAULT:
+ device_handler_cancel_default(client->server->device_handler);
+ break;
+
+ case PB_PROTOCOL_ACTION_REINIT:
+ device_handler_reinit(client->server->device_handler);
+ break;
+
+ case PB_PROTOCOL_ACTION_CONFIG:
+ config = talloc_zero(client, struct config);
+
+ rc = pb_protocol_deserialise_config(config, message);
+ if (rc) {
+ pb_log("%s: no config?", __func__);
+ return 0;
+ }