A Discrete-Event Network Simulator
Home
Tutorials ▼
English
Portuguese
Docs ▼
Wiki
Manual
Models
Develop ▼
API
Bugs
API
Main Page
Related Pages
Modules
Namespaces
Classes
Files
File List
File Members
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Properties
Friends
Macros
Groups
Pages
lte-ue-mac.cc
Go to the documentation of this file.
1
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
* Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
4
*
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License version 2 as
7
* published by the Free Software Foundation;
8
*
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
13
*
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
*
18
* Author: Nicola Baldo <nbaldo@cttc.es>
19
* Author: Marco Miozzo <mmiozzo@cttc.es>
20
*/
21
22
23
24
#include <ns3/log.h>
25
#include <ns3/pointer.h>
26
#include <ns3/packet.h>
27
#include <ns3/packet-burst.h>
28
29
#include "
lte-ue-mac.h
"
30
#include "
lte-ue-net-device.h
"
31
#include "
lte-radio-bearer-tag.h
"
32
#include <ns3/ff-mac-common.h>
33
#include <ns3/ideal-control-messages.h>
34
#include <ns3/simulator.h>
35
#include <ns3/lte-common.h>
36
37
38
NS_LOG_COMPONENT_DEFINE
(
"LteUeMac"
);
39
40
namespace
ns3 {
41
42
NS_OBJECT_ENSURE_REGISTERED
(LteUeMac);
43
44
46
// SAP forwarders
48
49
50
class
UeMemberLteUeCmacSapProvider
:
public
LteUeCmacSapProvider
51
{
52
public
:
53
UeMemberLteUeCmacSapProvider
(
LteUeMac
* mac);
54
55
// inherited from LteUeCmacSapProvider
56
virtual
void
ConfigureUe
(uint16_t rnti);
57
virtual
void
AddLc
(uint8_t lcId,
LteMacSapUser
* msu);
58
virtual
void
RemoveLc
(uint8_t lcId);
59
virtual
void
RrcUpdateConfigurationReq
(
LteUeConfig_t
params);
60
61
private
:
62
LteUeMac
*
m_mac
;
63
};
64
65
66
UeMemberLteUeCmacSapProvider::UeMemberLteUeCmacSapProvider
(
LteUeMac
* mac)
67
: m_mac (mac)
68
{
69
}
70
71
void
72
UeMemberLteUeCmacSapProvider::ConfigureUe
(uint16_t rnti)
73
{
74
m_mac
->
DoConfigureUe
(rnti);
75
}
76
77
void
78
UeMemberLteUeCmacSapProvider::AddLc
(uint8_t lcId,
LteMacSapUser
* msu)
79
{
80
m_mac
->
DoAddLc
(lcId, msu);
81
}
82
83
void
84
UeMemberLteUeCmacSapProvider::RemoveLc
(uint8_t lcid)
85
{
86
m_mac
->
DoRemoveLc
(lcid);
87
}
88
89
void
90
UeMemberLteUeCmacSapProvider::RrcUpdateConfigurationReq
(
LteUeConfig_t
params)
91
{
92
m_mac
->
DoRrcUpdateConfigurationReq
(params);
93
}
94
95
96
class
UeMemberLteMacSapProvider
:
public
LteMacSapProvider
97
{
98
public
:
99
UeMemberLteMacSapProvider
(
LteUeMac
* mac);
100
101
// inherited from LteMacSapProvider
102
virtual
void
TransmitPdu
(
TransmitPduParameters
params);
103
virtual
void
ReportBufferStatus
(
ReportBufferStatusParameters
params);
104
105
private
:
106
LteUeMac
*
m_mac
;
107
};
108
109
110
UeMemberLteMacSapProvider::UeMemberLteMacSapProvider
(
LteUeMac
* mac)
111
: m_mac (mac)
112
{
113
}
114
115
void
116
UeMemberLteMacSapProvider::TransmitPdu
(
TransmitPduParameters
params)
117
{
118
m_mac
->
DoTransmitPdu
(params);
119
}
120
121
122
void
123
UeMemberLteMacSapProvider::ReportBufferStatus
(
ReportBufferStatusParameters
params)
124
{
125
m_mac
->
DoReportBufferStatus
(params);
126
}
127
128
129
130
131
class
UeMemberLteUePhySapUser
:
public
LteUePhySapUser
132
{
133
public
:
134
UeMemberLteUePhySapUser
(
LteUeMac
* mac);
135
136
// inherited from LtePhySapUser
137
virtual
void
ReceivePhyPdu
(
Ptr<Packet>
p);
138
virtual
void
SubframeIndication
(uint32_t frameNo, uint32_t subframeNo);
139
virtual
void
ReceiveIdealControlMessage
(
Ptr<IdealControlMessage>
msg);
140
141
private
:
142
LteUeMac
*
m_mac
;
143
};
144
145
UeMemberLteUePhySapUser::UeMemberLteUePhySapUser
(
LteUeMac
* mac) : m_mac (mac)
146
{
147
148
}
149
150
void
151
UeMemberLteUePhySapUser::ReceivePhyPdu
(
Ptr<Packet>
p)
152
{
153
m_mac
->
DoReceivePhyPdu
(p);
154
}
155
156
157
void
158
UeMemberLteUePhySapUser::SubframeIndication
(uint32_t frameNo, uint32_t subframeNo)
159
{
160
m_mac
->
DoSubframeIndication
(frameNo, subframeNo);
161
}
162
163
void
164
UeMemberLteUePhySapUser::ReceiveIdealControlMessage
(
Ptr<IdealControlMessage>
msg)
165
{
166
m_mac
->
DoReceiveIdealControlMessage
(msg);
167
}
168
169
170
171
173
// LteUeMac methods
175
176
177
TypeId
178
LteUeMac::GetTypeId
(
void
)
179
{
180
static
TypeId
tid =
TypeId
(
"ns3::LteUeMac"
)
181
.
SetParent
<
Object
> ()
182
.AddConstructor<LteUeMac> ();
183
return
tid;
184
}
185
186
187
LteUeMac::LteUeMac
()
188
: m_bsrPeriodicity (
MilliSeconds
(1)),
// ideal behavior
189
m_bsrLast (
MilliSeconds
(0)),
190
m_freshUlBsr (false)
191
192
{
193
NS_LOG_FUNCTION
(
this
);
194
m_macSapProvider
=
new
UeMemberLteMacSapProvider
(
this
);
195
m_cmacSapProvider
=
new
UeMemberLteUeCmacSapProvider
(
this
);
196
m_uePhySapUser
=
new
UeMemberLteUePhySapUser
(
this
);
197
}
198
199
200
LteUeMac::~LteUeMac
()
201
{
202
NS_LOG_FUNCTION
(
this
);
203
}
204
205
void
206
LteUeMac::DoDispose
()
207
{
208
NS_LOG_FUNCTION
(
this
);
209
delete
m_macSapProvider
;
210
delete
m_cmacSapProvider
;
211
delete
m_uePhySapUser
;
212
Object::DoDispose
();
213
}
214
215
216
LteUePhySapUser
*
217
LteUeMac::GetLteUePhySapUser
(
void
)
218
{
219
return
m_uePhySapUser
;
220
}
221
222
void
223
LteUeMac::SetLteUePhySapProvider
(
LteUePhySapProvider
* s)
224
{
225
m_uePhySapProvider
= s;
226
}
227
228
229
LteMacSapProvider
*
230
LteUeMac::GetLteMacSapProvider
(
void
)
231
{
232
return
m_macSapProvider
;
233
}
234
235
void
236
LteUeMac::SetLteUeCmacSapUser
(
LteUeCmacSapUser
* s)
237
{
238
m_cmacSapUser
= s;
239
}
240
241
LteUeCmacSapProvider
*
242
LteUeMac::GetLteUeCmacSapProvider
(
void
)
243
{
244
return
m_cmacSapProvider
;
245
}
246
247
248
void
249
LteUeMac::DoTransmitPdu
(
LteMacSapProvider::TransmitPduParameters
params)
250
{
251
NS_LOG_FUNCTION
(
this
);
252
NS_ASSERT_MSG
(
m_rnti
== params.
rnti
,
"RNTI mismatch between RLC and MAC"
);
253
LteRadioBearerTag
tag (params.
rnti
, params.
lcid
, 0
/* UE works in SISO mode*/
);
254
params.
pdu
->
AddPacketTag
(tag);
255
// Ptr<PacketBurst> pb = CreateObject<PacketBurst> ();
256
// pb->AddPacket (params.pdu);
257
m_uePhySapProvider
->
SendMacPdu
(params.
pdu
);
258
// Uplink not implemented yet, so we wait can wait for the PHY SAP
259
// to be defined before we implement the transmission method.
260
}
261
262
void
263
LteUeMac::DoReportBufferStatus
(
LteMacSapProvider::ReportBufferStatusParameters
params)
264
{
265
NS_LOG_FUNCTION
(
this
);
266
267
std::map <uint8_t, uint64_t>::iterator it;
268
269
270
it =
m_ulBsrReceived
.find (params.
lcid
);
271
if
(it!=
m_ulBsrReceived
.end ())
272
{
273
// update entry
274
(*it).second = params.
txQueueSize
+ params.
retxQueueSize
+ params.
statusPduSize
;
275
}
276
else
277
{
278
m_ulBsrReceived
.insert (std::pair<uint8_t, uint64_t> (params.
lcid
, params.
txQueueSize
+ params.
retxQueueSize
+ params.
statusPduSize
));
279
}
280
m_freshUlBsr
=
true
;
281
}
282
283
284
void
285
LteUeMac::SendReportBufferStatus
(
void
)
286
{
287
NS_LOG_FUNCTION
(
this
);
288
if
(
m_ulBsrReceived
.size () == 0)
289
{
290
return
;
// No BSR report to transmit
291
}
292
MacCeListElement_s
bsr;
293
bsr.
m_rnti
=
m_rnti
;
294
bsr.
m_macCeType
=
MacCeListElement_s::BSR
;
295
296
// BSR is reported for each LCG. As a simplification, we consider that all LCs belong to the first LCG.
297
std::map <uint8_t, uint64_t>::iterator it;
298
int
queue = 0;
299
for
(it =
m_ulBsrReceived
.begin (); it !=
m_ulBsrReceived
.end (); it++)
300
{
301
queue += (*it).second;
302
303
}
304
int
index =
BufferSizeLevelBsr::BufferSize2BsrId
(queue);
305
bsr.
m_macCeValue
.
m_bufferStatus
.push_back (index);
306
// FF API says that all 4 LCGs are always present
307
// we do so but reporting a 0 size for all other LCGs
308
bsr.
m_macCeValue
.
m_bufferStatus
.push_back (
BufferSizeLevelBsr::BufferSize2BsrId
(0));
309
bsr.
m_macCeValue
.
m_bufferStatus
.push_back (
BufferSizeLevelBsr::BufferSize2BsrId
(0));
310
bsr.
m_macCeValue
.
m_bufferStatus
.push_back (
BufferSizeLevelBsr::BufferSize2BsrId
(0));
311
312
// create the feedback to eNB
313
Ptr<BsrIdealControlMessage>
msg = Create<BsrIdealControlMessage> ();
314
msg->SetBsr (bsr);
315
m_uePhySapProvider
->
SendIdealControlMessage
(msg);
316
317
}
318
319
void
320
LteUeMac::DoConfigureUe
(uint16_t rnti)
321
{
322
NS_LOG_FUNCTION
(
this
<<
" rnti"
<< rnti);
323
m_rnti
= rnti;
324
}
325
326
void
327
LteUeMac::DoAddLc
(uint8_t lcId,
LteMacSapUser
* msu)
328
{
329
NS_LOG_FUNCTION
(
this
<<
" lcId"
<< (uint16_t) lcId);
330
NS_ASSERT_MSG
(
m_macSapUserMap
.find (lcId) ==
m_macSapUserMap
.end (),
"cannot add channel because LCID "
<< lcId <<
" is already present"
);
331
m_macSapUserMap
[lcId] = msu;
332
}
333
334
void
335
LteUeMac::DoRemoveLc
(uint8_t lcId)
336
{
337
NS_LOG_FUNCTION
(
this
<<
" lcId"
<< lcId);
338
NS_ASSERT_MSG
(
m_macSapUserMap
.find (lcId) ==
m_macSapUserMap
.end (),
"could not find LCID "
<< lcId);
339
m_macSapUserMap
.erase (lcId);
340
}
341
342
void
343
LteUeMac::DoRrcUpdateConfigurationReq
(
LteUeConfig_t
params)
344
{
345
NS_LOG_FUNCTION
(
this
<<
" txMode "
<< (uint8_t) params.
m_transmissionMode
);
346
// forward info to PHY layer
347
m_uePhySapProvider
->
SetTransmissionMode
(params.
m_transmissionMode
);
348
}
349
350
351
void
352
LteUeMac::DoReceivePhyPdu
(
Ptr<Packet>
p)
353
{
354
LteRadioBearerTag
tag;
355
p->
RemovePacketTag
(tag);
356
if
(tag.
GetRnti
() ==
m_rnti
)
357
{
358
// packet is for the current user
359
std::map <uint8_t, LteMacSapUser*>::const_iterator it =
m_macSapUserMap
.find (tag.
GetLcid
());
360
NS_ASSERT_MSG
(it !=
m_macSapUserMap
.end (),
"received packet with unknown lcid"
);
361
it->second->ReceivePdu (p);
362
}
363
}
364
365
366
void
367
LteUeMac::DoReceiveIdealControlMessage
(
Ptr<IdealControlMessage>
msg)
368
{
369
NS_LOG_FUNCTION
(
this
);
370
if
(msg->
GetMessageType
() ==
IdealControlMessage::UL_DCI
)
371
{
372
Ptr<UlDciIdealControlMessage>
msg2 = DynamicCast<UlDciIdealControlMessage> (msg);
373
UlDciListElement_s
dci = msg2->GetDci ();
374
std::map <uint8_t, uint64_t>::iterator itBsr;
375
NS_ASSERT_MSG
(
m_ulBsrReceived
.size () <=4,
" Too many LCs (max is 4)"
);
376
uint16_t activeLcs = 0;
377
for
(itBsr =
m_ulBsrReceived
.begin (); itBsr !=
m_ulBsrReceived
.end (); itBsr++)
378
{
379
if
((*itBsr).second > 0)
380
{
381
activeLcs++;
382
}
383
}
384
if
(activeLcs == 0)
385
{
386
NS_LOG_ERROR
(
this
<<
" No active flows for this UL-DCI"
);
387
return
;
388
}
389
std::map <uint8_t, LteMacSapUser*>::iterator it;
390
NS_LOG_FUNCTION
(
this
<<
" UE: UL-CQI notified TxOpportunity of "
<< dci.m_tbSize);
391
for
(it =
m_macSapUserMap
.begin (); it!=
m_macSapUserMap
.end (); it++)
392
{
393
itBsr =
m_ulBsrReceived
.find ((*it).first);
394
if
(itBsr!=
m_ulBsrReceived
.end ())
395
{
396
NS_LOG_FUNCTION
(
this
<<
"\t"
<< dci.m_tbSize /
m_macSapUserMap
.size () <<
" bytes to LC "
<< (uint16_t)(*it).first <<
" queue "
<< (*itBsr).second);
397
(*it).second->NotifyTxOpportunity (dci.m_tbSize / activeLcs, 0);
398
if
((*itBsr).second >= static_cast<uint64_t> (dci.m_tbSize / activeLcs))
399
{
400
(*itBsr).second -= dci.m_tbSize / activeLcs;
401
}
402
else
403
{
404
(*itBsr).second = 0;
405
}
406
}
407
}
408
409
}
410
else
411
{
412
NS_LOG_FUNCTION
(
this
<<
" IdealControlMessage not recognized"
);
413
}
414
}
415
416
417
void
418
LteUeMac::DoSubframeIndication
(uint32_t frameNo, uint32_t subframeNo)
419
{
420
NS_LOG_FUNCTION
(
this
);
421
if
((
Simulator::Now
() >=
m_bsrLast
+
m_bsrPeriodicity
) && (
m_freshUlBsr
==
true
))
422
{
423
SendReportBufferStatus
();
424
m_bsrLast
=
Simulator::Now
();
425
m_freshUlBsr
=
false
;
426
}
427
}
428
429
430
}
// namespace ns3
src
lte
model
lte-ue-mac.cc
Generated on Tue Oct 9 2012 16:45:41 for ns-3 by
1.8.1.2