summaryrefslogtreecommitdiff
path: root/cp/msg/src/msg.c
blob: 9fdce1a484343639342a0228f0ed159e884a342c (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
/* Cesar project {{{
 *
 * Copyright (C) 2007 Spidcom
 *
 * <<<Licence>>>
 *
 * }}} */
/**
 * \file    cp/msg/msg.c
 * \brief   MME message processing
 * \ingroup cp_msg
 */

#include "common/std.h"
#include "cp/msg/msg.h"

/*
 * this array describe messages, their prefered destination and the function
 *  which process it.
 * the array must be ordered on the first field of each line.
 */
const msg_list_mme_t msg_list_m[] = 
    { 
        { CC_CCO_APPOINT_REQ,           0 },
        { CC_CCO_APPOINT_CNF,           0 }, 
        { CC_BACKUP_APPOINT_REQ,        0 }, 
        { CC_BACKUP_APPOINT_CNF,        0 },
        { CC_LINK_INFO_REQ,             0 },
        { CC_LINK_INFO_CNF,             0 },
        { CC_LINK_INFO_IND,             0 },
        { CC_LINK_INFO_RSP,             0 },
        { CC_HANDOVER_REQ,              0 }, 
        { CC_HANDOVER_CNF,              0 }, 
        { CC_HANDOVER_INFO_IND,         0 }, 
        { CC_HANDOVER_INFO_RSP,         0 },
        // TBC ...
        {CC_ASSOC_REQ,                  RECEIVE_CC_ASSOC_REQ},
        {CC_ASSOC_CNF,                  RECEIVE_CC_ASSOC_CNF},
        {CC_SET_TEI_MAP_REQ,            RECEIVE_CC_SET_TEI_MAP_REQ},
        {CC_SET_TEI_MAP_IND,            RECEIVE_CC_SET_TEI_MAP_IND},
        
        { CM_UNASSOCIATED_STA_IND,      RECEIVE_USTA_MME}
        // TBC ...
    };

// this is the fmsn that will be used in fragmented mme
static u8 fmsn_m;

void msg_init(void)
{
#if DEBUG == 0
    uint i;
    for(i=1 ; i<COUNT(msg_list_m) ; i++) 
        dbg_assert(msg_list_m[i].mm_type > msg_list_m[i-1].mm_type);
#endif
    fmsn_m = 0;
    msg_cm_init();
}

u8
msg_get_fmsn(const bool new)
{
    // TODO the question is : is it possible to have 2 thread accessing this 
    // function at the same time ?
    if(new) fmsn_m++;
    return fmsn_m; 
}

u16 
msg_get_number (msg_mme_t *msg)
{
    u16 mme_num;
      
    dbg_assert ( !msg_check_wrong_mme_const_values (msg));
    //TODO this is maybe not very efficient, to check with more messages ...
    DICHOTOMY_SEARCH(0, COUNT(msg_list_m), mme_num, msg->mm_type <= msg_list_m[mme_num].mm_type);
    //printf("requested msg : %i, index found : %i\n", msg->mm_type, mme_num);
    if(msg->mm_type != msg_list_m[mme_num].mm_type) return MSG_UNKNOW;    
    return mme_num;
}

void
msg_dispatch (msg_mme_t *msg)
{
    u16 mme_num;    

    dbg_assert ( !msg_check_wrong_mme_const_values (msg));
    mme_num = msg_get_number (msg);
    if (mme_num != MSG_UNKNOW)
    {
        dbg_assert(msg_list_m[mme_num].msg_num);
        sta_add_event(msg_list_m[mme_num].msg_num, (void *) msg);

    }
    // release the message's buffer(s)
//    interf_release_buf(msg);
}

void 
msg_set_mme_const_values (msg_mme_t *msg)
{
    dbg_assert (msg);
    
    msg->m_type = MSG_MTYPE;    // 11.1.4
    msg->mmv = MSG_MM_VERSION;
    #if CHECK_BUFFER_OVERFLOW
    interf_buffer_t *buffer = NULL;
    buffer = PARENT_OF(interf_buffer_t, msg, msg);
    buffer->signature = BUFFER_SIGNATURE;
    #endif
}

bool 
msg_check_wrong_mme_const_values (const msg_mme_t *msg)
{
    dbg_assert (msg);

    #if CHECK_BUFFER_OVERFLOW
    interf_buffer_t *buffer = NULL;
    buffer = PARENT_OF(interf_buffer_t, msg, msg);
    dbg_assert(buffer->signature == BUFFER_SIGNATURE);
    #endif

    return (msg->m_type != MSG_MTYPE);
}

msg_mme_t *
msg_sending_common_part(msg_mme_t *msg, const mac_address_t oda, msg_param_t *msg_param)
{   
    dbg_assert(msg);
    dbg_assert(msg_param);
    
    // ask for a buffer
    //msg = interf_give_buf ();
    //dbg_assert ( !msg_check_wrong_mme_const_values (msg));
    // set the header values of msg
    memcpy(msg->oda, oda, sizeof(mac_address_t));
    memcpy(msg->osa, station_get_mac_address(), sizeof(mac_address_t));
    // vlan is optional and not used
    msg->m_type = MSG_MTYPE;    // 11.1.4
    msg->mmv = MSG_MM_VERSION;
    // set fragmentation default values
    msg->fmi.nf_mi = 0;
    msg->fmi.fn_mi = 0;
    msg->fmi.fmsn  = 0;
    // set the default message parameters
    memset(msg_param, 0, sizeof(msg_param_t));
    msg_param->encryption = HARDWARE_ENCRYPTED;
    msg_param->peks = NOT_ENCRYPTED;
    return msg;
}

void
msg_send(msg_mme_t *msg, u16 msg_size, msg_param_t msg_param)
{
    tei_t tei;
    dbg_assert ( !msg_check_wrong_mme_const_values (msg));
    dbg_assert(msg_size <= SAR_MSDU_PAYLOAD_MAX_SIZE);

    // find the tei of the ODA
    tei = station_find_tei_from_mac(msg->oda);
    // check if the message is software encrypted
    if(msg_param.encryption == SOFTWARE_ENCRYPTED)
    {
        
    }
    else
    {
        // and then, send the message
        interf_send (msg, msg_size, msg_param, tei);
    }
}