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