summaryrefslogtreecommitdiffstats
path: root/src/modules/module-avb/mrp.h
blob: 0a05d4b4da34878bec760e169da1581e13f90b96 (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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
/* AVB support
 *
 * Copyright © 2022 Wim Taymans
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

#ifndef AVB_MRP_H
#define AVB_MRP_H

#include "packets.h"
#include "internal.h"

#define AVB_MRP_PROTOCOL_VERSION	0

struct avb_packet_mrp {
	struct avb_ethernet_header eth;
	uint8_t version;
} __attribute__ ((__packed__));

struct avb_packet_mrp_hdr {
	uint8_t attribute_type;
	uint8_t attribute_length;
} __attribute__ ((__packed__));

struct avb_packet_mrp_vector {
#if __BYTE_ORDER == __BIG_ENDIAN
	unsigned lva:3;
	unsigned nv1:5;
#elif __BYTE_ORDER == __LITTLE_ENDIAN
	unsigned nv1:5;
	unsigned lva:3;
#endif
	uint8_t nv2;
	uint8_t first_value[0];
} __attribute__ ((__packed__));

#define AVB_MRP_VECTOR_SET_NUM_VALUES(a,v)	((a)->nv1 = ((v) >> 8),(a)->nv2 = (v))
#define AVB_MRP_VECTOR_GET_NUM_VALUES(a)	((a)->nv1 << 8 | (a)->nv2)

struct avb_packet_mrp_footer {
	uint16_t end_mark;
} __attribute__ ((__packed__));

/* applicant states */
#define AVB_MRP_VO	0		/* Very anxious Observer */
#define AVB_MRP_VP	1		/* Very anxious Passive */
#define AVB_MRP_VN	2		/* Very anxious New */
#define AVB_MRP_AN	3		/* Anxious New */
#define AVB_MRP_AA	4		/* Anxious Active */
#define AVB_MRP_QA	5		/* Quiet Active */
#define AVB_MRP_LA	6		/* Leaving Active */
#define AVB_MRP_AO	7		/* Anxious Observer */
#define AVB_MRP_QO	8		/* Quiet Observer */
#define AVB_MRP_AP	9		/* Anxious Passive */
#define AVB_MRP_QP	10		/* Quiet Passive */
#define AVB_MRP_LO	11		/* Leaving Observer */

/* registrar states */
#define AVB_MRP_IN	16
#define AVB_MRP_LV	17
#define AVB_MRP_MT	18

/* events */
#define AVB_MRP_EVENT_BEGIN		0
#define AVB_MRP_EVENT_NEW		1
#define AVB_MRP_EVENT_JOIN		2
#define AVB_MRP_EVENT_LV		3
#define AVB_MRP_EVENT_TX		4
#define AVB_MRP_EVENT_TX_LVA		5
#define AVB_MRP_EVENT_TX_LVAF		6
#define AVB_MRP_EVENT_RX_NEW		7
#define AVB_MRP_EVENT_RX_JOININ		8
#define AVB_MRP_EVENT_RX_IN		9
#define AVB_MRP_EVENT_RX_JOINMT		10
#define AVB_MRP_EVENT_RX_MT		11
#define AVB_MRP_EVENT_RX_LV		12
#define AVB_MRP_EVENT_RX_LVA		13
#define AVB_MRP_EVENT_FLUSH		14
#define AVB_MRP_EVENT_REDECLARE		15
#define AVB_MRP_EVENT_PERIODIC		16
#define AVB_MRP_EVENT_LV_TIMER		17
#define AVB_MRP_EVENT_LVA_TIMER		18

/* attribute events */
#define AVB_MRP_ATTRIBUTE_EVENT_NEW	0
#define AVB_MRP_ATTRIBUTE_EVENT_JOININ	1
#define AVB_MRP_ATTRIBUTE_EVENT_IN	2
#define AVB_MRP_ATTRIBUTE_EVENT_JOINMT	3
#define AVB_MRP_ATTRIBUTE_EVENT_MT	4
#define AVB_MRP_ATTRIBUTE_EVENT_LV	5

#define AVB_MRP_SEND_NEW		1
#define AVB_MRP_SEND_JOININ		2
#define AVB_MRP_SEND_IN			3
#define AVB_MRP_SEND_JOINMT		4
#define AVB_MRP_SEND_MT			5
#define AVB_MRP_SEND_LV			6

#define AVB_MRP_NOTIFY_NEW		1
#define AVB_MRP_NOTIFY_JOIN		2
#define AVB_MRP_NOTIFY_LEAVE		3

const char *avb_mrp_notify_name(uint8_t notify);
const char *avb_mrp_send_name(uint8_t send);

struct avb_mrp_attribute {
	uint8_t pending_send;
	void *user_data;
};

struct avb_mrp_attribute_events {
#define AVB_VERSION_MRP_ATTRIBUTE_EVENTS	0
	uint32_t version;

	void (*notify) (void *data, uint64_t now, uint8_t notify);
};

struct avb_mrp_attribute *avb_mrp_attribute_new(struct avb_mrp *mrp,
		size_t user_size);
void avb_mrp_attribute_destroy(struct avb_mrp_attribute *attr);

void avb_mrp_attribute_update_state(struct avb_mrp_attribute *attr, uint64_t now, int event);

void avb_mrp_attribute_rx_event(struct avb_mrp_attribute *attr, uint64_t now, uint8_t event);

void avb_mrp_attribute_begin(struct avb_mrp_attribute *attr, uint64_t now);
void avb_mrp_attribute_join(struct avb_mrp_attribute *attr, uint64_t now, bool is_new);
void avb_mrp_attribute_leave(struct avb_mrp_attribute *attr, uint64_t now);

void avb_mrp_attribute_add_listener(struct avb_mrp_attribute *attr, struct spa_hook *listener,
		const struct avb_mrp_attribute_events *events, void *data);

struct avb_mrp_parse_info {
#define AVB_VERSION_MRP_PARSE_INFO	0
	uint32_t version;

	bool (*check_header) (void *data, const void *hdr, size_t *hdr_size, bool *has_params);

	int (*attr_event) (void *data, uint64_t now, uint8_t attribute_type, uint8_t event);

	int (*process) (void *data, uint64_t now, uint8_t attribute_type, const void *value,
			uint8_t event, uint8_t param, int index);
};

int avb_mrp_parse_packet(struct avb_mrp *mrp, uint64_t now, const void *pkt, int size,
		const struct avb_mrp_parse_info *cb, void *data);

struct avb_mrp_events {
#define AVB_VERSION_MRP_EVENTS	0
	uint32_t version;

	void (*event) (void *data, uint64_t now, uint8_t event);

	void (*notify) (void *data, uint64_t now, struct avb_mrp_attribute *attr, uint8_t notify);
};

struct avb_mrp *avb_mrp_new(struct server *server);
void avb_mrp_destroy(struct avb_mrp *mrp);

void avb_mrp_add_listener(struct avb_mrp *mrp, struct spa_hook *listener,
		const struct avb_mrp_events *events, void *data);

#endif /* AVB_MRP_H */