summaryrefslogtreecommitdiff
path: root/lib/avtp_pipeline/srp/openavb_srp.h
blob: c0d05e93d6fde717bf989cd4794e726d7cf283e9 (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
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
/*************************************************************************************************************
Copyright (c) 2012-2015, Symphony Teleca Corporation, a Harman International Industries, Incorporated company
Copyright (c) 2016-2017, Harman International Industries, Incorporated
All rights reserved.
 
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
 
1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.
 
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS LISTED "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS LISTED BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
Attributions: The inih library portion of the source code is licensed from 
Brush Technology and Ben Hoyt - Copyright (c) 2009, Brush Technology and Copyright (c) 2009, Ben Hoyt. 
Complete license and copyright information can be found at 
https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
*************************************************************************************************************/

/*
* HEADER SUMMARY :
*
* Implementation of IEEE 802.1Q
* Multiple Stream Reservation Protocol
* (limited initial implementation for end stations)
* 
* This file declares the "Private" portion - see also openavb_srp_api.h
*/

#ifndef OPENAVB_SRP_H
#define OPENAVB_SRP_H

#include "openavb_srp_api.h"
//#include "openavb_srp_osal.h"
#include "openavb_poll_osal.h"

enum {
	SRP_POLL_RAW_SOCK_FD = 0,
	SRP_POLL_FD_COUNT      // Must be the last entry.
};

// TBD - How often to [re]send (tx of the Applicant State Machine) - should be configurable
#define OPENAVB_SRP_TX_PERIOD_SEC  10

#define openavbSrp_PROTO_VERSION  0x00 // IEEE 802.1Q-2011 Section 35.2.2.3
#define openavbSrp_ETHERTYPE  0x22EA // there should be a more general define for this someplace with other ether types

// SR Class Id values are fixed. Priority (PCP) and VLAN Id values
// have defaults specified, but should be configurable - TBD
// Tables referenced here are per IEEE 802.1Q-2011
// SR Class - SR Class Id - SR Class Priority -  SR Class VID
//    -        Table 35-7       Table 6-6         Table 9-2
//    A           6                3                 2
//    B           5                2                 2

// SR Class IDs are defined here - used only in SRP messages
#define SR_CLASS_A_ID 6
#define SR_CLASS_B_ID 5

// SR Class default Priority (PCP) values per IEEE 802.1Q-2011 Table 6-6
#define SR_CLASS_A_DEFAULT_PRIORITY 3
#define SR_CLASS_B_DEFAULT_PRIORITY 2
// SR Class default VLAN Id values per IEEE 802.1Q-2011 Table 9-2
#define SR_CLASS_A_DEFAULT_VID 2
#define SR_CLASS_B_DEFAULT_VID 2

// SR Class default delta bandwidth values per IEEE 802.1Q-2011 Section 34.3.1
#define SR_CLASS_A_DEFAULT_DELTA_BW  75
#define SR_CLASS_B_DEFAULT_DELTA_BW   0

// SR Class Measurement Intervals / Frames Per Second
// - see IEEE 802.1Q-2011 Sections 34.6.1 and 35.2.2.8.4 and Table 35-5
// Class   Class Measurement Interval   Frames per Second
//   A        125 uSec       1 / .000125 = 8000
//   B        250 uSec       1 / .000250 = 4000
#define SR_CLASS_A_FPS  8000
#define SR_CLASS_B_FPS  4000


// Ethernet Frame DA for openavbSrp packets is the
// “Individual LAN Scope group address, Nearest Bridge group address” (per IEEE 802.1Q)
static const U8 openavbSrpDA[ETH_MAC_ADDR_LEN] = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x0E };

enum openavbSrpAttributeLength { // IEEE 802.1Q-2011 Table 35-2
	openavbSrp_AtLen_Lsnr    = 0x08,
	openavbSrp_AtLen_TlkrAdv = 0x19, // (= 25)
	openavbSrp_AtLen_TlkrFld = 0x22, // (= 34)
	openavbSrp_AtLen_Domain  = 0x04
};

// openavbSrp Attribute Event (aka "ThreePacked Events") - IEEE 802.1Q-2011 Section 35.2.2.7.1
typedef enum openavbSrpAtEvt {
	openavbSrp_AtEvt_New    = 0x00,
	openavbSrp_AtEvt_JoinIn = 0x01,
	openavbSrp_AtEvt_In     = 0x02,
	openavbSrp_AtEvt_JoinMt = 0x03,
	openavbSrp_AtEvt_Mt     = 0x04,
	openavbSrp_AtEvt_Leave  = 0x05,
	openavbSrp_AtEvt_None
} openavbSrpAtEvt_t;

typedef struct openavbSrpSockInfo {
	void* rawTxSock;
	void* rawRxSock;
	int   RxSock;
} openavbSrpSockInfo_t;

typedef struct avtpCallbacks {
	strmAttachCb_t  attachCb;
	strmRegCb_t     registerCb;
} avtpCallbacks_t;

typedef struct SrClassParameters {
	U8  priority;
	U16 vid;
	U32 operIdleSlope;  // currently reserved bandwidth - bits per second
	U32 deltaBandwidth; // %
	                    // TBD - deltaBandwidth is supposed to be scaled by 1,000,000
	                    //       (100,000,000 == 100%), but it is NOT in this current implementation
	U32 inverseIntervalSec; // 1/classMeasurementInterval (in seconds)
} SrClassParameters_t;

// Applicant State - IEEE 802.1Q Table 10-3
// State here are simplified because:
// - we are supporting point-to-point only and
// - initial declaration sends are immediate so there is no need for VP and VN
typedef enum openavbSrpAppState {
	openavbSrp_ApSt_VO = 0x00, // no declarations - note that we initialize to 0
	openavbSrp_ApSt_AN = 0x01, // [at least] one new  sent - one more pending
	openavbSrp_ApSt_AA = 0x02, // [at least] one join sent - one more pending
	openavbSrp_ApSt_QA = 0x03, // at least two new or join sent - none pending
	openavbSrp_ApSt_LA = 0x04, // one leave sent - one more pending
	openavbSrp_ApSt_VN = 0x05, // first new pending
} openavbSrpAppState_t;

// Registrar State - IEEE 802.1Q Table 10-4
typedef enum openavbSrpRegState {
	openavbSrp_RgSt_MT = 0x00, // Empty - note that we initialize to 0
	openavbSrp_RgSt_LV = 0x01, // Leave
	openavbSrp_RgSt_IN = 0x02, // In
} openavbSrpRegState_t;


// Element for linked list of declared / registered streams.
// Since both a talker and a listener can exist for the same stream on the same
// end-station, separate talker and listener lists are kept.
// IMPORTANT NOTE: This implementation assumes that on a given end-station, no
// more than one talker and no more than one listener exist for each stream; if
// this is not the case, individual stream list elements could be corrupted
// because they are not thread-safe; the overall lists are mutex protected.
//
// On talker:
//   a list entry will exist only if the talker has a stream to declare
//   (or is in the process of withdrawing)
//   - declType is what this talker has most recently declared;
//   - declSubType is not used;
//   - regType / regSubType indicate what the talker has most recently received from
//     the listener(s), if anything;
//   - avtpHandle, streamId, DA, tSpec, SRClassId, Rank, and Latency
//     are as received from AVTP via openavbSrpRegisterStream();
//   - failInfo is populated only if this station has insufficient outbound
//     bandwidth for this stream, so must send Talker Failed declaration;
//   - kbpsReserved is the bandwidth currently reserved for the stream.
//
// On Listener: 
//   a list entry will exist if the listener has either expressed interest in
//   receiving the stream (or is in the process of withdrawing interest) or has
//   received a talker declaration for the stream, or both.
//   - declType is what this listener has most recently declared (via
//     openavbSrpAttachStream()), if anything;
//   - declSubType is the listener declaration subtype, if any;
//   - regType indicates what talker declaration the listener has most recently
//     received for the stream, if anything; (openavbSrp_AtTyp_None indicates that
//     the listener currently has no talker declaration for the stream);
//   - regSubType is not used;
//   - avtpHandle is as received from AVTP via openavbSrpAttachStream();
//   - strmId is either as received from AVTP via openavbSrpAttachStream() or
//     as received via a talker declaration packet (MSRPDU), whichever occurs first;
//   - SRClassIdx is derived from priority received in talker declaration packet;
//   - DA, tSpec, latency, and, if applicable, failInfo are
//     as received in talker declaration packet
//   - rank and kbpsReserved are not applicable on the listener;
//
typedef struct openavbSrpStrm {
	struct openavbSrpStrm*      prev;
	struct openavbSrpStrm*      next;
	AVBStreamID_t           strmId;
	void*                   avtpHandle;
	SRClassIdx_t            SRClassIdx;
	openavbSrpAttribType_t      declType;    // attribute type this station is declaring for this stream, if any;
	                                     // (declType == openavbSrp_AtTyp_None is redundant to appState == openavbSrp_ApSt_VO).
	openavbSrpLsnrDeclSubtype_t declSubType; // listener subtype this station is declaring for this stream, if any;
	                                     // not used on talker; valid only if declType == openavbSrp_AtTyp_Listener.
	openavbSrpAttribType_t      regType;     // attribute type   this station has received (registered) for this stream, if any;
	openavbSrpLsnrDeclSubtype_t regSubType;  // listener subtype this station has received (registered) for this stream, if any;
	                                     // not used on listener; valid only if regType == openavbSrp_AtTyp_Listener.
	U8                      DA[ETH_MAC_ADDR_LEN];
	AVBTSpec_t              tSpec;
	U32                     kbpsReserved;
	bool                    rank;
	U32                     latency;
	openavbSrpFailInfo_t        failInfo;
	openavbSrpAppState_t        appState; // current applicant state of the stream on this station
	openavbSrpRegState_t        regState;
} openavbSrpStrmElem_t;


// SRP internal routines
int               openavbSrpGetIndexFromId   (U8 SRClassId);
void              openavbSrpRemoveStrm       (openavbSrpStrmElem_t** lstHead, openavbSrpStrmElem_t* pStream);
openavbSrpStrmElem_t* openavbSrpFindOrCreateStrm (openavbSrpStrmElem_t** lstHead, AVBStreamID_t* streamId,
                                          bool allowCreate, bool* created);
void              openavbSrpLogBw            (void);
void              openavbSrpLogAllStreams    (void);
void              openavbSrpRegState         (openavbSrpAttribType_t atrbType);
void              openavbSrpCheckAsCapable   (void);
void              openavbSrpCheckTalkerFailed(void);
void              openavbSrpResend           (bool tx, openavbSrpAttribType_t atrbType);
void*             openavbSrpTxThread         (void* notUsed);
void*             openavbSrpRcvThread        (void* notUsed);
openavbRC          openavbSrpCheckStartLsnr   (openavbSrpStrmElem_t* stream);
openavbRC          openavbSrpDomainSend       (void);
openavbRC          openavbSrpSend             (openavbSrpStrmElem_t* pStream, openavbSrpAtEvt_t atrbEvent);
void              openavbSrpReceive          (U8* msrpdu,  unsigned int pduLen);
void              openavbSrpCalcKbps         (int SRClassIndex, AVBTSpec_t* tSpec, U32* kbps);
openavbRC          openavbSrpCheckAvlBw       (int SRClassIndex, U32 kbps);
openavbRC          openavbSrpReserve          (openavbSrpStrmElem_t* pStream);
void              openavbSrpRelease          (openavbSrpStrmElem_t* pStream);

openavbRC          openavbSrpOpenPtpSharedMemory   (void);
void              openavbSrpReleasePtpSharedMemory(void);
bool              openavbSrpAsCapable             (void);

int               openavbSrpInitializePfd    (OPENAVB_POLLFD_TYPE *pfd);

// First Value content and size depend on the Declaration Type (openavbSrpAttribType_t)
// see IEEE 802.1Q-2011 Section 35.2.2.8.1
// (left column indicates byte index to start of parameter)
// 	FirstValue ::= 
// 	 0	StreamID: 8 bytes
// 	 0		[Src] MAC: 6 bytes (ETH_MAC_ADDR_LEN)
// 	 6		UniqueID: 2 bytes, U16
// 		end of the Listener attribute 
// 	 8	DataFrameParameters: 8 bytes
// 	 8		DA: 6 bytes (ETH_MAC_ADDR_LEN)
// 	14		VID: 2 bytes
// 	16	TSpec: 4 bytes
// 	16		MaxFrameSize: 2 bytes, U16
// 	18		MaxIntervalFrames: 2 bytes, U16
// 	20	PriorityAndRank: 1 byte
// 	20		Priority: 3 bits
// 	20		Rank: 1 bit
// 	20		Reserved: 4 bits
// 	21	AccumulatedLatency: 4 bytes, U32
// 		end of the Talker Advertise attribute
// 	25	FailureInformation: 9 bytes
// 	25		BridgeID: 8 bytes
// 	33		FailureCode: 1 byte
// 		end of the Talker Failed attribute


/* description of the limited MSRPDU being supported here
 * (currently, only one declaration per packet is supported)
 * openavbSrpDU ::= ProtocolVersion, Message
 * 	ProtocolVersion BYTE ::= 0x00
 * 	Message ::= AttributeType, AttributeLength [, AttributeListLength], AttributeList
 * 		AttributeType BYTE ::= Talker Advertise | Talker Failed | Listener
 * 			Talker Advertise::= 0x01
 * 			Talker Failed::= 0x02
 * 			Listener::= 0x03
 * 		AttributeLength BYTE ::= 0x19 | 0x34 | 0x08
 * 		AttributeListLength SHORT ::= AttributeLength  + 3 | 4 (4 only if AttributeType  = Listener)
 * 		AttributeList ::= VectorAttribute {, VectorAttribute}, EndMark
 * 			VectorAttribute ::= VectorHeader, FirstValue, Vector
 * 				VectorHeader SHORT ::= 0x0001
 * 				FirstValue ::= 
 * 					StreamID: 8 bytes
 * 						[Src] MAC: 6 bytes
 * 						UniqueID: 2 bytes, U16
 * 					end of the Listener attribute 
 * 					DataFrameParameters: 8 bytes
 * 						DA: 6 bytes
 * 						VID: 2 bytes
 * 					TSpec: 4 bytes
 * 						MaxFrameSize: 2 bytes, U16
 * 						MaxIntervalFrames: 2 bytes, U16
 * 					PriorityAndRank: 1 byte
 * 						Priority: 3 bits
 * 						Rank: 1 bit
 * 						Reserved: 4 bits
 * 					AccumulatedLatency: 4 bytes, U32
 * 					end of the Talker Advertise attribute
 * 					FailureInformation: 9 bytes
 * 						BridgeID: 8 bytes
 * 						FailureCode: 1 byte
 * 					end of the Talker Failed attribute
 * 				Vector ::= ThreePackedEvent, [FourPackedEvent]
 * 					ThreePackedEvents BYTE ::= New |Lv
 * 							New ::= 0
 * 							Lv ::= 5
 * 					FourPackedEvents BYTE ::=  Asking Failed | Ready | Ready Failed
 * 					 (FourPackedEvents  is included only if AttributeType  = Listener)
 * 						Asking Failed ::= 1
 * 						Ready ::= 2
 * 						Ready Failed ::= 3
 */

#endif // OPENAVB_SRP_H