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#include "qemu/osdep.h"
28#include "chardev/char.h"
29#include "qemu/sockets.h"
30#include "qapi/error.h"
31#include "net/can_emu.h"
32#include "qom/object_interfaces.h"
33
34struct CanBusState {
35 Object object;
36
37 QTAILQ_HEAD(, CanBusClientState) clients;
38};
39
40static void can_bus_instance_init(Object *object)
41{
42 CanBusState *bus = (CanBusState *)object;
43
44 QTAILQ_INIT(&bus->clients);
45}
46
47int can_bus_insert_client(CanBusState *bus, CanBusClientState *client)
48{
49 client->bus = bus;
50 QTAILQ_INSERT_TAIL(&bus->clients, client, next);
51 return 0;
52}
53
54int can_bus_remove_client(CanBusClientState *client)
55{
56 CanBusState *bus = client->bus;
57 if (bus == NULL) {
58 return 0;
59 }
60
61 QTAILQ_REMOVE(&bus->clients, client, next);
62 client->bus = NULL;
63 return 1;
64}
65
66ssize_t can_bus_client_send(CanBusClientState *client,
67 const struct qemu_can_frame *frames, size_t frames_cnt)
68{
69 int ret = 0;
70 CanBusState *bus = client->bus;
71 CanBusClientState *peer;
72 if (bus == NULL) {
73 return -1;
74 }
75
76 QTAILQ_FOREACH(peer, &bus->clients, next) {
77 if (peer->info->can_receive(peer)) {
78 if (peer == client) {
79
80 continue;
81 }
82 if (peer->info->receive(peer, frames, frames_cnt) > 0) {
83 ret = 1;
84 }
85 }
86 }
87
88 return ret;
89}
90
91int can_bus_filter_match(struct qemu_can_filter *filter, qemu_canid_t can_id)
92{
93 int m;
94 if (((can_id | filter->can_mask) & QEMU_CAN_ERR_FLAG)) {
95 return (filter->can_mask & QEMU_CAN_ERR_FLAG) != 0;
96 }
97 m = (can_id & filter->can_mask) == (filter->can_id & filter->can_mask);
98 return filter->can_id & QEMU_CAN_INV_FILTER ? !m : m;
99}
100
101int can_bus_client_set_filters(CanBusClientState *client,
102 const struct qemu_can_filter *filters, size_t filters_cnt)
103{
104 return 0;
105}
106
107
108static bool can_bus_can_be_deleted(UserCreatable *uc)
109{
110 return false;
111}
112
113static void can_bus_class_init(ObjectClass *klass,
114 void *class_data G_GNUC_UNUSED)
115{
116 UserCreatableClass *uc_klass = USER_CREATABLE_CLASS(klass);
117
118 uc_klass->can_be_deleted = can_bus_can_be_deleted;
119}
120
121static const TypeInfo can_bus_info = {
122 .parent = TYPE_OBJECT,
123 .name = TYPE_CAN_BUS,
124 .instance_size = sizeof(CanBusState),
125 .instance_init = can_bus_instance_init,
126 .class_init = can_bus_class_init,
127 .interfaces = (InterfaceInfo[]) {
128 { TYPE_USER_CREATABLE },
129 { }
130 }
131};
132
133static void can_bus_register_types(void)
134{
135 type_register_static(&can_bus_info);
136}
137
138type_init(can_bus_register_types);
139