summaryrefslogtreecommitdiff
path: root/cesar/cp/eoc/cco/bw/src/bw.c
blob: a8585214747675b132ceed4f0d2723642b96d141 (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
/* Cesar project {{{
 *
 * Copyright (C) 2009 Spidcom
 *
 * <<<Licence>>>
 *
 * }}} */
/**
 * \file cp/eoc/cco/bw/src/bw.c
 * \brief Create the alloctions for beacon period and create CCo schedule
 * \ingroup cp_eoc_cco_bw
 *
*/
#include "common/std.h"

/* Private headers. */
#include "cp/inc/context.h"
#include "cp/cco/bw/inc/context.h"
#include "cp/eoc/cco/bw/inc/bw.h"

/* Public headers. */
#include "cp/eoc/cco/bw/bw.h"
#include "cp/eoc/cco/bw/service.h"
#include "cp/cco/bw/bw.h"
#include "cp/sta/mgr/sta.h"

static uint cp_eoc_cco_bw_csma_duration = MAC_US_TO_TCK (4300);
static uint cp_eoc_cco_bw_central_tck = MIN_SPC_CENTRAL_TCK;

void
cp_eoc_cco_bw_allocations_adjust (cp_t *ctx, bool adjust)
{
    dbg_assert (ctx);
    if (!adjust)
    {
        cp_eoc_cco_bw_csma_duration = MIN_CSMA_EOC_TCK;
        cp_eoc_cco_bw_central_tck = MIN_SPC_CENTRAL_TCK;
    }
    else
    {
        cp_eoc_cco_bw_csma_duration = MAC_MS_TO_TCK (7);
        cp_eoc_cco_bw_central_tck = MAC_MS_TO_TCK (2);
    }
    dbg_assert ((cp_eoc_cco_bw_csma_duration - cp_eoc_cco_bw_central_tck)
                >= MAC_MS_TO_TCK (3));
}

/**
 * Create schedule bentry to be transmitted in EOC beacon
 * \param ctx the module context
 */
void
cp_eoc_cco_bw_bp_allocations (cp_t *ctx)
{
    dbg_assert (ctx);
    cp_cco_bw_alloc_t *alloc;
    static bool startup_period = true;
    static bool update_end_date = true;
    static u32 startup_date_end;
    if (update_end_date)
    {
#if MODULE_INCLUDED (hal_phy_maximus)
        startup_date_end = phy_date () + MAC_MS_TO_TCK (3000);
#else
        startup_date_end = phy_date () + CP_EOC_CCO_STARTUP_PERIOD;
#endif
        update_end_date = false;
    }

    if (startup_period && !less_mod2p32 (phy_date (), startup_date_end))
        startup_period = false;

    cp_cco_bw_alloc_clean (ctx, &ctx->bw.alloc_list);

    alloc = cp_cco_bw_alloc_init (ctx);
    alloc->stpf = false;
    alloc->glid = MAC_LID_SPC_CENTRAL;
    alloc->end_time_atu = MAC_TCK_TO_ATU(cp_eoc_cco_bw_central_tck);
    alloc->persistence = CP_CCO_BW_ALLOC_PERSISTENCE_NOT_PERSISTENT;
    cp_cco_bw_alloc_add (ctx, &ctx->bw.alloc_list, alloc);
    slab_release (alloc);

    alloc = cp_cco_bw_alloc_init (ctx);
    alloc->stpf = false;
    alloc->glid = MAC_LID_LOCAL_CSMA;
    if (startup_period)
    {
        alloc->end_time_atu = MAC_TCK_TO_ATU(CP_EOC_CSMA_STARTUP_PERIOD);
    }
    else
    {
        alloc->end_time_atu = MAC_TCK_TO_ATU(cp_eoc_cco_bw_csma_duration);
    }
    alloc->persistence = CP_CCO_BW_ALLOC_PERSISTENCE_NOT_PERSISTENT;
    cp_cco_bw_alloc_add (ctx, &ctx->bw.alloc_list, alloc);
    slab_release (alloc);

    alloc = cp_cco_bw_alloc_init (ctx);
    alloc->stpf = false;
    alloc->glid = MAC_LID_CFPI;
    alloc->end_time_atu = MAC_TCK_TO_ATU(BSU_ACLF_BP_CABLE_TCK);
    alloc->persistence = CP_CCO_BW_ALLOC_PERSISTENCE_NOT_PERSISTENT;
    cp_cco_bw_alloc_add (ctx, &ctx->bw.alloc_list, alloc);
    slab_release (alloc);
}

/** Create allocations at CCo startup or for station that has missed some
 *  beacons
 * \param ctx module context
 */
void
cp_eoc_cco_bw_sta_allocations (cp_t *ctx)
{
    cp_cco_bw_alloc_t *alloc;
    dbg_assert (ctx);

    cp_cco_bw_alloc_clean (ctx, &ctx->bw.alloc_list);

    alloc = cp_cco_bw_alloc_init (ctx);
    alloc->stpf = false;
    alloc->glid = MAC_LID_SPC_CENTRAL;
    alloc->end_time_atu = MAC_TCK_TO_ATU(BSU_ACLF_BP_CABLE_TCK);
    alloc->persistence = CP_CCO_BW_ALLOC_PERSISTENCE_NOT_PERSISTENT;
    cp_cco_bw_alloc_add (ctx, &ctx->bw.alloc_list, alloc);
    slab_release (alloc);
}

#if CONFIG_CP_EOC_IS_MASTER
void
cp_eoc_cco_bw_sched_init (cp_t * ctx)
{
    dbg_assert (ctx);
    cp_eoc_cco_services_init (ctx);
}

void
cp_eoc_cco_bw_scheduler (cp_t *ctx)
{
    sta_t *sta = NULL;
    uint i;

    dbg_assert ((sizeof (sta->poll_off) * 8) > CP_EOC_CCO_RELEASE_LIMIT);

    for (i = MAC_TEI_STA_MIN_EOC; i < MAC_TEI_STA_MAX; i++)
    {
        sta = mac_store_sta_get (ctx->mac_store, i);
        if (sta)
        {
            /* Manage stations not replying to poll. */
            if (sta->poll_off & 1)
                sta->poll_off <<= 1;
            else
                sta->poll_off = 0;

            if (sta->poll_off & (1 << CP_EOC_CCO_RELEASE_LIMIT))
            {
                sta->tdma_poll = false;
                sta->poll_off = 0;
                ca_sta_update (ctx->ca, sta);
            }
            /* Release previously polled stations. */
            blk_release (sta);
        }
    }
}

void
cp_eoc_cco_bw_sched_uninit (cp_t *ctx)
{
    dbg_assert (ctx);
    cp_eoc_cco_services_uninit (ctx);
}

#endif /* CONFIG_CP_EOC_IS_MASTER */