summaryrefslogtreecommitdiff
path: root/cesar/cp2/conn/src/conn.c
blob: 5da7b6d237ac0837fefd10582e6493512e0ca2d8 (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
 /* Cesar project {{{
 *
 * Copyright (C) 2008 Spidcom
 *
 * <<<Licence>>>
 *
 * }}} */
/**
 * \file    conn.c
 * \brief   conn 
 * \ingroup cp2_conn
 *
 * Control the schedule of the becon period
 */
#include "common/std.h"
#include "cp2/cp.h"
#include "cp2/inc/context.h"
#include "cp2/conn/conn.h"
#include "cp2/conn/inc/conn.h"
#include "cp2/conn/link.h"
#include "cp2/conn/inc/link.h"
#include "lib/blk.h"

/**
 * function that return a specific connection
 * \param  ctx  control plane context
 * \param  cid  connection id of the target conn
 * \return  the target connection or NULL if none
 *
 * checks the list of conn until it finds the conn or that there is no more
 * conn and return it
 */
cp_conn_t*
cp_conn_get_conn(cp_t *ctx, u16 cid)
{
    bool cid_found = false;
    bool no_more_conn = false;

    cp_conn_t *conn = NULL;
    
    dbg_assert(ctx);

    conn = cp_conn_get_first_conn(ctx);

    do
    {
        if(conn->conn_info->cid == cid)
            cid_found = true;

        else if(!cp_conn_is_last_conn(ctx, conn))
            conn = cp_conn_get_next_conn(conn);

        else
            no_more_conn = true;
    }
    while(!cid_found && !no_more_conn);

    return conn;
}
/**
 * init a connection 
 * \param  cid  connection identifier
 * \param  flink  forward link
 * \param  rlink  reverse link
 * \return  return the connection initialised
 *
 * Init the memory of the connection
 * fill the elements concerning the connection
 */
void
cp_conn_add_conn(cp_t *ctx, cp_conn_t *conn)
{
    dbg_assert(ctx);

    list_init_node (&conn->node);
    list_push(&ctx->conn_mgr.conns, &conn->node);
}

void
cp_conn_del_conn(cp_t *ctx, u16 cid)
{
    cp_conn_t *conn = NULL;

    conn = cp_conn_get_conn(ctx, cid);

    cp_link_uninit(conn->flink);
    cp_link_uninit(conn->rlink);
    blk_release(conn->flink);
    blk_release(conn->rlink);

    list_remove(&ctx->conn_mgr.conns, &conn->node);
    blk_release(conn);
}

u8
cp_conn_get_free_lid(cp_t *ctx)
{
    bool free_lid = true;
    bool no_more_conn = false;
    u8 lid = 0x00;

    cp_conn_t *conn;

    do
    {
        conn = cp_conn_get_first_conn(ctx);
        lid++;
        free_lid = true;
        no_more_conn = false;

        while(!no_more_conn && free_lid)
        {
            if(conn->conn_info->lid_r == lid || conn->conn_info->lid_f == lid)
                free_lid = false;

            else if(cp_conn_is_last_conn(ctx, conn))
                no_more_conn = true;

            else
                conn = cp_conn_get_next_conn(conn);
        }
    }
    while(!free_lid);

    return lid;
}

u8
cp_conn_get_request_id(cp_t *ctx, u16 cid)
{
    return cp_conn_get_conn(ctx, cid)->request_id;
}
/**
 * Return the next connection
 * \param  conn  actual conncetion
 * \return  The next connection
 *
 */
cp_conn_t*
cp_conn_get_next_conn(cp_conn_t *conn)
{
    return PARENT_OF(cp_conn_t, node, list_next(&conn->node));
}

/**
 * Return the first connection of a heap
 * \param  heap  Heap
 * \return  The first connection of the heap
 *
 */
cp_conn_t*
cp_conn_get_first_conn(cp_t *ctx)
{
    return PARENT_OF(cp_conn_t, node, list_begin(&ctx->conn_mgr.conns));
}

/**
 * Tells if the connection is the last of the heap
 * \param  conn  connection
 * \return  bool true if last connection
 *
 */
bool
cp_conn_is_last_conn(cp_t *ctx,cp_conn_t *conn)
{
    return &conn->node == list_rbegin(&ctx->conn_mgr.conns) ? true : false;
}