summaryrefslogtreecommitdiff
path: root/cesar/mac/common/src/mfs.c
blob: 2a4fbfe4bd71539c40a5d6b6768e974b1ad4c2e5 (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
/* 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. */
#define MFS_WINDOW_SIZE_MME 8

/** MFS DATA window size. */
#define MFS_WINDOW_SIZE_DATA 200

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)
        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 = mme ? MFS_WINDOW_SIZE_MME : MFS_WINDOW_SIZE_DATA;
    mfs->window_size_encoded = mfs_rx_window_size_encode (mfs->window_size);
    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;
    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->min_ssn = 0;
    mfs->window_size = mme ? MFS_WINDOW_SIZE_MME : MFS_WINDOW_SIZE_DATA;
    mfs->window_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;
    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;
}

u8
mfs_rx_window_size_encode (u16 window_size)
{
    uint i;
    static u16 encode_table[] = { 4, 8, 16, 24, 32, 48, 64, 80, 96, 112, 128,
        144, 160, 192, 224, 256 };
    dbg_assert (window_size >= 4 && window_size <= 256);
    DICHOTOMY_SEARCH (0, COUNT (encode_table), i,
                      window_size < encode_table[i]);
    return i - 1;
}