summaryrefslogtreecommitdiff
path: root/cesar/bsu/src/interface.c
blob: 5fa6772b561d517f9c6acd562be7b87edda3ed56 (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
/* Cesar project {{{
 *
 * Copyright (C) 2010 Spidcom
 *
 * <<<Licence>>>
 *
 * }}} */
/**
 * \file    bsu/src/interface.c
 * \brief   BSU interface functions.
 * \ingroup bsu
 *
 * BSU interface functions with the SAR and upper layer.
 */
#include "common/std.h"
#include "hal/arch/arch.h"
#include "lib/fixed.h"
#include "bsu/bsu.h"
#include "bsu/inc/bsu.h"

#include "bsu/inc/context.h"

void
bsu_beacon_send (bsu_t *ctx, bsu_beacon_type_t beacon_type,
                 pb_beacon_t *beacon, void *bto_bpsto)
{
    mfs_tx_t *beacon_mfs;
    bool added;
    dbg_assert (ctx);
    dbg_assert (beacon);
    dbg_assert (beacon_type < BSU_BEACON_TYPE_NB);
    dbg_assert (bto_bpsto);
    /* Get lid from the beacon type. */
    switch (beacon_type)
    {
    case BSU_BEACON_TYPE_CENTRAL:
        beacon_mfs = mac_store_mfs_add_tx (ctx->mac_store, true, false,
                                           MAC_LID_SPC_CENTRAL, MAC_TEI_BCAST,
                                           &added);
        break;
    case BSU_BEACON_TYPE_DISCOVER:
        beacon_mfs = mac_store_mfs_add_tx (ctx->mac_store, true, false,
                                           MAC_LID_DISCOVER, MAC_TEI_BCAST,
                                           &added);
        break;
    default:
        dbg_assert_default ();
    }
    dbg_assert (beacon_mfs);
    /* If the MFS is new, configure it. */
    if (added)
    {
        /* Highest priority for central beacon. */
        if (beacon_type == BSU_BEACON_TYPE_CENTRAL)
            beacon_mfs->cap = 0x3;
        else
            beacon_mfs->cap = 0x2;
        beacon_mfs->beacon = true;
        ca_mfs_add (ctx->ca, beacon_mfs);
    }
    /* Hold the segment until the next beacon period. Only for central
     * beacons. To be done each time, the CA only held until the next beacon
     * period it is not forever. */
    if (beacon_type == BSU_BEACON_TYPE_CENTRAL)
        ca_mfs_hold (ctx->ca, beacon_mfs);
    blk_addref_desc ((blk_t*) beacon);
    /* Provide the beacon to the SAR. */
    sar_beacon_send (ctx->sar, beacon, beacon_mfs, bto_bpsto);
    /* Send the beacon to the upper layer. */
    bsu_params_t bsu_params = {BSU_BEACON_DIRECTION_TO_PLC,
        FIXED (ctx->sta_avln->sync.fe, BSU_NTB_FIXED_POINT),
        ctx->sta_avln->sync.ntb_offset_tck};
    (*ctx->ul_cb) (ctx->ul_data, beacon, NULL, bsu_params);
}

void
bsu_beacon_recv (bsu_t *ctx, pb_beacon_t *beacon,
                 pbproc_rx_beacon_params_t *params)
{
    dbg_assert (ctx);
    dbg_assert (beacon);
    dbg_assert (params);
    /* Load beacon into the cache. */
    arch_load_cache (&beacon->first_data_word, 1);
    arch_load_cache ((u32*) beacon->data, BLK_SIZE / 4);
    /* Process the beacon received from the SAR. */
    bsu_beacon_process (ctx, beacon, params);
    /* Send it to the upper layer. */
    bsu_params_t bsu_params = {BSU_BEACON_DIRECTION_FROM_PLC,
        FIXED (ctx->sta_avln->sync.fe, BSU_NTB_FIXED_POINT),
        ctx->sta_avln->sync.ntb_offset_tck};
    (*ctx->ul_cb) (ctx->ul_data, beacon, params, bsu_params);
}