rlc_mac.c 13.1 KB
Newer Older
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
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
/*
                                rlc_mac.c
                             -------------------
  AUTHOR  : Lionel GAUTHIER
  COMPANY : EURECOM
  EMAIL   : Lionel.Gauthier@eurecom.fr
*/

//-----------------------------------------------------------------------------
#define RLC_MAC_C
#include "rlc.h"
#include "LAYER2/MAC/extern.h"
#include "UTIL/LOG/log.h"

#define DEBUG_MAC_INTERFACE

// tb_size_t in bytes
//-----------------------------------------------------------------------------
struct mac_data_ind mac_rlc_deserialize_tb (char* bufferP, tb_size_t tb_sizeP, num_tb_t num_tbP, crc_t *crcsP) {
//-----------------------------------------------------------------------------

  struct mac_data_ind  data_ind;
  mem_block_t*         tb;
  num_tb_t             nb_tb_read;
  tbs_size_t   tbs_size;

  nb_tb_read = 0;
  tbs_size   = 0;
  list_init(&data_ind.data, NULL);

  while (num_tbP > 0) {
        tb = get_free_mem_block(sizeof (mac_rlc_max_rx_header_size_t) + tb_sizeP);
        if (tb != NULL) {
            ((struct mac_tb_ind *) (tb->data))->first_bit = 0;
            ((struct mac_tb_ind *) (tb->data))->data_ptr = (u8_t*)&tb->data[sizeof (mac_rlc_max_rx_header_size_t)];
            ((struct mac_tb_ind *) (tb->data))->size = tb_sizeP;
            if (crcsP)
                ((struct mac_tb_ind *) (tb->data))->error_indication = crcsP[nb_tb_read];
            else
                ((struct mac_tb_ind *) (tb->data))->error_indication = 0;

            memcpy(((struct mac_tb_ind *) (tb->data))->data_ptr, &bufferP[tbs_size], tb_sizeP);

#ifdef DEBUG_MAC_INTERFACE
            LOG_T(RLC, "[MAC-RLC] DUMP RX PDU(%d bytes):\n", tb_sizeP);
            rlc_util_print_hex_octets(RLC, ((struct mac_tb_ind *) (tb->data))->data_ptr, tb_sizeP);
#endif
            nb_tb_read = nb_tb_read + 1;
            tbs_size   = tbs_size   + tb_sizeP;
            list_add_tail_eurecom(tb, &data_ind.data);
        }
        num_tbP = num_tbP - 1;
  }
  data_ind.no_tb            = nb_tb_read;
  data_ind.tb_size          = tb_sizeP << 3;

  return data_ind;
}
//-----------------------------------------------------------------------------
tbs_size_t mac_rlc_serialize_tb (char* bufferP, list_t transport_blocksP) {
//-----------------------------------------------------------------------------
  mem_block_t* tb;
  tbs_size_t   tbs_size;
  tbs_size_t   tb_size;

  tbs_size = 0;
  while (transport_blocksP.nb_elements > 0) {
    tb = list_remove_head (&transport_blocksP);
    if (tb != NULL) {
       tb_size = ((struct mac_tb_req *) (tb->data))->tb_size_in_bits>>3;
#ifdef DEBUG_MAC_INTERFACE
        LOG_T(RLC, "[MAC-RLC] DUMP TX PDU(%d bytes):\n", tb_size);
        rlc_util_print_hex_octets(RLC, ((struct mac_tb_req *) (tb->data))->data_ptr, tb_size);
#endif
       memcpy(&bufferP[tbs_size], &((struct mac_tb_req *) (tb->data))->data_ptr[0], tb_size);
       tbs_size = tbs_size + tb_size;
       free_mem_block(tb);
    }
  }
  return tbs_size;
}
//-----------------------------------------------------------------------------
tbs_size_t mac_rlc_data_req     (module_id_t module_idP, u32_t frame, u8_t MBMS_flagP, chan_id_t channel_idP, char* bufferP) {
//-----------------------------------------------------------------------------
    struct mac_data_req    data_request;
    rb_id_t                rb_id;
#ifdef DEBUG_MAC_INTERFACE
    LOG_D(RLC, "\n[RLC] Inst %d(%d): MAC_RLC_DATA_REQ channel %d (%d) MAX RB %d, Num_tb %d\n",
	    module_idP,MAX_MODULES,  channel_idP, RLC_MAX_LC, RLC_MAX_RB);
    
#endif // DEBUG_MAC_INTERFACE

    if ((module_idP >= 0) && (module_idP < MAX_MODULES)) {
        if ((channel_idP >= 0) && (channel_idP < RLC_MAX_LC)) {
            rb_id = rlc[module_idP].m_lcid2rbid[channel_idP];
            if ((rb_id > 0) && (rb_id < RLC_MAX_RB)) {
                switch (rlc[module_idP].m_rlc_pointer[rb_id].rlc_type) {
                    case RLC_NONE:
                        //handle_event(WARNING,"FILE %s FONCTION mac_rlc_data_ind() LINE %s : no radio bearer configured :%d\n", __FILE__, __LINE__, channel_idP);
                        break;

                    case RLC_AM:
                        data_request = rlc_am_mac_data_request(&rlc[module_idP].m_rlc_am_array[rlc[module_idP].m_rlc_pointer[rb_id].rlc_index], frame);
                        return mac_rlc_serialize_tb(bufferP, data_request.data);
                        break;

                    case RLC_UM:
                        data_request = rlc_um_mac_data_request(&rlc[module_idP].m_rlc_um_array[rlc[module_idP].m_rlc_pointer[rb_id].rlc_index], frame);
                        return mac_rlc_serialize_tb(bufferP, data_request.data);
                        break;

                    case RLC_TM:
                        data_request = rlc_tm_mac_data_request(&rlc[module_idP].m_rlc_tm_array[rlc[module_idP].m_rlc_pointer[rb_id].rlc_index], frame);
                        return mac_rlc_serialize_tb(bufferP, data_request.data);
                        break;

                    default:;
                        //handle_event(ERROR,"FILE %s FONCTION mac_rlc_data_ind() LINE %s : no RLC found for this radio bearer %d\n", __FILE__, __LINE__, channel_idP);
                }
            } else {
                LOG_E(RLC, "%s() : radio bearer id out of bounds :%d\n", __FUNCTION__, rb_id);
            }
      } else {
          //handle_event(ERROR,"FILE %s FONCTION mac_rlc_data_ind() LINE %s : parameter rb_id out of bounds :%d\n", __FILE__, __LINE__, channel_idP);
          LOG_E(RLC, "%s() : parameter channel_id out of bounds :%d\n", __FUNCTION__, channel_idP);
          return(-1);
      }
  } else {
      LOG_E(RLC, "%s() : parameter module_id out of bounds :%d\n", __FUNCTION__, module_idP);
  }
  return (tbs_size_t)0;
}
//-----------------------------------------------------------------------------
void mac_rlc_data_ind     (module_id_t module_idP,  u32_t frame, u8_t eNB_flag, u8_t MBMS_flagP, chan_id_t channel_idP, char* bufferP, tb_size_t tb_sizeP, num_tb_t num_tbP, crc_t *crcs) {
//-----------------------------------------------------------------------------
    rb_id_t                rb_id;
#ifdef DEBUG_MAC_INTERFACE
    if (num_tbP) {
      LOG_D(RLC, "\n[RLC] Inst %d(%d): MAC_RLC_DATA_IND on channel %d (%d), rb max %d, Num_tb %d\n",
	    module_idP,MAX_MODULES,  channel_idP, RLC_MAX_LC, RLC_MAX_RB, num_tbP);
    }
#endif // DEBUG_MAC_INTERFACE

    if ((module_idP >= 0) && (module_idP < MAX_MODULES)) {
        if ((channel_idP >= 0) && (channel_idP < RLC_MAX_LC)) {
            rb_id = rlc[module_idP].m_lcid2rbid[channel_idP];
            if ((rb_id > 0) && (rb_id < RLC_MAX_RB)) {
                //if (num_tbP > 0) {
                struct mac_data_ind data_ind = mac_rlc_deserialize_tb(bufferP, tb_sizeP, num_tbP, crcs);

                switch (rlc[module_idP].m_rlc_pointer[rb_id].rlc_type) {
                    case RLC_NONE:
                        //handle_event(WARNING,"FILE %s FONCTION mac_rlc_data_ind() LINE %s : no radio bearer configured :%d\n", __FILE__, __LINE__, rb_idP);
                        LOG_W(RLC, " FONCTION mac_rlc_data_ind()  : no radio bearer configured :%d\n",  rb_id);
                        break;

                    case RLC_AM:
#ifdef DEBUG_MAC_INTERFACE
		      LOG_D(RLC, "MAC DATA IND TO RLC_AM MOD_ID %d RB_INDEX %d (%d) MOD_ID_RLC %d\n", module_idP, rlc[module_idP].m_rlc_pointer[rb_id].rlc_index, rb_id, rlc[module_idP].m_rlc_am_array[rlc[module_idP].m_rlc_pointer[rb_id].rlc_index].module_id);
#endif

                        rlc_am_mac_data_indication(&rlc[module_idP].m_rlc_am_array[rlc[module_idP].m_rlc_pointer[rb_id].rlc_index], frame, eNB_flag, data_ind);
                        break;

                    case RLC_UM:
#ifdef DEBUG_MAC_INTERFACE
                        LOG_D(RLC, "MAC DATA IND TO RLC_UM MOD_ID %d RB_INDEX %d MOD_ID_RLC %d\n", module_idP, rlc[module_idP].m_rlc_pointer[rb_id].rlc_index, rlc[module_idP].m_rlc_um_array[rlc[module_idP].m_rlc_pointer[rb_id].rlc_index].module_id);
#endif
                        rlc_um_mac_data_indication(&rlc[module_idP].m_rlc_um_array[rlc[module_idP].m_rlc_pointer[rb_id].rlc_index], frame, eNB_flag, data_ind);
                        break;

                    case RLC_TM:
#ifdef DEBUG_MAC_INTERFACE
                        LOG_D(RLC, "MAC DATA IND TO RLC_TM MOD_ID %d RB_INDEX %d MOD_ID_RLC %d\n", module_idP, rlc[module_idP].m_rlc_pointer[rb_id].rlc_index, rlc[module_idP].m_rlc_tm_array[rlc[module_idP].m_rlc_pointer[rb_id].rlc_index].module_id);
#endif
                        rlc_tm_mac_data_indication(&rlc[module_idP].m_rlc_tm_array[rlc[module_idP].m_rlc_pointer[rb_id].rlc_index], frame, eNB_flag, data_ind);
                        break;

                    default:
                        //handle_event(ERROR,"FILE %s FONCTION mac_rlc_data_ind() LINE %s : no RLC found for this radio bearer %d\n", __FILE__, __LINE__, rb_idP);
                        LOG_W(RLC, "FILE  FONCTION mac_rlc_data_ind() LINE  : no RLC found for this radio bearer %d\n",  rb_id);
                        ;

                }
            } else {
                LOG_E(RLC, "%s() : radio bearer id out of bounds : rb is %d\n", __FUNCTION__, rb_id);
            }
        } else {
            LOG_E(RLC, "%s() : parameter channel_id out of bounds : channel is %d\n", __FUNCTION__, channel_idP);
        }
    } else {
        LOG_E(RLC, "%s() : parameter module_id out of bounds : module id is %d\n", __FUNCTION__, module_idP);
    }
}
//-----------------------------------------------------------------------------
mac_rlc_status_resp_t mac_rlc_status_ind     (module_id_t module_idP, u32_t frame, u8_t eNB_flag, u8_t MBMS_flagP, chan_id_t channel_idP, tb_size_t tb_sizeP) {
//-----------------------------------------------------------------------------
  rb_id_t                rb_id = 0;
  mac_rlc_status_resp_t  mac_rlc_status_resp;

  mac_rlc_status_resp.bytes_in_buffer = 0;
  mac_rlc_status_resp.pdus_in_buffer  = 0;

  if ((module_idP >= 0) && (module_idP < MAX_MODULES)) {
      if ((channel_idP >= 0) && (channel_idP < RLC_MAX_LC)) {
          rb_id = rlc[module_idP].m_lcid2rbid[channel_idP];
          if ((rb_id > 0) && (rb_id < RLC_MAX_RB)) {
              struct mac_status_resp status_resp;
              struct mac_status_ind tx_status;
                  switch (rlc[module_idP].m_rlc_pointer[channel_idP].rlc_type) {
                    case RLC_NONE:
                        //handle_event(WARNING,"FILE %s FONCTION mac_rlc_data_ind() LINE %s : no radio bearer configured :%d\n", __FILE__, __LINE__, channel_idP);
                        break;

                    case RLC_AM:
                        status_resp = rlc_am_mac_status_indication(&rlc[module_idP].m_rlc_am_array[rlc[module_idP].m_rlc_pointer[channel_idP].rlc_index], frame, tb_sizeP, tx_status);
                        mac_rlc_status_resp.bytes_in_buffer = status_resp.buffer_occupancy_in_bytes;
218
219
220
                        mac_rlc_status_resp.head_sdu_creation_time = status_resp.head_sdu_creation_time;
			 mac_rlc_status_resp.head_sdu_remaining_size_to_send = status_resp.head_sdu_remaining_size_to_send;	
			 mac_rlc_status_resp.head_sdu_is_segmented = status_resp.head_sdu_is_segmented;	
221
222
223
224
225
226
227
                        return mac_rlc_status_resp;
                        break;

                    case RLC_UM:
                        //msg("[RLC_UM][MOD %d] mac_rlc_status_ind  tb_size %d\n", module_idP,  tb_sizeP);
                        status_resp = rlc_um_mac_status_indication(&rlc[module_idP].m_rlc_um_array[rlc[module_idP].m_rlc_pointer[channel_idP].rlc_index], frame, eNB_flag, tb_sizeP, tx_status);
                        mac_rlc_status_resp.bytes_in_buffer = status_resp.buffer_occupancy_in_bytes;
228
229
230
231
                        mac_rlc_status_resp.pdus_in_buffer = status_resp.buffer_occupancy_in_pdus;
			 mac_rlc_status_resp.head_sdu_creation_time = status_resp.head_sdu_creation_time;
			 mac_rlc_status_resp.head_sdu_remaining_size_to_send = status_resp.head_sdu_remaining_size_to_send;
			 mac_rlc_status_resp.head_sdu_is_segmented = status_resp.head_sdu_is_segmented;	
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
                        return mac_rlc_status_resp;
                        break;

                    case RLC_TM:
                        status_resp = rlc_tm_mac_status_indication(&rlc[module_idP].m_rlc_tm_array[rlc[module_idP].m_rlc_pointer[channel_idP].rlc_index], frame, tb_sizeP, tx_status);
                        mac_rlc_status_resp.bytes_in_buffer = status_resp.buffer_occupancy_in_bytes;
                        mac_rlc_status_resp.pdus_in_buffer = status_resp.buffer_occupancy_in_pdus;
                        return mac_rlc_status_resp;
                        break;

                    default:;
                        //handle_event(ERROR,"FILE %s FONCTION mac_rlc_data_ind() LINE %s : no RLC found for this radio bearer %d\n", __FILE__, __LINE__, channel_idP);

                  }
          } else {
              // two many traces because MAC probe inactive channels. LOG_E(RLC, "%s(Mod=%d, eNB_flag=%d, mbms flag=%d,channel_id=%d) : radio bearer id out of bounds :%d \n", __FUNCTION__, module_idP, eNB_flag, MBMS_flagP, channel_idP, rb_id);
          }
      } else {
          LOG_E(RLC, "%s() : parameter channel_id out of bounds :%d\n", __FUNCTION__, channel_idP);
      }
  } else {
      LOG_E(RLC, "%s() : parameter module_id out of bounds :%d\n", __FUNCTION__, module_idP);
  }
  return mac_rlc_status_resp;
}