+#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <asm/byteorder.h>
#include <talloc/talloc.h>
+#include <log/log.h>
#include "ui/common/discover-client.h"
#include "pb-protocol/pb-protocol.h"
struct discover_client {
int fd;
struct discover_client_ops ops;
+ int n_devices;
+ struct device **devices;
};
static int discover_client_destructor(void *arg)
return 0;
}
-struct discover_client* discover_client_init(struct discover_client_ops *ops)
+struct discover_client* discover_client_init(
+ const struct discover_client_ops *ops, void *cb_arg)
{
struct discover_client *client;
struct sockaddr_un addr;
return NULL;
memcpy(&client->ops, ops, sizeof(client->ops));
+ client->ops.cb_arg = cb_arg;
client->fd = socket(AF_UNIX, SOCK_STREAM, 0);
- if (!client->fd < 0) {
- perror("socket");
+ if (client->fd < 0) {
+ pb_log("%s: socket: %s\n", __func__, strerror(errno));
goto out_err;
}
talloc_set_destructor(client, discover_client_destructor);
+ client->n_devices = 0;
+ client->devices = NULL;
+
addr.sun_family = AF_UNIX;
strcpy(addr.sun_path, PB_SOCKET_PATH);
if (connect(client->fd, (struct sockaddr *)&addr, sizeof(addr))) {
- perror("connect");
+ pb_log("%s: connect: %s\n", __func__, strerror(errno));
goto out_err;
}
return NULL;
}
-int discover_client_get_fd(struct discover_client *client)
+int discover_client_get_fd(const struct discover_client *client)
{
return client->fd;
}
talloc_free(client);
}
+static void device_add(struct discover_client *client, struct device *device)
+{
+ client->n_devices++;
+ client->devices = talloc_realloc(client, client->devices,
+ struct device *, client->n_devices);
+
+ client->devices[client->n_devices - 1] = device;
+ talloc_steal(client, device);
+
+ client->ops.device_add(device, client->ops.cb_arg);
+}
+
+static void device_remove(struct discover_client *client, const char *id)
+{
+ struct device *device = NULL;
+ int i;
+
+ for (i = 0; i < client->n_devices; i++) {
+ if (!strcmp(client->devices[i]->id, id)) {
+ device = client->devices[i];
+ break;
+ }
+ }
+
+ if (!device)
+ return;
+
+ /* remove the device from the client's device array */
+ client->n_devices--;
+ memmove(&client->devices[i], &client->devices[i+1],
+ (client->n_devices - i) * sizeof(client->devices[0]));
+ client->devices = talloc_realloc(client, client->devices,
+ struct device *, client->n_devices);
+
+ /* notify the UI */
+ client->ops.device_remove(device, client->ops.cb_arg);
+
+ talloc_free(device);
+}
+
int discover_client_process(struct discover_client *client)
{
struct pb_protocol_message *message;
case PB_PROTOCOL_ACTION_ADD:
dev = pb_protocol_deserialise_device(client, message);
if (!dev) {
- printf("no device?\n");
+ pb_log("%s: no device?\n", __func__);
return 0;
}
- client->ops.add_device(dev);
- talloc_free(dev);
+
+ device_add(client, dev);
break;
case PB_PROTOCOL_ACTION_REMOVE:
dev_id = pb_protocol_deserialise_string(client, message);
if (!dev_id) {
- printf("no device id?\n");
+ pb_log("%s: no device id?\n", __func__);
return 0;
}
- client->ops.remove_device(dev_id);
+ device_remove(client, dev_id);
break;
default:
- printf("unknown action %d\n", message->action);
+ pb_log("%s: unknown action %d\n", __func__, message->action);
}
return 0;
}
+
+/* accessors for discovered devices */
+int discover_client_device_count(struct discover_client *client)
+{
+ return client->n_devices;
+}
+
+struct device *discover_client_get_device(struct discover_client *client,
+ int index)
+{
+ if (index < 0 || index >= client->n_devices)
+ return NULL;
+
+ return client->devices[index];
+}