bc5a4fab3192ce5795f776d0b04d2ad09499b34a
[petitboot] / ui / common / discover-client.c
1
2 #include <unistd.h>
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <stdint.h>
6
7 #include <sys/socket.h>
8 #include <sys/un.h>
9 #include <asm/byteorder.h>
10
11 #include <talloc/talloc.h>
12
13 #include "ui/common/discover-client.h"
14 #include "ui/common/device.h"
15 #include "pb-protocol/pb-protocol.h"
16
17 struct discover_client {
18         int fd;
19         struct discover_client_ops ops;
20 };
21
22 static int discover_client_destructor(void *arg)
23 {
24         struct discover_client *client = arg;
25
26         if (client->fd >= 0)
27                 close(client->fd);
28
29         return 0;
30 }
31
32 struct discover_client* discover_client_init(struct discover_client_ops *ops)
33 {
34         struct discover_client *client;
35         struct sockaddr_un addr;
36
37         client = talloc(NULL, struct discover_client);
38         if (!client)
39                 return NULL;
40
41         memcpy(&client->ops, ops, sizeof(client->ops));
42
43         client->fd = socket(AF_UNIX, SOCK_STREAM, 0);
44         if (!client->fd < 0) {
45                 perror("socket");
46                 goto out_err;
47         }
48
49         talloc_set_destructor(client, discover_client_destructor);
50
51         addr.sun_family = AF_UNIX;
52         strcpy(addr.sun_path, PB_SOCKET_PATH);
53
54         if (connect(client->fd, (struct sockaddr *)&addr, sizeof(addr))) {
55                 perror("connect");
56                 goto out_err;
57         }
58
59         return client;
60
61 out_err:
62         talloc_free(client);
63         return NULL;
64 }
65
66 int discover_client_get_fd(struct discover_client *client)
67 {
68         return client->fd;
69 }
70
71 void discover_client_destroy(struct discover_client *client)
72 {
73         talloc_free(client);
74 }
75
76 int discover_client_process(struct discover_client *client)
77 {
78         struct pb_protocol_message *message;
79         struct device *dev;
80         char *dev_id;
81
82         message = pb_protocol_read_message(client, client->fd);
83
84         if (!message)
85                 return 0;
86
87         switch (message->action) {
88         case PB_PROTOCOL_ACTION_ADD:
89                 dev = pb_protocol_deserialise_device(client, message);
90                 if (!dev) {
91                         printf("no device?\n");
92                         return 0;
93                 }
94                 client->ops.add_device(dev);
95                 talloc_free(dev);
96                 break;
97         case PB_PROTOCOL_ACTION_REMOVE:
98                 dev_id = pb_protocol_deserialise_string(client, message);
99                 if (!dev_id) {
100                         printf("no device id?\n");
101                         return 0;
102                 }
103                 client->ops.remove_device(dev_id);
104                 break;
105         default:
106                 printf("unknown action %d\n", message->action);
107         }
108
109
110         return 0;
111 }