summaryrefslogtreecommitdiffstats
path: root/ui/common/discover-client.c
blob: 112fa65782e88e910e2ba3c11a03e1bb637b6ed2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112

#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>

#include <sys/socket.h>
#include <sys/un.h>
#include <asm/byteorder.h>

#include <talloc/talloc.h>
#include <log.h>

#include "ui/common/discover-client.h"
#include "pb-protocol/pb-protocol.h"

struct discover_client {
	int fd;
	struct discover_client_ops ops;
};

static int discover_client_destructor(void *arg)
{
	struct discover_client *client = arg;

	if (client->fd >= 0)
		close(client->fd);

	return 0;
}

struct discover_client* discover_client_init(struct discover_client_ops *ops)
{
	struct discover_client *client;
	struct sockaddr_un addr;

	client = talloc(NULL, struct discover_client);
	if (!client)
		return NULL;

	memcpy(&client->ops, ops, sizeof(client->ops));

	client->fd = socket(AF_UNIX, SOCK_STREAM, 0);
	if (!client->fd < 0) {
		pb_log("%s: socket: %s\n", __func__, strerror(errno));
		goto out_err;
	}

	talloc_set_destructor(client, discover_client_destructor);

	addr.sun_family = AF_UNIX;
	strcpy(addr.sun_path, PB_SOCKET_PATH);

	if (connect(client->fd, (struct sockaddr *)&addr, sizeof(addr))) {
		pb_log("%s: connect: %s\n", __func__, strerror(errno));
		goto out_err;
	}

	return client;

out_err:
	talloc_free(client);
	return NULL;
}

int discover_client_get_fd(struct discover_client *client)
{
	return client->fd;
}

void discover_client_destroy(struct discover_client *client)
{
	talloc_free(client);
}

int discover_client_process(struct discover_client *client)
{
	struct pb_protocol_message *message;
	struct device *dev;
	char *dev_id;

	message = pb_protocol_read_message(client, client->fd);

	if (!message)
		return -1;

	switch (message->action) {
	case PB_PROTOCOL_ACTION_ADD:
		dev = pb_protocol_deserialise_device(client, message);
		if (!dev) {
			pb_log("%s: no device?\n", __func__);
			return 0;
		}
		client->ops.add_device(dev, client->ops.cb_arg);
		talloc_free(dev);
		break;
	case PB_PROTOCOL_ACTION_REMOVE:
		dev_id = pb_protocol_deserialise_string(client, message);
		if (!dev_id) {
			pb_log("%s: no device id?\n", __func__);
			return 0;
		}
		client->ops.remove_device(dev_id, client->ops.cb_arg);
		break;
	default:
		pb_log("%s: unknown action %d\n", __func__, message->action);
	}


	return 0;
}
OpenPOWER on IntegriCloud