1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3 * Copyright (c) 2012 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 */
20
21 #include <ns3/fatal-error.h>
22 #include <ns3/log.h>
23 #include <ns3/nstime.h>
24 #include <ns3/node-list.h>
25 #include <ns3/node.h>
26 #include <ns3/simulator.h>
27
28 #include "lte-rrc-protocol-ideal.h"
29 #include "lte-ue-rrc.h"
30 #include "lte-enb-rrc.h"
31 #include "lte-enb-net-device.h"
32 #include "lte-ue-net-device.h"
33
34 namespace ns3 {
35
36 NS_LOG_COMPONENT_DEFINE ("LteRrcProtocolIdeal");
37
38 /**
39 * \ingroup lte
40 *
41 */
42
43 /// RRC ideal message delay
44 static const Time RRC_IDEAL_MSG_DELAY = MilliSeconds (0);
45
46 NS_OBJECT_ENSURE_REGISTERED (LteUeRrcProtocolIdeal);
47
LteUeRrcProtocolIdeal()48 LteUeRrcProtocolIdeal::LteUeRrcProtocolIdeal ()
49 : m_ueRrcSapProvider (0),
50 m_enbRrcSapProvider (0)
51 {
52 m_ueRrcSapUser = new MemberLteUeRrcSapUser<LteUeRrcProtocolIdeal> (this);
53 }
54
~LteUeRrcProtocolIdeal()55 LteUeRrcProtocolIdeal::~LteUeRrcProtocolIdeal ()
56 {
57 }
58
59 void
DoDispose()60 LteUeRrcProtocolIdeal::DoDispose ()
61 {
62 NS_LOG_FUNCTION (this);
63 delete m_ueRrcSapUser;
64 m_rrc = 0;
65 }
66
67 TypeId
GetTypeId(void)68 LteUeRrcProtocolIdeal::GetTypeId (void)
69 {
70 static TypeId tid = TypeId ("ns3::LteUeRrcProtocolIdeal")
71 .SetParent<Object> ()
72 .SetGroupName("Lte")
73 .AddConstructor<LteUeRrcProtocolIdeal> ()
74 ;
75 return tid;
76 }
77
78 void
SetLteUeRrcSapProvider(LteUeRrcSapProvider * p)79 LteUeRrcProtocolIdeal::SetLteUeRrcSapProvider (LteUeRrcSapProvider* p)
80 {
81 m_ueRrcSapProvider = p;
82 }
83
84 LteUeRrcSapUser*
GetLteUeRrcSapUser()85 LteUeRrcProtocolIdeal::GetLteUeRrcSapUser ()
86 {
87 return m_ueRrcSapUser;
88 }
89
90 void
SetUeRrc(Ptr<LteUeRrc> rrc)91 LteUeRrcProtocolIdeal::SetUeRrc (Ptr<LteUeRrc> rrc)
92 {
93 m_rrc = rrc;
94 }
95
96 void
DoSetup(LteUeRrcSapUser::SetupParameters params)97 LteUeRrcProtocolIdeal::DoSetup (LteUeRrcSapUser::SetupParameters params)
98 {
99 NS_LOG_FUNCTION (this);
100 // We don't care about SRB0/SRB1 since we use ideal RRC messages.
101 }
102
103 void
DoSendRrcConnectionRequest(LteRrcSap::RrcConnectionRequest msg)104 LteUeRrcProtocolIdeal::DoSendRrcConnectionRequest (LteRrcSap::RrcConnectionRequest msg)
105 {
106 // initialize the RNTI and get the EnbLteRrcSapProvider for the
107 // eNB we are currently attached to
108 m_rnti = m_rrc->GetRnti ();
109 SetEnbRrcSapProvider ();
110
111 Simulator::Schedule (RRC_IDEAL_MSG_DELAY,
112 &LteEnbRrcSapProvider::RecvRrcConnectionRequest,
113 m_enbRrcSapProvider,
114 m_rnti,
115 msg);
116 }
117
118 void
DoSendRrcConnectionSetupCompleted(LteRrcSap::RrcConnectionSetupCompleted msg)119 LteUeRrcProtocolIdeal::DoSendRrcConnectionSetupCompleted (LteRrcSap::RrcConnectionSetupCompleted msg)
120 {
121 Simulator::Schedule (RRC_IDEAL_MSG_DELAY,
122 &LteEnbRrcSapProvider::RecvRrcConnectionSetupCompleted,
123 m_enbRrcSapProvider,
124 m_rnti,
125 msg);
126 }
127
128 void
DoSendRrcConnectionReconfigurationCompleted(LteRrcSap::RrcConnectionReconfigurationCompleted msg)129 LteUeRrcProtocolIdeal::DoSendRrcConnectionReconfigurationCompleted (LteRrcSap::RrcConnectionReconfigurationCompleted msg)
130 {
131 // re-initialize the RNTI and get the EnbLteRrcSapProvider for the
132 // eNB we are currently attached to
133 m_rnti = m_rrc->GetRnti ();
134 SetEnbRrcSapProvider ();
135
136 Simulator::Schedule (RRC_IDEAL_MSG_DELAY,
137 &LteEnbRrcSapProvider::RecvRrcConnectionReconfigurationCompleted,
138 m_enbRrcSapProvider,
139 m_rnti,
140 msg);
141 }
142
143 void
DoSendRrcConnectionReestablishmentRequest(LteRrcSap::RrcConnectionReestablishmentRequest msg)144 LteUeRrcProtocolIdeal::DoSendRrcConnectionReestablishmentRequest (LteRrcSap::RrcConnectionReestablishmentRequest msg)
145 {
146 Simulator::Schedule (RRC_IDEAL_MSG_DELAY,
147 &LteEnbRrcSapProvider::RecvRrcConnectionReestablishmentRequest,
148 m_enbRrcSapProvider,
149 m_rnti,
150 msg);
151 }
152
153 void
DoSendRrcConnectionReestablishmentComplete(LteRrcSap::RrcConnectionReestablishmentComplete msg)154 LteUeRrcProtocolIdeal::DoSendRrcConnectionReestablishmentComplete (LteRrcSap::RrcConnectionReestablishmentComplete msg)
155 {
156 Simulator::Schedule (RRC_IDEAL_MSG_DELAY,
157 &LteEnbRrcSapProvider::RecvRrcConnectionReestablishmentComplete,
158 m_enbRrcSapProvider,
159 m_rnti,
160 msg);
161 }
162
163 void
DoSendMeasurementReport(LteRrcSap::MeasurementReport msg)164 LteUeRrcProtocolIdeal::DoSendMeasurementReport (LteRrcSap::MeasurementReport msg)
165 {
166 Simulator::Schedule (RRC_IDEAL_MSG_DELAY,
167 &LteEnbRrcSapProvider::RecvMeasurementReport,
168 m_enbRrcSapProvider,
169 m_rnti,
170 msg);
171 }
172
173 void
DoSendIdealUeContextRemoveRequest(uint16_t rnti)174 LteUeRrcProtocolIdeal::DoSendIdealUeContextRemoveRequest (uint16_t rnti)
175 {
176 NS_LOG_FUNCTION (this);
177
178 uint16_t cellId = m_rrc->GetCellId ();
179 // re-initialize the RNTI and get the EnbLteRrcSapProvider for the
180 // eNB we are currently attached to or attempting random access to
181 // a target eNB
182 m_rnti = m_rrc->GetRnti ();
183
184 NS_LOG_DEBUG ("RNTI " << rnti
185 << " sending UE context remove request to cell id " << cellId);
186 NS_ABORT_MSG_IF (m_rnti != rnti, "RNTI mismatch");
187
188 SetEnbRrcSapProvider (); //the provider has to be reset since the cell might have changed due to handover
189 //ideally informing eNB
190 Simulator::Schedule (RRC_IDEAL_MSG_DELAY, &LteEnbRrcSapProvider::RecvIdealUeContextRemoveRequest,
191 m_enbRrcSapProvider, m_rnti);
192 }
193
194 void
SetEnbRrcSapProvider()195 LteUeRrcProtocolIdeal::SetEnbRrcSapProvider ()
196 {
197 NS_LOG_FUNCTION (this);
198
199 uint16_t cellId = m_rrc->GetCellId ();
200 NS_LOG_DEBUG ("RNTI " << m_rnti << " connected to cell " << cellId);
201
202 // walk list of all nodes to get the peer eNB
203 Ptr<LteEnbNetDevice> enbDev;
204 NodeList::Iterator listEnd = NodeList::End ();
205 bool found = false;
206 for (NodeList::Iterator i = NodeList::Begin ();
207 (i != listEnd) && (!found);
208 ++i)
209 {
210 Ptr<Node> node = *i;
211 int nDevs = node->GetNDevices ();
212 for (int j = 0;
213 (j < nDevs) && (!found);
214 j++)
215 {
216 enbDev = node->GetDevice (j)->GetObject <LteEnbNetDevice> ();
217 if (enbDev == 0)
218 {
219 continue;
220 }
221 else
222 {
223 if (enbDev->HasCellId (cellId))
224 {
225 found = true;
226 break;
227 }
228 }
229 }
230 }
231 NS_ASSERT_MSG (found, " Unable to find eNB with CellId =" << cellId);
232 m_enbRrcSapProvider = enbDev->GetRrc ()->GetLteEnbRrcSapProvider ();
233 Ptr<LteEnbRrcProtocolIdeal> enbRrcProtocolIdeal = enbDev->GetRrc ()->GetObject<LteEnbRrcProtocolIdeal> ();
234 enbRrcProtocolIdeal->SetUeRrcSapProvider (m_rnti, m_ueRrcSapProvider);
235 }
236
237
238 NS_OBJECT_ENSURE_REGISTERED (LteEnbRrcProtocolIdeal);
239
LteEnbRrcProtocolIdeal()240 LteEnbRrcProtocolIdeal::LteEnbRrcProtocolIdeal ()
241 : m_enbRrcSapProvider (0)
242 {
243 NS_LOG_FUNCTION (this);
244 m_enbRrcSapUser = new MemberLteEnbRrcSapUser<LteEnbRrcProtocolIdeal> (this);
245 }
246
~LteEnbRrcProtocolIdeal()247 LteEnbRrcProtocolIdeal::~LteEnbRrcProtocolIdeal ()
248 {
249 NS_LOG_FUNCTION (this);
250 }
251
252 void
DoDispose()253 LteEnbRrcProtocolIdeal::DoDispose ()
254 {
255 NS_LOG_FUNCTION (this);
256 delete m_enbRrcSapUser;
257 }
258
259 TypeId
GetTypeId(void)260 LteEnbRrcProtocolIdeal::GetTypeId (void)
261 {
262 static TypeId tid = TypeId ("ns3::LteEnbRrcProtocolIdeal")
263 .SetParent<Object> ()
264 .SetGroupName("Lte")
265 .AddConstructor<LteEnbRrcProtocolIdeal> ()
266 ;
267 return tid;
268 }
269
270 void
SetLteEnbRrcSapProvider(LteEnbRrcSapProvider * p)271 LteEnbRrcProtocolIdeal::SetLteEnbRrcSapProvider (LteEnbRrcSapProvider* p)
272 {
273 m_enbRrcSapProvider = p;
274 }
275
276 LteEnbRrcSapUser*
GetLteEnbRrcSapUser()277 LteEnbRrcProtocolIdeal::GetLteEnbRrcSapUser ()
278 {
279 return m_enbRrcSapUser;
280 }
281
282 void
SetCellId(uint16_t cellId)283 LteEnbRrcProtocolIdeal::SetCellId (uint16_t cellId)
284 {
285 m_cellId = cellId;
286 }
287
288 LteUeRrcSapProvider*
GetUeRrcSapProvider(uint16_t rnti)289 LteEnbRrcProtocolIdeal::GetUeRrcSapProvider (uint16_t rnti)
290 {
291 std::map<uint16_t, LteUeRrcSapProvider*>::const_iterator it;
292 it = m_enbRrcSapProviderMap.find (rnti);
293 NS_ASSERT_MSG (it != m_enbRrcSapProviderMap.end (), "could not find RNTI = " << rnti);
294 return it->second;
295 }
296
297 void
SetUeRrcSapProvider(uint16_t rnti,LteUeRrcSapProvider * p)298 LteEnbRrcProtocolIdeal::SetUeRrcSapProvider (uint16_t rnti, LteUeRrcSapProvider* p)
299 {
300 std::map<uint16_t, LteUeRrcSapProvider*>::iterator it;
301 it = m_enbRrcSapProviderMap.find (rnti);
302 NS_ASSERT_MSG (it != m_enbRrcSapProviderMap.end (), "Cell id " << m_cellId
303 << " could not find RNTI = " << rnti);
304 it->second = p;
305 }
306
307 void
DoSetupUe(uint16_t rnti,LteEnbRrcSapUser::SetupUeParameters params)308 LteEnbRrcProtocolIdeal::DoSetupUe (uint16_t rnti, LteEnbRrcSapUser::SetupUeParameters params)
309 {
310 NS_LOG_FUNCTION (this << rnti);
311
312 // // walk list of all nodes to get the peer UE RRC SAP Provider
313 // Ptr<LteUeRrc> ueRrc;
314 // NodeList::Iterator listEnd = NodeList::End ();
315 // bool found = false;
316 // for (NodeList::Iterator i = NodeList::Begin (); (i != listEnd) && (found == false); i++)
317 // {
318 // Ptr<Node> node = *i;
319 // int nDevs = node->GetNDevices ();
320 // for (int j = 0; j < nDevs; j++)
321 // {
322 // Ptr<LteUeNetDevice> ueDev = node->GetDevice (j)->GetObject <LteUeNetDevice> ();
323 // if (!ueDev)
324 // {
325 // continue;
326 // }
327 // else
328 // {
329 // ueRrc = ueDev->GetRrc ();
330 // if ((ueRrc->GetRnti () == rnti) && (ueRrc->GetCellId () == m_cellId))
331 // {
332 // found = true;
333 // break;
334 // }
335 // }
336 // }
337 // }
338 // NS_ASSERT_MSG (found , " Unable to find UE with RNTI=" << rnti << " cellId=" << m_cellId);
339 // m_enbRrcSapProviderMap[rnti] = ueRrc->GetLteUeRrcSapProvider ();
340
341
342 // just create empty entry, the UeRrcSapProvider will be set by the
343 // ue upon connection request or connection reconfiguration
344 // completed
345 m_enbRrcSapProviderMap[rnti] = 0;
346
347 }
348
349 void
DoRemoveUe(uint16_t rnti)350 LteEnbRrcProtocolIdeal::DoRemoveUe (uint16_t rnti)
351 {
352 NS_LOG_FUNCTION (this << rnti);
353 m_enbRrcSapProviderMap.erase (rnti);
354 }
355
356 void
DoSendSystemInformation(uint16_t cellId,LteRrcSap::SystemInformation msg)357 LteEnbRrcProtocolIdeal::DoSendSystemInformation (uint16_t cellId, LteRrcSap::SystemInformation msg)
358 {
359 NS_LOG_FUNCTION (this << cellId);
360 // walk list of all nodes to get UEs with this cellId
361 Ptr<LteUeRrc> ueRrc;
362 for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
363 {
364 Ptr<Node> node = *i;
365 int nDevs = node->GetNDevices ();
366 for (int j = 0; j < nDevs; ++j)
367 {
368 Ptr<LteUeNetDevice> ueDev = node->GetDevice (j)->GetObject <LteUeNetDevice> ();
369 if (ueDev != 0)
370 {
371 Ptr<LteUeRrc> ueRrc = ueDev->GetRrc ();
372 NS_LOG_LOGIC ("considering UE IMSI " << ueDev->GetImsi () << " that has cellId " << ueRrc->GetCellId ());
373 if (ueRrc->GetCellId () == cellId)
374 {
375 NS_LOG_LOGIC ("sending SI to IMSI " << ueDev->GetImsi ());
376 ueRrc->GetLteUeRrcSapProvider ()->RecvSystemInformation (msg);
377 Simulator::Schedule (RRC_IDEAL_MSG_DELAY,
378 &LteUeRrcSapProvider::RecvSystemInformation,
379 ueRrc->GetLteUeRrcSapProvider (),
380 msg);
381 }
382 }
383 }
384 }
385 }
386
387 void
DoSendRrcConnectionSetup(uint16_t rnti,LteRrcSap::RrcConnectionSetup msg)388 LteEnbRrcProtocolIdeal::DoSendRrcConnectionSetup (uint16_t rnti, LteRrcSap::RrcConnectionSetup msg)
389 {
390 Simulator::Schedule (RRC_IDEAL_MSG_DELAY,
391 &LteUeRrcSapProvider::RecvRrcConnectionSetup,
392 GetUeRrcSapProvider (rnti),
393 msg);
394 }
395
396 void
DoSendRrcConnectionReconfiguration(uint16_t rnti,LteRrcSap::RrcConnectionReconfiguration msg)397 LteEnbRrcProtocolIdeal::DoSendRrcConnectionReconfiguration (uint16_t rnti, LteRrcSap::RrcConnectionReconfiguration msg)
398 {
399 Simulator::Schedule (RRC_IDEAL_MSG_DELAY,
400 &LteUeRrcSapProvider::RecvRrcConnectionReconfiguration,
401 GetUeRrcSapProvider (rnti),
402 msg);
403 }
404
405 void
DoSendRrcConnectionReestablishment(uint16_t rnti,LteRrcSap::RrcConnectionReestablishment msg)406 LteEnbRrcProtocolIdeal::DoSendRrcConnectionReestablishment (uint16_t rnti, LteRrcSap::RrcConnectionReestablishment msg)
407 {
408 Simulator::Schedule (RRC_IDEAL_MSG_DELAY,
409 &LteUeRrcSapProvider::RecvRrcConnectionReestablishment,
410 GetUeRrcSapProvider (rnti),
411 msg);
412 }
413
414 void
DoSendRrcConnectionReestablishmentReject(uint16_t rnti,LteRrcSap::RrcConnectionReestablishmentReject msg)415 LteEnbRrcProtocolIdeal::DoSendRrcConnectionReestablishmentReject (uint16_t rnti, LteRrcSap::RrcConnectionReestablishmentReject msg)
416 {
417 Simulator::Schedule (RRC_IDEAL_MSG_DELAY,
418 &LteUeRrcSapProvider::RecvRrcConnectionReestablishmentReject,
419 GetUeRrcSapProvider (rnti),
420 msg);
421 }
422
423 void
DoSendRrcConnectionRelease(uint16_t rnti,LteRrcSap::RrcConnectionRelease msg)424 LteEnbRrcProtocolIdeal::DoSendRrcConnectionRelease (uint16_t rnti, LteRrcSap::RrcConnectionRelease msg)
425 {
426 Simulator::Schedule (RRC_IDEAL_MSG_DELAY,
427 &LteUeRrcSapProvider::RecvRrcConnectionRelease,
428 GetUeRrcSapProvider (rnti),
429 msg);
430 }
431
432 void
DoSendRrcConnectionReject(uint16_t rnti,LteRrcSap::RrcConnectionReject msg)433 LteEnbRrcProtocolIdeal::DoSendRrcConnectionReject (uint16_t rnti, LteRrcSap::RrcConnectionReject msg)
434 {
435 Simulator::Schedule (RRC_IDEAL_MSG_DELAY,
436 &LteUeRrcSapProvider::RecvRrcConnectionReject,
437 GetUeRrcSapProvider (rnti),
438 msg);
439 }
440
441 /*
442 * The purpose of LteEnbRrcProtocolIdeal is to avoid encoding
443 * messages. In order to do so, we need to have some form of encoding for
444 * inter-node RRC messages like HandoverPreparationInfo and HandoverCommand. Doing so
445 * directly is not practical (these messages includes a lot of
446 * information elements, so encoding all of them would defeat the
447 * purpose of LteEnbRrcProtocolIdeal. The workaround is to store the
448 * actual message in a global map, so that then we can just encode the
449 * key in a header and send that between eNBs over X2.
450 *
451 */
452
453 static std::map<uint32_t, LteRrcSap::HandoverPreparationInfo> g_handoverPreparationInfoMsgMap; ///< handover preparation info message map
454 static uint32_t g_handoverPreparationInfoMsgIdCounter = 0; ///< handover preparation info message ID counter
455
456 /**
457 * This header encodes the map key discussed above. We keep this
458 * private since it should not be used outside this file.
459 *
460 */
461 class IdealHandoverPreparationInfoHeader : public Header
462 {
463 public:
464 /**
465 * Get the message ID function
466 *
467 * \returns the message ID
468 */
469 uint32_t GetMsgId ();
470 /**
471 * Set the message ID function
472 *
473 * \param id the message ID
474 */
475 void SetMsgId (uint32_t id);
476 /**
477 * \brief Get the type ID.
478 * \return the object TypeId
479 */
480 static TypeId GetTypeId (void);
481 virtual TypeId GetInstanceTypeId (void) const;
482 virtual void Print (std::ostream &os) const;
483 virtual uint32_t GetSerializedSize (void) const;
484 virtual void Serialize (Buffer::Iterator start) const;
485 virtual uint32_t Deserialize (Buffer::Iterator start);
486
487 private:
488 uint32_t m_msgId; ///< message ID
489 };
490
491 uint32_t
GetMsgId()492 IdealHandoverPreparationInfoHeader::GetMsgId ()
493 {
494 return m_msgId;
495 }
496
497 void
SetMsgId(uint32_t id)498 IdealHandoverPreparationInfoHeader::SetMsgId (uint32_t id)
499 {
500 m_msgId = id;
501 }
502
503
504 TypeId
GetTypeId(void)505 IdealHandoverPreparationInfoHeader::GetTypeId (void)
506 {
507 static TypeId tid = TypeId ("ns3::IdealHandoverPreparationInfoHeader")
508 .SetParent<Header> ()
509 .SetGroupName("Lte")
510 .AddConstructor<IdealHandoverPreparationInfoHeader> ()
511 ;
512 return tid;
513 }
514
515 TypeId
GetInstanceTypeId(void) const516 IdealHandoverPreparationInfoHeader::GetInstanceTypeId (void) const
517 {
518 return GetTypeId ();
519 }
520
Print(std::ostream & os) const521 void IdealHandoverPreparationInfoHeader::Print (std::ostream &os) const
522 {
523 os << " msgId=" << m_msgId;
524 }
525
GetSerializedSize(void) const526 uint32_t IdealHandoverPreparationInfoHeader::GetSerializedSize (void) const
527 {
528 return 4;
529 }
530
Serialize(Buffer::Iterator start) const531 void IdealHandoverPreparationInfoHeader::Serialize (Buffer::Iterator start) const
532 {
533 start.WriteU32 (m_msgId);
534 }
535
Deserialize(Buffer::Iterator start)536 uint32_t IdealHandoverPreparationInfoHeader::Deserialize (Buffer::Iterator start)
537 {
538 m_msgId = start.ReadU32 ();
539 return GetSerializedSize ();
540 }
541
542
543
544 Ptr<Packet>
DoEncodeHandoverPreparationInformation(LteRrcSap::HandoverPreparationInfo msg)545 LteEnbRrcProtocolIdeal::DoEncodeHandoverPreparationInformation (LteRrcSap::HandoverPreparationInfo msg)
546 {
547 uint32_t msgId = ++g_handoverPreparationInfoMsgIdCounter;
548 NS_ASSERT_MSG (g_handoverPreparationInfoMsgMap.find (msgId) == g_handoverPreparationInfoMsgMap.end (), "msgId " << msgId << " already in use");
549 NS_LOG_INFO (" encoding msgId = " << msgId);
550 g_handoverPreparationInfoMsgMap.insert (std::pair<uint32_t, LteRrcSap::HandoverPreparationInfo> (msgId, msg));
551 IdealHandoverPreparationInfoHeader h;
552 h.SetMsgId (msgId);
553 Ptr<Packet> p = Create<Packet> ();
554 p->AddHeader (h);
555 return p;
556 }
557
558 LteRrcSap::HandoverPreparationInfo
DoDecodeHandoverPreparationInformation(Ptr<Packet> p)559 LteEnbRrcProtocolIdeal::DoDecodeHandoverPreparationInformation (Ptr<Packet> p)
560 {
561 IdealHandoverPreparationInfoHeader h;
562 p->RemoveHeader (h);
563 uint32_t msgId = h.GetMsgId ();
564 NS_LOG_INFO (" decoding msgId = " << msgId);
565 std::map<uint32_t, LteRrcSap::HandoverPreparationInfo>::iterator it = g_handoverPreparationInfoMsgMap.find (msgId);
566 NS_ASSERT_MSG (it != g_handoverPreparationInfoMsgMap.end (), "msgId " << msgId << " not found");
567 LteRrcSap::HandoverPreparationInfo msg = it->second;
568 g_handoverPreparationInfoMsgMap.erase (it);
569 return msg;
570 }
571
572
573
574 static std::map<uint32_t, LteRrcSap::RrcConnectionReconfiguration> g_handoverCommandMsgMap; ///< handover command message map
575 static uint32_t g_handoverCommandMsgIdCounter = 0; ///< handover command message ID counter
576
577 /**
578 * This header encodes the map key discussed above. We keep this
579 * private since it should not be used outside this file.
580 *
581 */
582 class IdealHandoverCommandHeader : public Header
583 {
584 public:
585 /**
586 * Get the message ID function
587 *
588 * \returns the message ID
589 */
590 uint32_t GetMsgId ();
591 /**
592 * Set the message ID function
593 *
594 * \param id the message ID
595 */
596 void SetMsgId (uint32_t id);
597 /**
598 * \brief Get the type ID.
599 * \return the object TypeId
600 */
601 static TypeId GetTypeId (void);
602 virtual TypeId GetInstanceTypeId (void) const;
603 virtual void Print (std::ostream &os) const;
604 virtual uint32_t GetSerializedSize (void) const;
605 virtual void Serialize (Buffer::Iterator start) const;
606 virtual uint32_t Deserialize (Buffer::Iterator start);
607
608 private:
609 uint32_t m_msgId; ///< message ID
610 };
611
612 uint32_t
GetMsgId()613 IdealHandoverCommandHeader::GetMsgId ()
614 {
615 return m_msgId;
616 }
617
618 void
SetMsgId(uint32_t id)619 IdealHandoverCommandHeader::SetMsgId (uint32_t id)
620 {
621 m_msgId = id;
622 }
623
624
625 TypeId
GetTypeId(void)626 IdealHandoverCommandHeader::GetTypeId (void)
627 {
628 static TypeId tid = TypeId ("ns3::IdealHandoverCommandHeader")
629 .SetParent<Header> ()
630 .SetGroupName("Lte")
631 .AddConstructor<IdealHandoverCommandHeader> ()
632 ;
633 return tid;
634 }
635
636 TypeId
GetInstanceTypeId(void) const637 IdealHandoverCommandHeader::GetInstanceTypeId (void) const
638 {
639 return GetTypeId ();
640 }
641
Print(std::ostream & os) const642 void IdealHandoverCommandHeader::Print (std::ostream &os) const
643 {
644 os << " msgId=" << m_msgId;
645 }
646
GetSerializedSize(void) const647 uint32_t IdealHandoverCommandHeader::GetSerializedSize (void) const
648 {
649 return 4;
650 }
651
Serialize(Buffer::Iterator start) const652 void IdealHandoverCommandHeader::Serialize (Buffer::Iterator start) const
653 {
654 start.WriteU32 (m_msgId);
655 }
656
Deserialize(Buffer::Iterator start)657 uint32_t IdealHandoverCommandHeader::Deserialize (Buffer::Iterator start)
658 {
659 m_msgId = start.ReadU32 ();
660 return GetSerializedSize ();
661 }
662
663
664
665 Ptr<Packet>
DoEncodeHandoverCommand(LteRrcSap::RrcConnectionReconfiguration msg)666 LteEnbRrcProtocolIdeal::DoEncodeHandoverCommand (LteRrcSap::RrcConnectionReconfiguration msg)
667 {
668 uint32_t msgId = ++g_handoverCommandMsgIdCounter;
669 NS_ASSERT_MSG (g_handoverCommandMsgMap.find (msgId) == g_handoverCommandMsgMap.end (), "msgId " << msgId << " already in use");
670 NS_LOG_INFO (" encoding msgId = " << msgId);
671 g_handoverCommandMsgMap.insert (std::pair<uint32_t, LteRrcSap::RrcConnectionReconfiguration> (msgId, msg));
672 IdealHandoverCommandHeader h;
673 h.SetMsgId (msgId);
674 Ptr<Packet> p = Create<Packet> ();
675 p->AddHeader (h);
676 return p;
677 }
678
679 LteRrcSap::RrcConnectionReconfiguration
DoDecodeHandoverCommand(Ptr<Packet> p)680 LteEnbRrcProtocolIdeal::DoDecodeHandoverCommand (Ptr<Packet> p)
681 {
682 IdealHandoverCommandHeader h;
683 p->RemoveHeader (h);
684 uint32_t msgId = h.GetMsgId ();
685 NS_LOG_INFO (" decoding msgId = " << msgId);
686 std::map<uint32_t, LteRrcSap::RrcConnectionReconfiguration>::iterator it = g_handoverCommandMsgMap.find (msgId);
687 NS_ASSERT_MSG (it != g_handoverCommandMsgMap.end (), "msgId " << msgId << " not found");
688 LteRrcSap::RrcConnectionReconfiguration msg = it->second;
689 g_handoverCommandMsgMap.erase (it);
690 return msg;
691 }
692
693
694
695
696
697 } // namespace ns3
698