summaryrefslogtreecommitdiff
path: root/cesar/mac/common/src/mfs.c
blob: a16a10994c003cbc5d2671244d53c206af1f2691 (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
/* Cesar project {{{
 *
 * Copyright (C) 2007 Spidcom
 *
 * <<<Licence>>>
 *
 * }}} */
/**
 * \file    mac/common/src/mfs.c
 * \brief   MAC frame stream functions.
 * \ingroup mac_common
 */
#include "common/std.h"

#include "mac/common/mfs.h"
#include "mac/common/defs.h"
#include "mac/common/timings.h"

/** MFS MME window size (fixed). */
#define MFS_WINDOW_SIZE_MME MFS_WINDOW_SIZE_8

/** RX MFS DATA window size (fixed). */
#define MFS_WINDOW_SIZE_DATA_RX MFS_WINDOW_SIZE_256

/** Default TX MFS DATA window size (actual value is fixed by the receiver). */
#define MFS_DEFAULT_WINDOW_SIZE_DATA_TX CONFIG_MAC_COMMON_EOC_MFS ? \
    MFS_WINDOW_SIZE_256 : MFS_WINDOW_SIZE_16

/** Window size values table (values of the RxWSz field of the FCs in which
 *  it is included). */
const u16 mfs_window_size[MFS_WINDOW_SIZE_NB] = { 4, 8, 16, 24, 32, 48, 64, 80,
        96, 112, 128, 144, 160, 192, 224, 256 };

static void
mfs_common_init (mfs_common_t *mfs_common, bool tx, bool bcast, bool mme, uint
                 lid, uint tei)
{
    mfs_common->tx = tx;
    mfs_common->bcast = bcast;
    mfs_common->mme = mme;
    mfs_common->ats = false;
    mfs_common->lid = lid;
    mfs_common->tei = tei;
    mfs_common->lid_alias = MAC_LID_NONE;
    mfs_common->unassociated = false;
    list_init_node (&mfs_common->store_unassociated_link);
    /* mfs_common->expiration_ntb */
    if (tx)
#if CONFIG_MAC_COMMON_EOC_MFS
        if (mfs_common->mme)
            mfs_common->expiration_delay_tck =
                MAC_MS_TO_TCK (MFS_PB_TX_DELAY_MS << 1);
        else
#endif
        mfs_common->expiration_delay_tck =
            MAC_MS_TO_TCK (MFS_PB_TX_DELAY_MS);
    else
        mfs_common->expiration_delay_tck =
            MAC_MS_TO_TCK (MFS_PB_RX_DELAY_MS);
}

void
mfs_rx_init (mfs_rx_t *mfs, bool bcast, bool mme, uint lid, uint tei)
{
    dbg_assert_ptr (mfs);
    dbg_assert ((mme && lid == MAC_LID_NONE)
                || (!mme && MAC_LID_IS_XLID (lid)));
    dbg_assert (tei != MAC_TEI_BCAST);
    mfs_common_init (&mfs->common, false, bcast, mme, lid, tei);
    mfs->head = NULL;
    mfs->ssn_min = 0;
    mfs->window_size_encoded = mme ? MFS_WINDOW_SIZE_MME : MFS_WINDOW_SIZE_DATA_RX;
    mfs->window_size = mfs_window_size[mfs->window_size_encoded];
    mfs->release = false;
    link_stats_rx_reset (&mfs->stats);
}

void
mfs_rx_init_unassociated (mfs_rx_t *mfs, bool bcast, bool mme, uint lid,
                          uint tei)
{
    mfs_rx_init (mfs, bcast, mme, lid, tei);
    mfs->common.unassociated = true;
}

void
mfs_tx_init (mfs_tx_t *mfs, bool bcast, bool mme, uint lid, uint tei)
{
    dbg_assert_ptr (mfs);
    dbg_assert ((mme && lid == MAC_LID_NONE)
                || (!mme && (MAC_LID_IS_XLID (lid)
                             || MAC_LID_IS_BEACON (lid))));
    dbg_assert ((bcast && tei == MAC_TEI_BCAST)
                || (!bcast && MAC_TEI_IS_STA (tei))
                || (!bcast && mme && tei == MAC_TEI_UNASSOCIATED));
    mfs_common_init (&mfs->common, true, bcast, mme, lid, tei);
    mfs->cfp = false;
    if (CONFIG_MAC_COMMON_EOC_MFS && (tei != MAC_TEI_UNASSOCIATED))
    {
        mfs->cfp = true;
    }
    mfs->burst_count = 0;
    list_init_node (&mfs->ca_link);
    mfs->ca_state = CA_MFS_STATE_UNKNOWN;
    mfs->seg_nb = 0;
    mfs->pending_seg_nb = 0;
    mfs->fsm_state = bcast ? MFS_FSM_CMD_NOP : MFS_FSM_CMD_INIT;
    mfs->window_size = mme ? mfs_window_size[MFS_WINDOW_SIZE_MME]
                             : mfs_window_size[MFS_DEFAULT_WINDOW_SIZE_DATA_TX];
    mfs->holes_seg_nb = 0;
    if (mme)
        mfs->cap = 2;
    else
        mfs->cap = MAC_LID_IS_PLID (lid) ? lid : 0;
    mfs->head = NULL;
    dbg_invalid_ptr (mfs->tail);
    mfs->last_seg_offset = 0;
    mfs->next_ssn = 0;
    mfs->beacon = false;
#if CONFIG_MAC_COMMON_EOC_MFS
    mfs->no_reply_count = 0;
    mfs->cap = 0;
#endif
    link_stats_tx_reset (&mfs->stats);
}

void
mfs_tx_init_unassociated (mfs_tx_t *mfs, bool bcast, bool mme, uint lid, uint tei)
{
    dbg_assert (mfs);

    mfs_tx_init (mfs, bcast, mme, lid, tei);
    mfs->common.unassociated = true;
    mfs->fsm_state = MFS_FSM_CMD_NOP;
    if (CONFIG_MAC_COMMON_EOC_MFS)
        mfs->cfp = false;
}