summaryrefslogtreecommitdiff
path: root/cesar/mac/common/store.h
blob: a95d7deb5736fe820e0df4fa81ba2a7f31ac08e2 (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
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
#ifndef mac_common_store_h
#define mac_common_store_h
/* Cesar project {{{
 *
 * Copyright (C) 2007 Spidcom
 *
 * <<<Licence>>>
 *
 * }}} */
/**
 * \file    mac/common/store.h
 * \brief   MFS and STA store, store pointers to MFS and STA information.
 * \ingroup mac_common
 */
#include "lib/blame.h"
#include "mac/common/mfs.h"
#include "mac/common/sta.h"

typedef struct mac_store_t mac_store_t;

/**
 * Travel callback function.
 * \param  ctx  store context
 * \param  mfs  lent reference to the MFS visited
 * \param  user  user data
 *
 * The MFS reference is lend to the callee, therefore, there is no need to add
 * or release any reference if the callback does not keep the MFS for later
 * usage.  Actually, the travel function will add a reference before calling
 * the callback, and release a reference after the callback return.
 */
typedef void (*mac_store_travel_t) (mac_store_t *ctx, mfs_t *mfs, void *user);

BEGIN_DECLS

/**
 * Initialise and return a store.
 * \return  the newly created store context
 */
mac_store_t *
mac_store_init (void);

/**
 * Uninitialise a store.
 * \param  ctx  store context
 */
void
mac_store_uninit (mac_store_t *ctx);

/**
 * Retrieve an MFS.
 * \param  ctx  store context
 * \param  tx  true to request a TX MFS
 * \param  bcast  true to request a broadcast MFS
 * \param  mme  true to request a MME MFS
 * \param  lid  link id
 * \param  tei  peer terminal equipment id
 * \return  new reference to the MFS or NULL if not it does not exist
 * \context  ISR, DSR, Task
 *
 * The returned pointer is a new reference.  Callee is responsible to release
 * the reference after usage.
 */
mfs_t *
mac_store_mfs_get_ (mac_store_t *ctx, bool tx, bool bcast, bool mme, uint lid,
                    uint tei __FL);
#define mac_store_mfs_get(args...) mac_store_mfs_get_ (args __fL)

/**
 * Retrieve an RX MFS.
 * \param  ctx  store context
 * \param  bcast  true to request a broadcast MFS
 * \param  mme  true to request a MME MFS
 * \param  lid  link id
 * \param  tei  peer terminal equipment id
 * \return  new reference to the MFS or NULL if not it does not exist
 *
 * This is a shortcut for mac_store_mfs_get(), see its documentation for more
 * details.
 */
extern inline mfs_rx_t *
mac_store_mfs_get_rx_ (mac_store_t *ctx, bool bcast, bool mme, uint lid,
                       uint tei __FL)
{
    return &mac_store_mfs_get_ (ctx, false, bcast, mme, lid, tei __fl)->rx;
}
#define mac_store_mfs_get_rx(args...) mac_store_mfs_get_rx_ (args __fL)

/**
 * Retrieve an TX MFS.
 * \param  ctx  store context
 * \param  bcast  true to request a broadcast MFS
 * \param  mme  true to request a MME MFS
 * \param  lid  link id
 * \param  tei  peer terminal equipment id
 * \return  new reference to the MFS or NULL if not it does not exist
 *
 * This is a shortcut for mac_store_mfs_get(), see its documentation for more
 * details.
 */
extern inline mfs_tx_t *
mac_store_mfs_get_tx_ (mac_store_t *ctx, bool bcast, bool mme, uint lid,
                       uint tei __FL)
{
    return &mac_store_mfs_get_ (ctx, true, bcast, mme, lid, tei __fl)->tx;
}
#define mac_store_mfs_get_tx(args...) mac_store_mfs_get_tx_ (args __fL)

/**
 * Add an MFS.
 * \param  ctx  store context
 * \param  tx  true to add a TX MFS
 * \param  bcast  true to add a broadcast MFS
 * \param  mme  true to add a MME MFS
 * \param  lid  link id
 * \param  tei  peer terminal equipment id
 * \param  added  true if the returned MFS is a brand new one
 * \return  new reference to the MFS
 * \context  Task
 *
 * If the MFS exists yet, a new reference is returned to it and \p added is
 * set to false.
 *
 * If the MFS does not exists, it is default initialised.
 *
 * The returned pointer is a new reference.  Callee is responsible to release
 * the reference after usage.
 *
 * This is a fatal error if a GLID MFS exists but with a different direction.
 */
mfs_t *
mac_store_mfs_add_ (mac_store_t *ctx, bool tx, bool bcast, bool mme, uint lid,
                    uint tei, bool *added __FL)
    __attribute__ ((warn_unused_result));
#define mac_store_mfs_add(args...) mac_store_mfs_add_ (args __fL)

/**
 * Add an RX MFS.
 * \param  ctx  store context
 * \param  bcast  true to add a broadcast MFS
 * \param  mme  true to add a MME MFS
 * \param  lid  link id
 * \param  tei  peer terminal equipment id
 * \param  added  will be set to true if the returned MFS is a brand new one
 * \return  new reference to the MFS
 *
 * This is a shortcut for mac_store_mfs_add(), see its documentation for more
 * details.
 */
extern inline mfs_rx_t *
mac_store_mfs_add_rx_ (mac_store_t *ctx, bool bcast, bool mme, uint lid,
                       uint tei, bool *added __FL)
    __attribute__ ((warn_unused_result));
#define mac_store_mfs_add_rx(args...) mac_store_mfs_add_rx_ (args __fL)

extern inline mfs_rx_t *
mac_store_mfs_add_rx_ (mac_store_t *ctx, bool bcast, bool mme, uint lid,
                       uint tei, bool *added __FL)
{
    return &mac_store_mfs_add_ (ctx, false, bcast, mme, lid, tei, added
                                __fL)->rx;
}

/**
 * Add an TX MFS.
 * \param  ctx  store context
 * \param  bcast  true to add a broadcast MFS
 * \param  mme  true to add a MME MFS
 * \param  lid  link id
 * \param  tei  peer terminal equipment id
 * \param  added  will be set to true if the returned MFS is a brand new one
 * \return  new reference to the MFS
 *
 * This is a shortcut for mac_store_mfs_add(), see its documentation for more
 * details.
 */
extern inline mfs_tx_t *
mac_store_mfs_add_tx_ (mac_store_t *ctx, bool bcast, bool mme, uint lid,
                       uint tei, bool *added __FL)
    __attribute__ ((warn_unused_result));
#define mac_store_mfs_add_tx(args...) mac_store_mfs_add_tx_ (args __fL)

extern inline mfs_tx_t *
mac_store_mfs_add_tx_ (mac_store_t *ctx, bool bcast, bool mme, uint lid,
                       uint tei, bool *added __FL)
{
    return &mac_store_mfs_add_ (ctx, true, bcast, mme, lid, tei, added
                                __fL)->tx;
}

/**
 * Add an unassociated MFS.
 * \param  ctx  store context
 * \param  tx  true to add a TX MFS
 * \param  bcast  true to add a broadcast MFS
 * \param  mme  true to add a MME MFS
 * \param  lid  link id
 * \param  tei  peer terminal equipment id
 * \return  new reference to the MFS
 * \context  Task
 *
 * MFS is default initialised.
 *
 * The returned pointer is a new reference.  Callee is responsible to release
 * the reference after usage.
 */
mfs_t *
mac_store_mfs_unassociated_add_ (mac_store_t *ctx, bool tx, bool bcast,
                                 bool mme, uint lid, uint tei __FL)
    __attribute__ ((warn_unused_result));
#define mac_store_mfs_unassociated_add(args...) \
        mac_store_mfs_unassociated_add_ (args __fL)

/**
 * Alias an MFS to a new GLID.
 * \param  ctx  store context
 * \param  mfs  lent reference to the MFS to alias
 * \param  glid  new GLID to alias to
 * \context  CP Task
 *
 * The GLID must not be used.
 *
 * This call will modify the MFS to reflect the aliasing.
 */
void
mac_store_mfs_alias_ (mac_store_t *ctx, mfs_t *mfs, uint glid __FL);
#define mac_store_mfs_alias(args...) mac_store_mfs_alias_ (args __fL)

/**
 * Remove an MFS and any aliases.
 * \param  ctx  store context
 * \param  mfs  MFS to remove
 * \context  Task
 */
void
mac_store_mfs_remove_ (mac_store_t *ctx, mfs_t *mfs __FL);
#define mac_store_mfs_remove(args...) mac_store_mfs_remove_ (args __fL)

/**
 * Call the provided callback for all MFS.
 * \param  ctx  store context
 * \param  travel  callback function
 * \param  user  user data
 *
 * \see mac_store_travel_t for more details about calling convention.
 *
 * MFS with two aliases may be travelled two times.
 */
void
mac_store_mfs_travel (mac_store_t *ctx, mac_store_travel_t travel,
                      void *user);

/**
 * Call the provided callback for all MFS connected to a STA.
 * \param  ctx  store context
 * \param  tei  terminal equipment id of the STA
 * \param  travel  callback function
 * \param  user  user data
 *
 * \see mac_store_travel_t for more details about calling convention.
 *
 * This is not an error if the STA does not exists.
 *
 * This function does not travel TX LLID or any GLID (but GLID may be aliased
 * to a RX LLID).
 */
void
mac_store_mfs_travel_by_tei (mac_store_t *ctx, uint tei,
                             mac_store_travel_t travel, void *user);

/**
 * Call the provided callback for all MFS, with DSR locked.
 * \param  ctx  store context
 * \param  travel  callback function
 * \param  user  user data
 * \context  DSR
 *
 * \see mac_store_mfs_travel.
 *
 * DSR should be locked to call this function.
 */
void
mac_store_mfs_travel_locked (mac_store_t *ctx, mac_store_travel_t travel,
                             void *user);

/**
 * Call the provided callback for all MFS connected to a STA, with DSR locked.
 * \param  ctx  store context
 * \param  tei  terminal equipment id of the STA
 * \param  travel  callback function
 * \param  user  user data
 * \context  DSR
 *
 * \see mac_store_mfs_travel_by_tei.
 *
 * DSR should be locked to call this function.
 */
void
mac_store_mfs_travel_by_tei_locked (mac_store_t *ctx, uint tei,
                                    mac_store_travel_t travel, void *user);

/**
 * Get a STA information structure pointer.
 * \param  ctx  store context
 * \param  tei  peer terminal equipment id
 * \return  a new reference to the STA information structure or NULL if it
 * does not exist
 * \context  ISR, DSR, Task
 *
 * The returned pointer is a new reference.  Callee is responsible to release
 * the reference after usage.
 */
sta_t *
mac_store_sta_get_ (mac_store_t *ctx, uint tei __FL);
#define mac_store_sta_get(args...) mac_store_sta_get_ (args __fL)

/**
 * Create a new STA information structure.
 * \param  ctx  store context
 * \param  tei  peer terminal equipment id
 * \context  Task
 *
 * The STA information structure is default initialised.  This call will be
 * ignored if the STA exists yet.
 */
void
mac_store_sta_add_ (mac_store_t *ctx, uint tei __FL);
#define mac_store_sta_add(args...) mac_store_sta_add_ (args __fL)

/**
 * Remove a STA information structure.
 * \param  ctx  store context
 * \param  tei  peer terminal equipment id
 * \return  true on success
 * \context  CP Task
 *
 * All MFS associated with this STA must be removed prior to this call.  If
 * this is not the case, the call returns false.
 */
bool
mac_store_sta_remove_ (mac_store_t *ctx, uint tei __FL)
    __attribute__ ((warn_unused_result));
#define mac_store_sta_remove(args...) mac_store_sta_remove_ (args __fL)

/**
 * Return the next STA TEI.
 * \param  ctx  store context
 * \param  start_tei  previous TEI, or MAC_TEI_UNASSOCIATED to start from
 * first STA
 * \return  the next used TEI, or MAC_TEI_BCAST if no other TEI
 */
uint
mac_store_sta_next (mac_store_t *ctx, uint start_tei);

/**
 * Return the next STA TEI, loop to start of list.
 * \param  ctx  store context
 * \param  start_tei  previous TEI, or MAC_TEI_UNASSOCIATED to start from
 * first STA
 * \return  the next used TEI, or MAC_TEI_BCAST if no TEI
 */
uint
mac_store_sta_next_loop (mac_store_t *ctx, uint start_tei);

/**
 * Return a free LLID for TX.
 * \param  ctx  store context
 * \return  a free LLID or -1 if none can be found
 * \context  CP Task
 *
 * The only local link creator is the control plane.  Therefore, there is no
 * problem of concurrency, no one could create the MFS corresponding to the
 * returned LLID before the caller does it.
 */
int
mac_store_get_free_tx_llid (mac_store_t *ctx);

/**
 * Return a free TEI.
 * \param  ctx  store context
 * \return  a free TEI or -1 if none can be found
 * \context  CP Task
 *
 * This call is useful for the CCo.
 *
 * It could eventually arise that the TEI returned is no longer free because
 * the SAR process created the corresponding STA information just after this
 * call.  This case should be very rare but this should not case crashes.
 */
int
mac_store_get_free_tei (mac_store_t *ctx);

END_DECLS

#endif /* mac_common_store_h */