Files
openbts/GPRS/RLCMessages.cpp
2014-07-16 23:57:22 +02:00

201 lines
5.8 KiB
C++

/*
* Copyright 2011, 2014 Range Networks, Inc.
*
* This software is distributed under multiple licenses;
* see the COPYING file in the main directory for licensing
* information for this specific distribution.
*
* This use of this software may be subject to additional restrictions.
* See the LEGAL file in the main directory for details.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
/**@file GPRS L2 RLC Messages, from GSM 04.60 Section 11 */
#define LOG_GROUP LogGroup::GPRS // Can set Log.Level.GPRS for debugging
//#include <iostream>
#include "Defines.h"
//#include "GSMCommon.h"
#include <BitVector.h>
#include <Logger.h>
#define RLCHDR_IMPLEMENTATION 1
#include "RLCHdr.h"
#include "TBF.h"
#define RLCMESSAGES_IMPLEMENTATION 1
#include "RLCMessages.h"
#include "MAC.h"
#include "FEC.h"
namespace GPRS {
const char *RLCUplinkMessage::name(MessageType type)
{
static char buf[50];
switch (type) {
CASENAME(PacketCellChangeFailure)
CASENAME(PacketControlAcknowledgement)
CASENAME(PacketDownlinkAckNack)
CASENAME(PacketUplinkDummyControlBlock)
CASENAME(PacketMeasurementReport)
CASENAME(PacketEnhancedMeasurementReport)
CASENAME(PacketResourceRequest)
CASENAME(PacketMobileTBFStatus)
CASENAME(PacketPSIStatus)
CASENAME(EGPRSPacketDownlinkAckNack)
CASENAME(PacketPause)
CASENAME(AdditionalMSRadioAccessCapabilities)
default:
sprintf(buf,"RLCUplinkMessageType %d (unknown)",(int)type);
return buf;
}
}
const char *RLCDownlinkMessage::name(MessageType type)
{
static char buf[50];
switch (type) {
CASENAME(PacketAccessReject )
CASENAME(PacketCellChangeOrder)
CASENAME(PacketDownlinkAssignment)
CASENAME(PacketMeasurementOrder )
CASENAME(PacketPagingRequest )
CASENAME(PacketPDCHRelease)
CASENAME(PacketPollingRequest)
CASENAME(PacketPowerControlTimingAdvance)
CASENAME(PacketPRACHParameters)
CASENAME(PacketQueueingNotification)
CASENAME(PacketTimeslotReconfigure)
CASENAME(PacketTBFRelease)
CASENAME(PacketUplinkAckNack)
CASENAME(PacketUplinkAssignment)
CASENAME(PacketDownlinkDummyControlBlock)
CASENAME(PSI1)
CASENAME(PSI2)
CASENAME(PSI3)
CASENAME(PSI3bis)
CASENAME(PSI4)
CASENAME(PSI5)
CASENAME(PSI6)
CASENAME(PSI7)
CASENAME(PSI8)
CASENAME(PSI13)
CASENAME(PSI14)
CASENAME(PSI3ter)
CASENAME(PSI3quater)
CASENAME(PSI15)
default:
sprintf(buf,"RLCDownlinkMessageType %d (unknown)",(int)type);
return buf;
}
}
MSInfo *RLCMsgPacketResourceRequest::getMS(PDCHL1FEC *chan, bool create)
{
// If MS is identified by a TLLI, the msg is not specifically associated with a TBF.
if (mTLLIPresent) {
MSInfo *ms = gL2MAC.macFindMSByTlli(mTLLI, create);
return ms;
} else {
RLCDirType dir = mGTFI.mIsDownlinkTFI ? RLCDir::Down : RLCDir::Up;
TBF *tbf = chan->getTFITBF(mGTFI.mGTFI,dir);
if (tbf) return tbf->mtMS;
}
return NULL;
}
void RLCMsgPacketUplinkAssignmentDynamicAllocationElt::setFrom(TBF *tbf,MultislotSymmetry sym)
{
MSInfo *ms = tbf->mtMS;
setAlpha(ms->msGetAlpha());
PDCHL1Uplink *up;
RN_FOR_ALL(PDCHL1UplinkList_t,ms->msPCHUps,up) {
int tn = up->TN();
setUSF(tn,ms->msUSFs[tn]);
setGamma(tn,ms->msGetGamma());
}
if (ms->isExtendedDynamic()) {
mExtendedDynamicAllocation = true;
}
//if (sym == MultislotSymmetric && isExtendedDynamic()) {
// // This sounds odd, but we need to use the downlink timeslots to program
// // the uplink timeslots so that they will be symmetric.
// // If they are assymetric, the smaller array is always valid in both directions.
// PDCHL1Downlink *down;
// RN_FOR_ALL(PDCHL1DownlinkList_t,ms->msPCHDowns,down) {
// int tn = down->TN();
// setUSF(tn,ms->msUSFs[tn]);
// setGamma(tn,ms->msGetGamma());
// }
//} else {
// PDCHL1Uplink *up;
// RN_FOR_ALL(PDCHL1UplinkList_t,ms->msPCHUps,up) {
// int tn = up->TN();
// setUSF(tn,ms->msUSFs[tn]);
// setGamma(tn,ms->msGetGamma());
// }
//}
}
void RLCMsgPowerControlParametersIE::setFrom(TBF *tbf)
{
MSInfo *ms = tbf->mtMS;
setAlpha(ms->msGetAlpha());
PDCHL1Downlink *down;
RN_FOR_ALL(PDCHL1DownlinkList_t,ms->msPCHDowns,down) {
int tn = down->TN();
setGamma(tn,ms->msGetGamma());
}
}
/** GSM 04.60 11.2
* Process/parse all uplink messages
* */
RLCUplinkMessage* RLCUplinkMessageParse(RLCRawBlock *src)
{
RLCUplinkMessage *result = NULL;
unsigned mMessageType = src->mData.peekField(8,6);
// Kyle reported that OpenBTS crashes parsing the RLCMsgMSRACapabilityValuePartIE.
// If you look at the message that is in, if the RACap is trashed, the message is unusable.
// So lets catch errors way up at this level, and ignore them on error.
// In case of error, we are probably permanently losing the memory associated with the messsage, oh well.
try {
switch (mMessageType) {
case RLCUplinkMessage::PacketControlAcknowledgement:
result = new RLCMsgPacketControlAcknowledgement(src);
break;
case RLCUplinkMessage::PacketDownlinkAckNack:
// Thats right: DownlinkAckNack is an uplink message.
result = new RLCMsgPacketDownlinkAckNack(src);
break;
case RLCUplinkMessage::PacketUplinkDummyControlBlock:
result = new RLCMsgPacketUplinkDummyControlBlock(src);
break;
case RLCUplinkMessage::PacketResourceRequest:
result = new RLCMsgPacketResourceRequest(src);
break;
// case PacketMobileTBFStatus:
// case AdditionalMSRadioAccessCapabilities:
default:
GLOG(INFO) << "unsupported RLC uplink message, type=" << mMessageType;
//result = new RLCMsgPacketUplinkDummyControlBlock(src);
return NULL;
}
return result;
} catch (ByteVectorError) {
GLOG(ERR) << "Parse Error: Premature end of message, type="
<<mMessageType<<"="<<RLCUplinkMessage::name((RLCUplinkMessage::MessageType)mMessageType);
}
return NULL;
};
}; // namespace GPRS