-
Notifications
You must be signed in to change notification settings - Fork 2
/
EFPBonding.h
173 lines (142 loc) · 6.69 KB
/
EFPBonding.h
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
// Copyright Edgeware AB 2020, Agile Content 2021-2022
//Methods are NOT thread safe meaning you may only call all methods from the same thread as calling distributeDataGroup
// Prefixes used
// m class member
// p pointer (*)
// r reference (&)
// h part of header
// l local scope
#ifndef EFPBOND__EFPBONDING_H
#define EFPBOND__EFPBONDING_H
#include <vector>
#include <iostream>
#include <tuple>
#include <memory>
#include <functional>
#define EFP_BONDING_MAJOR_VERSION 1
#define EFP_BONDING_MINOR_VERSION 0
#define EFP_MASTER_INTERFACE true
#define EFP_NORMAL_INTERFACE false
enum class EFPBondingMessages : int16_t {
interfaceIDNotFound = -10000, // Interface ID not found
groupNotFound, // Group ID not found
parameterError, // The parameters given when changing the commit for the interfaces are out of spec.
interfaceAlreadyAdded, // The interface is already added to the EFP-Stream
noError = 0, // No error
sumCommitHigherThan100Percent, // Total commit higher than 100%
noGroupsFound, // The list of groups is empty
fragmentNotSent // No interface was sending this fragment
};
class EFPBonding {
public:
///@EFPBondingInterfaceID unique id of the single interface used by the EFPBonding class
typedef uint64_t EFPBondingInterfaceID;
///@EFPBondingGroupID unique id of the group interface used by the EFPBonding class
typedef uint64_t EFPBondingGroupID;
///EFPStatistics
///@mNoGapsCoveredFor number of fragments this interface has covered for
///@mNoFragmentsSent fragments sent by this interface
///@mPercentOfTotalTraffic % of total traffic sent by EFPBonding has been sent by this interface
class EFPStatistics {
public:
uint64_t mNoGapsCoveredFor = 0;
uint64_t mNoFragmentsSent = 0;
double mPercentOfTotalTraffic = 0.0;
};
///EFPInterface
///@mInterfaceID The unique ID of this interface
///@mFireCounter The fragment counter for this interface (The commit counter)
///@mFragmentCounter Number of fragments sent trough this interface
///@mForwardMissingFragment The number of fragments sent trough this interface due to calculation fractions
///@mInterfaceLocation The location of the interface callback
///@mMasterInterface If this is the master interface
///@mCommit % of total traffic this interface committed to.
class EFPInterface {
public:
explicit EFPInterface(std::function<void(const std::vector<uint8_t> &)> interfaceLocation = nullptr, EFPBonding::EFPBondingInterfaceID interfaceID = 0, bool masterInterface = EFP_NORMAL_INTERFACE) {
mInterfaceID = interfaceID;
mInterfaceLocation = interfaceLocation;
mMasterInterface = masterInterface;
}
EFPBondingInterfaceID mInterfaceID = 0;
double mFireCounter = 0.0;
uint64_t mFragmentCounter = 0;
uint64_t mForwardMissingFragment = 0;
std::function<void(const std::vector<uint8_t> &)> mInterfaceLocation = nullptr;
bool mMasterInterface = EFP_NORMAL_INTERFACE;
double mCommit = 0.0;
};
///EFPGroup
///@mGroupID Group ID
///@mGroupInterfaces The list of interfaces belonging to this group
class EFPGroup {
public:
EFPBondingGroupID mGroupID = 0;
std::vector<std::shared_ptr<EFPInterface>> mGroupInterfaces;
};
///EFPInterfaceCommit
///@mCommit commit value %
///@mInterfaceID The interface ID
class EFPInterfaceCommit {
public:
explicit EFPInterfaceCommit(double commit, EFPBonding::EFPBondingInterfaceID interfaceID) {
mCommit = commit;
mInterfaceID = interfaceID;
}
double mCommit = 0.0;
EFPBonding::EFPBondingInterfaceID mInterfaceID = 0;
};
///Constructor
explicit EFPBonding();
///Destructor
virtual ~EFPBonding();
///Delete copy and move constructors and assign operators
EFPBonding(EFPBonding const &) = delete; // Copy construct
EFPBonding(EFPBonding &&) = delete; // Move construct
EFPBonding &operator=(EFPBonding const &) = delete; // Copy assign
EFPBonding &operator=(EFPBonding &&) = delete; // Move assign
///Return the version of the current implementation
uint16_t getVersion() { return (EFP_BONDING_MAJOR_VERSION << 8) | EFP_BONDING_MINOR_VERSION; }
///Returns the statistics fo a interface
///@interfaceID the ID of the interface to get statistics for
///@groupID the ID of the group to get statistics for if not provided the statistics will be from a interface not belonging to a group.
///@reset resets the packet counter for the interface
EFPStatistics getStatistics(EFPBonding::EFPBondingInterfaceID interfaceID, EFPBonding::EFPBondingGroupID groupID, bool reset);
///Modify listed interfaces commit level for a group
///@rInterfacesCommit a vector of new % commits for the interfaces specified in EFPInterfaceCommit
///@groupID the ID of the group
EFPBondingMessages modifyInterfaceCommits(std::vector<EFPBonding::EFPInterfaceCommit> &rInterfacesCommit, EFPBonding::EFPBondingGroupID groupID);
///Returns the total number of fragments handled with by EFPBonding
uint64_t getGlobalPacketCounter();
///adds 1 to the global packet counter
void increaseGlobalPacketCounter();
///re-sets the global packet counter
void clearGlobalPacketCounter();
///Returns a unique interfaceID
///To be used when creating new interfaces
EFPBondingInterfaceID generateInterfaceID();
///Adds a group of interfaces to EFPBonding
///@rInterfaces A list/vector of EFPInterfaces to be grouped together
EFPBondingGroupID addInterfaceGroup(std::vector<EFPInterface> &rInterfaces);
///Distributes the data to all groups registerd
///@rSubPacket the data to be distributed
///@fragmentID the EFP stream ID this fragment belongs to.
EFPBondingMessages distributeData(const std::vector<uint8_t> &rSubPacket, uint8_t fragmentID);
///Split fragments based on fragmentID to registerd interfaces
///@rSubPacket the data to be distributed
///@fragmentID the EFP stream ID this fragment belongs to.
EFPBondingMessages splitData(const std::vector<uint8_t> &rSubPacket, uint8_t fragmentID);
///Removes a interface group from EFPBonding
///@groupID the ID of the group to remove
EFPBondingMessages removeGroup(EFPBondingGroupID groupID);
EFPBondingMessages addInterfaceToStreamID(EFPInterface interface, std::vector<uint8_t> &rEFPIDList);
EFPBondingMessages removeInterfaceFromStreamID(EFPBondingInterfaceID interfaceID, std::vector<uint8_t> &rEFPIDList);
private:
uint64_t mGlobalPacketCounter = 0;
uint64_t mMonotonicPacketCounter = 0;
EFPBondingInterfaceID mUniqueInterfaceID = 1;
EFPBondingGroupID mUniqueGroupID = 1;
std::vector<EFPGroup> mGroupList;
std::vector<std::vector<EFPInterface>> mStreamInterfaces;
};
#endif //EFPBOND__EFPBONDING_H