-
Notifications
You must be signed in to change notification settings - Fork 14
/
DlepService.h
303 lines (277 loc) · 13.1 KB
/
DlepService.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
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
/*
* Dynamic Link Exchange Protocol (DLEP)
*
* Copyright (C) 2015, 2016, 2019 Massachusetts Institute of Technology
*/
/// @file
/// This is the abstract interface that the DLEP service
/// (library) must present to the DLEP client (library user).
/// I.e., the DLEP service implements this interface and the
/// DLEP client calls it.
/// Clients should include this file indirectly by including DlepInit.h.
#ifndef DLEP_SERVICE_H
#define DLEP_SERVICE_H
#include <vector>
#include "DlepCommon.h"
#include "ProtocolConfig.h"
namespace LLDLEP
{
/// This is the abstract interface that the DLEP service (library)
/// must present to the DLEP client (library user).
///
/// At library initialization time (DlepInit), the library returns a
/// pointer to an object that implements the DlepService interface.
/// The DLEP client calls these methods to provide information,
/// primarily about destinations, to the DLEP service. The DLEP
/// service subclasses from this class and implements all of the
/// required methods. The DLEP client calls these methods from its
/// own internal threads, distinct from the service's threads. The
/// service must be prepared for this, possibly implementing mutex
/// mechanisms as appropriate.
class DlepService
{
public:
/// Possible return values for our methods.
enum class ReturnStatus
{
/// The operation completed successfully.
ok,
/// One or more of the data items were invalid.
invalid_data_item,
/// The MAC address was malformed or not recognized.
invalid_mac_address,
/// Attempt to add a destination MAC address that already exists.
destination_exists,
/// An operation was attempted on an unknown destination MAC address.
destination_does_not_exist,
/// An operation was attempted on an unknown peer id.
peer_does_not_exist
};
/// Notify the DLEP service that a new destination is available.
///
/// The DLEP service will issue a Destination Up message to the
/// peer(s). If there is no extant peer session, the DLEP service
/// adds the destination to its local database so that it can be
/// sent to a future peer.
///
/// Actually, this method can send one of four different messages
/// depending on the circumstances: Destination Up, Destination Up
/// Response, Destination Announce, or Destination Announce
/// Response.
///
/// If the DLEP service is configured as a router (see the
/// local-type configuration parameter), and the protocol
/// configuration defines the Destination Announce message, then
/// this method will generate a Destination Announce message
/// instead of a Destination Up message. The modem peer will be
/// expected to send a Destination Announce Response message.
///
/// If the DLEP service is configured as a modem, and the router
/// has previously sent a Destination Announce or Destination Up
/// message for this destination, then this method will send the
/// corresponding response message (Destination Up Response or
/// Destination Announce Response). Otherwise, it will send
/// Destination Up.
///
/// The intention is that the client doesn't have to care what
/// type of DLEP message is generated underneath. It just
/// declares destinations to be up as appropriate, and DlepService
/// takes care of sending the right message.
///
/// @param[in] mac_address
/// the destination that is up
/// @param[in] data_items
/// data items (metrics and IP addresses) associated with
/// the destination
///
/// @return ok if no error, else as described in DlepService::ReturnStatus
virtual ReturnStatus destination_up(const DlepMac & mac_address,
const DataItems & data_items) = 0;
/// Notify the DLEP service that an existing destination's
/// attributes have changed.
///
/// The DLEP service will issue a Destination Update signal to the
/// peer(s). If there is no extant peer session, the DLEP service
/// records the new attributes for the destination in its local
/// database so that it can be sent to a future peer.
///
/// If the client has never declared the destination
/// mac_address up via DlepService::destination_up(), then the
/// destination is assumed to belong to a peer. The DLEP
/// service will send the request to the peer that declared
/// the destination to be up if one exists. In this case, the
/// specified data items are NOT stored locally, since it is
/// not a locally-owned destination.
///
/// @param[in] mac_address
/// the destination being updated
/// @param[in] data_items
/// data items (metrics and IP addresses) associated with
/// the destination
///
/// @return ok if no error, else as described in DlepService::ReturnStatus
virtual ReturnStatus destination_update(const DlepMac & mac_address,
const DataItems & data_items) = 0;
/// Notify the DLEP service that a previously existing destination
/// is down.
///
/// The DLEP service will issue a Destination Down for the given
/// destination to the peer. If there is no extant peer session,
/// the DLEP service library removes the destination from its
/// local database. A future peer will not see this destination
/// unless it is subsequently re-added via destination_up().
///
/// @param[in] mac_address
/// the destination that is down
/// @param[in] data_items
/// data items associated with \p mac_address
///
/// @return ok if no error, else as described in DlepService::ReturnStatus
virtual ReturnStatus destination_down(const DlepMac & mac_address,
const DataItems & data_items = DataItems()) = 0;
/// Notify the DLEP service that the local peer's metrics, IP
/// addresses, and other data items have changed.
///
/// The DLEP service will issue a Peer Update to the peer with the
/// new information. If there is no extant peer session, the DLEP
/// protocol remembers the data items so that they can be
/// sent to a future peer. The set of data items so remembered is
/// referred to as the set of session initialization data items.
///
/// @param[in] data_items
/// data items (metrics and IP addresses) associated with
/// the local peer
///
/// @return ok if no error, else as described in DlepService::ReturnStatus
virtual ReturnStatus peer_update(const DataItems & data_items) = 0;
/// Remove data items that were previously given in a peer_update().
///
/// The specified data items are removed from DLEP service's
/// session initialization data items. Future peers will not see
/// these data items sent during session initialization. This
/// does not issue a Peer Update to the peer.
///
/// @param[in] data_items
/// data items associated with the local peer to be removed
///
/// @return ok if no error, else as described in DlepService::ReturnStatus
/// It is not an error to specify a data item that is not in the DlepService's
/// set of session initialization data items.
virtual ReturnStatus peer_remove_data_items(const DataItems & data_items) = 0;
/// Get a list of all existing peer ids.
///
/// @param[out] peers
/// Upon return, this will be filled in with the peer ids
/// @return ok if no error, else as described in DlepService::ReturnStatus
virtual ReturnStatus get_peers(std::vector<std::string> & peers) = 0;
/// Get detailed information about a peer.
///
/// @param[in] peer_id
/// the id of the peer for which information is requested
/// @param[out] peer_info
/// Upon successful return, this will be filled in with
/// information about the given \p peer_id
/// @return
/// - ok if no error
/// - peer_does_not_exist if peer_id does not name an existing peer
virtual ReturnStatus get_peer_info(const std::string & peer_id,
LLDLEP::PeerInfo & peer_info) = 0;
/// Get detailed information about a destination.
///
/// @param[in] peer_id
/// the id of the peer to which the destination belongs
/// @param[in] mac_address
/// the destination for which information is requested
/// @param[out] dest_info
/// Upon successful return, this will be filled in with
/// information about the destination \p mac_address
/// @return
/// - ok if no error
/// - peer_does_not_exist if peer_id does not name an existing peer
/// - destination_does_not_exist if mac_address was not a destination
/// known to peer_id
virtual ReturnStatus get_destination_info(const std::string & peer_id,
const DlepMac & mac_address,
LLDLEP::DestinationInfo & dest_info) = 0;
/// Get the ProtocolConfig object, enabling the client to
/// access protocol configuration information, e.g. supported
/// metrics. See the LLDLEP::ProtocolConfig class for
/// details.
///
/// @return a pointer to the ProtocolConfig object. The client
/// can use this pointer until this DlepService instance terminates.
virtual LLDLEP::ProtocolConfig * get_protocol_config() = 0;
/// Tell the DLEP service to send a Link Characteristics Request.
///
/// The DLEP service will issue a Link Characteristics Request to the
/// peer that declared the destination to be up.
///
/// See DlepClient::linkchar_reply() for the complete sequence of events
/// in a link characteristics request/reply transacation.
///
/// @param[in] mac_address
/// the destination whose link characteristics are being
/// requested
/// @param[in] data_items
/// data items (metrics) associated with \p mac_address.
/// If empty, this is a request for the peer to send the
/// current values of all metrics. Otherwise, it is a
/// request for the peer to "make it so": the given metric
/// values should be established as the real metrics for
/// the given destination.
/// @return
/// - ok if no error
/// - peer_does_not_exist if no peer could be found for
/// destination \p mac_address
virtual ReturnStatus linkchar_request(const DlepMac & mac_address,
const DataItems & data_items) = 0;
/// Tell the DLEP service to send a Link Characteristics Response.
///
/// The DLEP service will issue a Link Characteristics Response to
/// the specified peer. A DLEP client must call this in response
/// to a Link Characteristics Request, i.e., after its
/// DlepClient::linkchar_request() method is called. Separating
/// the linkchar request and reply allows the client to do
/// arbitrary processing in between (for example, to make the new
/// link characteristics take effect) without holding up the Dlep
/// protocol processing thread.
///
/// See DlepClient::linkchar_reply() for the complete sequence of events
/// in a link characteristics request/reply transacation.
///
/// @param[in] peer_id
/// the peer to send the reply to. This is one of the
/// few places that DlepService requires a peer id.
/// The reason is that the sending of the ack (reply)
/// signal is usually handled internally by
/// DlepService, but in this case the generation of the
/// reply is being initiated by the client. So the
/// client needs to know which peer to send it to,
/// since there can be multiple peers. The client
/// knows which peer id should be replied to because
/// DlepService provides it to the client in the method
/// DlepClient::linkchar_request().
/// @param[in] mac_address
/// the destination whose link characteristics are being
/// supplied
/// @param[in] data_items
/// data items (metrics) associated with \p mac_address
///
/// @return
/// - ok if no error
/// - peer_does_not_exist if peer_id does not name an existing peer
virtual ReturnStatus linkchar_reply(const std::string & peer_id,
const DlepMac & mac_address,
const DataItems & data_items) = 0;
/// Tell the DLEP service to terminate all operations.
///
/// This should be done before the user of the DLEP service
/// library exits, to enable a clean shutdown the library's
/// threads, peer sessions, etc.
virtual void terminate() = 0;
virtual ~DlepService() {};
protected:
DlepService() {};
};
} // namespace LLDLEP
#endif // DLEP_SERVICE_H