8 #include <sys/socket.h>
10 #include <asm/byteorder.h>
12 #include <talloc/talloc.h>
15 #include "ui/common/discover-client.h"
16 #include "pb-protocol/pb-protocol.h"
18 struct discover_client {
20 struct discover_client_ops ops;
22 struct device **devices;
25 static int discover_client_destructor(void *arg)
27 struct discover_client *client = arg;
35 struct discover_client* discover_client_init(
36 const struct discover_client_ops *ops)
38 struct discover_client *client;
39 struct sockaddr_un addr;
41 client = talloc(NULL, struct discover_client);
45 memcpy(&client->ops, ops, sizeof(client->ops));
47 client->fd = socket(AF_UNIX, SOCK_STREAM, 0);
48 if (!client->fd < 0) {
49 pb_log("%s: socket: %s\n", __func__, strerror(errno));
53 talloc_set_destructor(client, discover_client_destructor);
55 client->n_devices = 0;
56 client->devices = NULL;
58 addr.sun_family = AF_UNIX;
59 strcpy(addr.sun_path, PB_SOCKET_PATH);
61 if (connect(client->fd, (struct sockaddr *)&addr, sizeof(addr))) {
62 pb_log("%s: connect: %s\n", __func__, strerror(errno));
73 int discover_client_get_fd(const struct discover_client *client)
78 void discover_client_destroy(struct discover_client *client)
83 static void add_device(struct discover_client *client, struct device *device)
86 client->devices = talloc_realloc(client, client->devices,
87 struct device *, client->n_devices);
89 client->devices[client->n_devices - 1] = device;
90 talloc_steal(client, device);
92 client->ops.add_device(device, client->ops.cb_arg);
95 static void remove_device(struct discover_client *client, const char *id)
97 struct device *device = NULL;
100 for (i = 0; i < client->n_devices; i++) {
101 if (!strcmp(client->devices[i]->id, id)) {
102 device = client->devices[i];
110 /* remove the device from the client's device array */
112 memmove(&client->devices[i], &client->devices[i+1],
113 client->n_devices - i);
114 client->devices = talloc_realloc(client, client->devices,
115 struct device *, client->n_devices);
118 client->ops.remove_device(device, client->ops.cb_arg);
123 int discover_client_process(struct discover_client *client)
125 struct pb_protocol_message *message;
129 message = pb_protocol_read_message(client, client->fd);
134 switch (message->action) {
135 case PB_PROTOCOL_ACTION_ADD:
136 dev = pb_protocol_deserialise_device(client, message);
138 pb_log("%s: no device?\n", __func__);
142 add_device(client, dev);
144 case PB_PROTOCOL_ACTION_REMOVE:
145 dev_id = pb_protocol_deserialise_string(client, message);
147 pb_log("%s: no device id?\n", __func__);
150 remove_device(client, dev_id);
153 pb_log("%s: unknown action %d\n", __func__, message->action);
160 /* accessors for discovered devices */
161 int discover_client_device_count(struct discover_client *client)
163 return client->n_devices;
166 struct device *discover_client_get_device(struct discover_client *client,
169 if (index < 0 || index >= client->n_devices)
172 return client->devices[index];