mirror of
https://github.com/RangeNetworks/openbts.git
synced 2025-10-23 07:42:01 +00:00
523 lines
17 KiB
C++
523 lines
17 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.
|
|
*/
|
|
|
|
#ifndef BSSGMESSAGES_H
|
|
#define BSSGMESSAGES_H
|
|
|
|
|
|
// This file includes both the NS and BSSG layer messages.
|
|
|
|
// For a downlink PDU, we know the size when we receive it.
|
|
// For an uplink data PDU, which comes from RLCEngine, we will allocate the
|
|
// maximum size right off the bat, and let the RLCEngine write the data
|
|
// directly into it. There is no real reason to downsize it; these dont last long.
|
|
|
|
namespace GPRS { extern unsigned GPRSDebug; };
|
|
#include "GPRSExport.h"
|
|
|
|
#include "Defines.h"
|
|
#include "ScalarTypes.h"
|
|
#include "ByteVector.h"
|
|
#include "Utils.h"
|
|
//#ifndef OFFSETOF // This is a standard definition in many header files.
|
|
//#define OFFSETOF(type, field) ((int) ((char *) &((type *) 0)->field))
|
|
//#endif
|
|
|
|
namespace BSSG {
|
|
|
|
// BVCI defined GSM 08.18 5.4.1
|
|
// See table 5.4 for which BVCI to use with each message.
|
|
// The SIGNALLING and PTP numbers are reserved.
|
|
// See LookupBVCI(BSPDUType::type bstype);
|
|
class BVCI {
|
|
public:
|
|
enum type {
|
|
SIGNALLING = 0, // For BSSG BVC messages other than data.
|
|
PTM = 1, // Point to multipoint
|
|
PTP = 2 // Any other value is a base station designator for Point-To-Point data.
|
|
// We only use one value, gBSSG.mbsBVCI, which must be >- PTP.
|
|
};
|
|
};
|
|
|
|
/**********************************************************
|
|
BSSGSP Messages we need to support eventually:
|
|
DL-UNITDATA
|
|
Includes PDU type (DL-UNITDATA), TLLI, QoS Profile, PDU Lifetime, PDU.
|
|
optional: IMSI, oldTLLI, PFI (Packet Flow Identifier), etc.
|
|
UL-UNITDATA
|
|
Includes PDU type (UL-UNITDATA), TLLI, BVCI, Cell Identifier, PDU.
|
|
GMM-PAGING-PS/GMM-PAGING-CS (for packet or voice)
|
|
Includes PDU type (PAGING-PS), QoS Profile, P-TMSI <or> IMSI.
|
|
Note: If TLLI is specified and already exists within a Radio Context in BSS
|
|
[because MS has communicated previously] it is used.
|
|
|
|
BVCI <or> Location Area <or> Routing Area <or> BSSArea Indication
|
|
Optional: P-TMSI, BVCI, Location area, Routing area.
|
|
GMM-RA-CAPABILITY, GMM-RA-CAPABILITY-UPDATE
|
|
Astonishingly, the BSS asks the SGSN for this info.
|
|
It is because the MS may be moving from BTS to BTS, so the SGSN
|
|
is a slightly more permanent repository, and makes handover easier between BTSs.
|
|
But note that the MS can also travel from SGSN to SGSN, so I think the location
|
|
of the MS info is arbitrary.
|
|
We are talking about information that is only kept around a short while anyway.
|
|
GMM-RADIO-STATUS
|
|
GMM-SUSPEND
|
|
GMM-RESUME
|
|
|
|
Note that there are alot of messages to control the data-rate on the BSSG connection.
|
|
None of them are implemented in the SGSN, so we dont support them either.
|
|
**********************************************************/
|
|
|
|
class BSPDUType {
|
|
public:
|
|
// GSM08.18 sec11.3.26 table11.27: PDU Types
|
|
// GSM08.18 table 5.4 defines the BVCI to be used with each message.
|
|
// BVCIs are: PTP, PTM, SIG
|
|
enum type {
|
|
// PDUs between RL and BSSGP SAPs:
|
|
DL_UNITDATA = 0, // PTP network->MS
|
|
UL_UNITDATA = 1, // PTP MS->network
|
|
// PDUs between GMM SAPs.
|
|
RA_CAPABILITY = 2, // PTP network->BSS
|
|
PTM_UNITDATA = 3, // PTM not currently used
|
|
// PDUs between GMM SAPs:
|
|
PAGING_PS = 6, // PTP or SIG network->BSS request to page MS for packet connection.
|
|
PAGING_CS = 7, // PTP or SIG network->BSS request to page MS for RR connection.
|
|
RA_CAPABILITY_UPDATE = 8, // PTP BSS->network request for MS Radio Access Capabilities.
|
|
RA_CAPABILITY_UPDATE_ACK = 9,// PTP network->BSS Radio Access Capability and IMSI.
|
|
RADIO_STATUS = 0x0a, // PTP BSS->SGSN notification of error
|
|
|
|
SUSPEND = 0x0b, // SIG MS->network request to suspend GPRS service.
|
|
SUSPEND_ACK = 0x0c, // SIG network->MS ACK
|
|
SUSPEND_NACK = 0x0d, // SIG network->MS NACK
|
|
RESUME = 0xe, // SIG MS->network request to resume GPRS service.
|
|
RESUME_ACK = 0xf, // SIG network->MS ACK
|
|
RESUME_NACK = 0x10, // SIG network->MS NACK
|
|
// PDUs between NM SAPs:
|
|
// We will not use the flow control stuff, block, unblock, etc.
|
|
BVC_BLOCK = 0x20, // SIG
|
|
BVC_BLOCK_ACK = 0x21, // SIG
|
|
BVC_RESET = 0x22, // SIG network->BSS request reset everything.
|
|
BVC_RESET_ACK = 0x23, // SIG BSS->network and network->BSS?
|
|
BVC_UNBLOCK = 0x24, // SIG
|
|
BVC_UNBLOCK_ACK = 0x25, // SIG
|
|
FLOW_CONTROL_BVC = 0x26, // PTP BSS->network inform maximum throughput on Gb I/F
|
|
FLOW_CONTROL_BVC_ACK = 0x27, // PTP network->BSS
|
|
FLOW_CONTROL_MS = 0x28, // PTP BSS->network inform maximum throughput for MS.
|
|
FLOW_CONTROL_MS_ACK = 0x29, // PTP network->BSS
|
|
FLUSH_LL = 0x2a, // SIG network->BSS forget this MS (it moved to another cell.)
|
|
FLUSH_LL_ACK = 0x2b, // SIG BSS->network
|
|
LLC_DISCARDED = 0x2c, // SIG BSS->network notification of lost PDUs (probably expired)
|
|
// We ignore all these:
|
|
SGSN_INVOKE_TRACE = 0x40, // network->BSS request trace an MS
|
|
STATUS = 0x41, // SIG BSS->network or network->BSS report error condition.
|
|
DOWNLOAD_BSS_PFC = 0x50, // PTP
|
|
CREATE_BSS_PFC = 0x51, // PTP
|
|
CREATE_BSS_PFC_ACK = 0x52, // PTP
|
|
CREATE_BSS_PFC_NACK = 0x53, // PTP
|
|
MODIFY_BSS_PFC = 0x54, // PTP
|
|
MODIFY_BSS_PFC_ACK = 0x55, // PTP
|
|
DELETE_BSS_PFC = 0x56, // PTP
|
|
DELETE_BSS_PFC_ACK = 0x57 // PTP
|
|
};
|
|
static const char *name(int val);
|
|
static const unsigned LookupBVCI(BSPDUType::type bstype);
|
|
};
|
|
std::ostream& operator<<(std::ostream& os, const BSPDUType::type val);
|
|
|
|
class NsIEIType {
|
|
// GSM08.18 sec10.3 NS protocol IEI Types.
|
|
// The NS protocol doesnt do much. It specifies a procedure
|
|
// to make sure the link is alive, to reset it after failure,
|
|
// and to turn the entire link on and off (block/unblock.)
|
|
public: enum type {
|
|
IEINsCause,
|
|
IEINsVCI,
|
|
IEINsPDU,
|
|
IEINsBVCI,
|
|
IEINsNSEI,
|
|
};
|
|
};
|
|
|
|
class NsCause {
|
|
public: enum type {
|
|
TransitNetworkFailure,
|
|
OAndMIntervention,
|
|
EquipmentFailure,
|
|
NSVCBlocked,
|
|
NSVCUnknown,
|
|
BVCIUnknown,
|
|
SemanticallyIncorrectPDU = 8,
|
|
PduNotCompatible = 10,
|
|
ProtocolError = 11,
|
|
InvalidEssentialIE = 12,
|
|
MissingEssentialIE = 13
|
|
};
|
|
};
|
|
|
|
class IEIType {
|
|
public:
|
|
// GSM08.18 sec11.3 table11.1: IEI Types
|
|
enum type {
|
|
AlignmentOctets = 0x00,
|
|
BmaxDefaultMS = 0x01,
|
|
BSSAreaIndication = 0x02,
|
|
BucketLeakRate = 0x03,
|
|
BVCI = 0x04,
|
|
BVCBucketSize = 0x05,
|
|
BVCMeasurement = 0x06,
|
|
Cause = 0x07,
|
|
CellIdentifier = 0x08,
|
|
ChannelNeeded = 0x09,
|
|
DRXParameters = 0x0a,
|
|
eMLPPPriority = 0x0b,
|
|
FlushAction = 0x0c,
|
|
IMSI = 0x0d,
|
|
LLCPDU = 0x0e,
|
|
LLCFramesDiscarded = 0x0f,
|
|
LocationArea = 0x10,
|
|
MobileId = 0x11,
|
|
MSBucketSize = 0x12,
|
|
MSRadioAccessCapability = 0x13,
|
|
OMCId = 0x14,
|
|
PDUInError = 0x15,
|
|
PDULifetime = 0x16,
|
|
Priority = 0x17,
|
|
QoSProfile = 0x18,
|
|
RadioCause = 0x19,
|
|
RACapUPDCause = 0x1a,
|
|
RouteingArea = 0x1b,
|
|
RDefaultMS = 0x1c,
|
|
SuspendReferenceNumber = 0x1d,
|
|
Tag = 0x1e,
|
|
TLLI = 0x1f,
|
|
TMSI = 0x20,
|
|
TraceReference = 0x21,
|
|
TraceType = 0x22,
|
|
TransactionId = 0x23,
|
|
TriggerId = 0x24,
|
|
NumberOfOctetsAffected = 0x25,
|
|
LSAIdentifierList = 0x26,
|
|
LSAInformation = 0x27,
|
|
PacketFlowIdentifier = 0x28,
|
|
PacketFlowTimer = 0x29,
|
|
AggregateBSSQoSProfile = 0x3a, // (ABQP)
|
|
FeatureBitmap = 0x3b,
|
|
BucketFullRatio = 0x3c,
|
|
ServiceUTRANCCO = 0x3d // (Cell Change Order)
|
|
};
|
|
static const char *name(int val);
|
|
|
|
};
|
|
std::ostream& operator<<(std::ostream& os, const IEIType::type val);
|
|
|
|
// Notes:
|
|
// BVC = BSSG Virtual Connection
|
|
// NS SDU = the BSSG data packet transmitted over NS.
|
|
|
|
// GSM08.16 sec 10.3.7: Network Service PDU Type
|
|
class NSPDUType {
|
|
public:
|
|
enum type {
|
|
NS_UNITDATA = 0,
|
|
NS_RESET = 2,
|
|
NS_RESET_ACK = 3,
|
|
NS_BLOCK = 4,
|
|
NS_BLOCK_ACK = 5,
|
|
NS_UNBLOCK = 6,
|
|
NS_UNBLOCK_ACK = 7,
|
|
NS_STATUS = 8,
|
|
NS_ALIVE = 10,
|
|
NS_ALIVE_ACK = 11
|
|
};
|
|
static const char *name(int val);
|
|
};
|
|
std::ostream& operator<<(std::ostream& os, const NSPDUType::type val);
|
|
|
|
// GSM08.16 sec 9.2.10
|
|
struct RN_PACKED NSUnitDataHeader {
|
|
ByteType mNSPDUType;
|
|
ByteType mUnused;
|
|
ByteType mBVCI[2];
|
|
};
|
|
|
|
class NSMsg : public ByteVector, public Utils::Text2Str
|
|
{
|
|
public:
|
|
// This is the NS header length only for NS_UNIT_DATA messages,
|
|
// which are the only ones we care about because they are the
|
|
// only ones that have BSSG and potentially user data in them.
|
|
static const unsigned UnitDataHeaderLen = sizeof(struct NSUnitDataHeader);
|
|
|
|
// wlen should include the NS header + BSSG header + data
|
|
NSMsg(ByteType *wdata, int wlen) // Make one from downlink data.
|
|
: ByteVector(wdata,wlen)
|
|
{ }
|
|
|
|
// wlen should include the NS header + BSSG header + data
|
|
NSMsg(int wlen) // Make one for uplink data.
|
|
: ByteVector(wlen + NSMsg::UnitDataHeaderLen) // But we will add it in anyway
|
|
{
|
|
// Zero out the NS header; the type will be filled in later.
|
|
fill(0,0,NSMsg::UnitDataHeaderLen);
|
|
}
|
|
|
|
// Make a new message from some other, taking over the ByteVector.
|
|
// Used to change the type of a BSSG message.
|
|
NSMsg(NSMsg *src) : ByteVector(*src) {
|
|
//assert(src->isOwner());
|
|
//move(*src); // Grab the memory from src.
|
|
//assert(!src->isOwner()); no longer true with refcnts.
|
|
}
|
|
|
|
// Passify the brain-dead compiler:
|
|
#define NSMsgConstructors(type1,type2) \
|
|
type1(ByteType *data, int len) : type2(data,len) {} \
|
|
type1(int wlen) : type2(wlen) {} \
|
|
type1(NSMsg *src) : type2(src) {}
|
|
|
|
// Fields in the 4 byte NS Header:
|
|
void setNSPDUType(NSPDUType::type nstype) { setByte(0,nstype); }
|
|
NSPDUType::type getNSPDUType() const { return (NSPDUType::type) getByte(0); }
|
|
|
|
void textNSHeader(std::ostream&os) const;
|
|
virtual void text(std::ostream&os) const;
|
|
std::string str() const { return this->Text2Str::str(); } // Disambigute
|
|
};
|
|
|
|
class BSSGMsg : public NSMsg {
|
|
public:
|
|
NSMsgConstructors(BSSGMsg,NSMsg)
|
|
// Common fields in the BSSG Header:
|
|
void setPDUType(BSPDUType::type type) { setByte(NSMsg::UnitDataHeaderLen,(ByteType)type); }
|
|
BSPDUType::type getPDUType() const { return (BSPDUType::type) getByte(NSMsg::UnitDataHeaderLen); }
|
|
virtual void text(std::ostream &os) const;
|
|
virtual std::string briefDescription() const;
|
|
};
|
|
|
|
class BSSGUplinkMsgElt {
|
|
public:
|
|
//TODO: virtual void text(std::ostream&) const;
|
|
virtual void parseElement(const char *src, size_t &rp);
|
|
};
|
|
class BSSGDownlinkMsgElt {
|
|
public:
|
|
//TODO: virtual void text(std::ostream&) const;
|
|
};
|
|
|
|
// Note that the ByteVector in NSMsg is allocated, and all the other ones in downlink messages
|
|
// are segments referring to this one.
|
|
//class BSSGDownlinkMsg : public NSMsg, public BSSGMsg
|
|
class BSSGDownlinkMsg : public BSSGMsg
|
|
{
|
|
public:
|
|
NSMsgConstructors(BSSGDownlinkMsg,BSSGMsg)
|
|
|
|
virtual void text(std::ostream &os) const { BSSGMsg::text(os); }
|
|
};
|
|
|
|
class BSSGUplinkMsg : public BSSGMsg
|
|
{
|
|
public:
|
|
NSMsgConstructors(BSSGUplinkMsg,BSSGMsg)
|
|
|
|
virtual void text(std::ostream &os) const { BSSGMsg::text(os); }
|
|
};
|
|
|
|
|
|
// This is the QoS Profile in the header, when not including the 2 byte IEI prefix.
|
|
// GSM08.18 sec 11.3.28
|
|
struct QoSProfile {
|
|
// Coded as value part of Bucket Leak Rate 'R' from sec 11.3.4
|
|
// And I quote:
|
|
// The R field is the binary encoding of the rate information expressed in 100 bits/sec
|
|
// increments starting from 0 x 100 bits/sec until 65535 * 100 bits/sec (6Mbps)
|
|
// Note a) Bit Rate 0 means "Best Effort".
|
|
unsigned mPeakBitRate:16;
|
|
|
|
// These are the bits of byte 3.
|
|
unsigned mSpare:2;
|
|
unsigned mCR:1;
|
|
unsigned mT:1;
|
|
unsigned mA:1;
|
|
unsigned mPrecedence:3;
|
|
|
|
ByteType getB3() { return (mCR<<5)|(mT<<4)|(mA<<3)|mPrecedence; }
|
|
void setB3(ByteType bits) {
|
|
mPrecedence = bits & 0x7;
|
|
mA = (bits>>3)&1;
|
|
mT = (bits>>4)&1;
|
|
mCR = (bits>>5)&1;
|
|
}
|
|
|
|
QoSProfile() { // Create a default QoSProfile
|
|
mPeakBitRate = 0;
|
|
setB3(0);
|
|
}
|
|
|
|
// Get from the ByteVector, which is in network order:
|
|
void qosRead(ByteVector &src, size_t &wp) {
|
|
mPeakBitRate = src.getUInt16(wp); wp+=2;
|
|
ByteType byte3 = src.getByte(wp++);
|
|
setB3(byte3);
|
|
}
|
|
|
|
// Write to ByteVector in network order.
|
|
void qosAppend(ByteVector *dest) {
|
|
dest->appendUInt16(mPeakBitRate);
|
|
dest->appendByte(getB3());
|
|
}
|
|
};
|
|
|
|
|
|
// GSM 08.18 sec 10.2.1 From SGSN to BSS.
|
|
class BSSGMsgDLUnitData : public BSSGDownlinkMsg
|
|
{
|
|
public:
|
|
// Mandatory elements:
|
|
UInt32_z mbdTLLI;
|
|
UInt16_z mbdPDULifetime;
|
|
QoSProfile mbdQoS; // 3 bytes
|
|
Bool_z mbdHaveOldTLLI;
|
|
UInt32_z mbdOldTLLI;
|
|
// Optional elements:
|
|
//RLCMsgEltMSRACapabilityValuePart mbdRACap;
|
|
ByteVector mbdRACap;
|
|
ByteVector mbdIMSI;
|
|
ByteVector mbdPDU;
|
|
|
|
BSSGMsgDLUnitData(BSSGDownlinkMsg*src) : BSSGDownlinkMsg(src) {
|
|
size_t wp = NSMsg::UnitDataHeaderLen;
|
|
parseDLUnitDataBody(*this,wp);
|
|
}
|
|
|
|
// Parse body, excluding the NS header.
|
|
void parseDLUnitDataBody(ByteVector &src, size_t &wp);
|
|
void text(std::ostream &os) const;
|
|
std::string briefDescription() const;
|
|
};
|
|
|
|
BSSGDownlinkMsg* BSSGDownlinkMessageParse(ByteVector&src);
|
|
|
|
// Routing Area Identification: GSM04.08 sec 10.5.5.15.
|
|
// 6 bytes. This is just a magic cookie as far as we are concerned.
|
|
struct RN_PACKED RoutingAreaID {
|
|
// First three bytes identify MCC Mobile Country Code and MNC Mobile Network Code.
|
|
// Weird encoding; see spec.
|
|
ByteType mMCCDigits12; // MCC Digit2, MCC Digit1.
|
|
ByteType mHighDigits; // MNC Digit3, MCC Digit3.
|
|
ByteType mMNCDigits12; // MNC Digit2, MNC Digit1.
|
|
unsigned mLAC:16; // Location Area Code.
|
|
unsigned mRAC:8; // Routing Area Code.
|
|
RoutingAreaID(unsigned MCC, unsigned MNC, unsigned LAC, unsigned RAC) {
|
|
// TODO, but maybe no one cares.
|
|
}
|
|
};
|
|
|
|
|
|
// Cell Identifier: GSM 08.18 sec 11.2.9
|
|
struct RN_PACKED CellIdentifier {
|
|
// Routing Area Identification: GSM 04.08 sec 10.5.5.15.
|
|
uint64_t RoutingAreaIdentification:48;
|
|
// Cell Identity: GSM04.08 sec 10.5.1.1
|
|
// It is just a two byte int whose value determined by the administrator.
|
|
unsigned CellIdentity:16;
|
|
};
|
|
|
|
struct RN_PACKED CellIdentifierIEI {
|
|
ByteType iei;
|
|
ByteType length;
|
|
ByteType RoutingAreaID[6];
|
|
ByteType CellIdentity[2];
|
|
};
|
|
|
|
// This is the specific UlUnitData format that we use.
|
|
struct RN_PACKED BSSGMsgULUnitDataHeader {
|
|
NSUnitDataHeader mbuNS;
|
|
ByteType mbuPDUType;
|
|
ByteType mbuTLLI[4];
|
|
ByteType mbuQoS[3];
|
|
ByteType mbuCellIdIEI[10];
|
|
ByteType mbuAlignmentIEI[2]; // spacer required to make size div by 4.
|
|
ByteType mLLCIEIType;
|
|
ByteType mLLCPDULength[2];
|
|
// PDU data starts after this..
|
|
};
|
|
|
|
//class BSSGMsgBVCReset {
|
|
// NSUnitDataHeader mbuNS;
|
|
//};
|
|
|
|
// GSM 08.18 sec 10.2.2 Packet Data from BSS to SGSN.
|
|
// It could be user data or a GMM or other message from a higher
|
|
// layer in the MS to the SGSN.
|
|
// There are several optional IEIs we do not include.
|
|
// Alignment octets are necessary so the start of the PDU IEI
|
|
// starts on a 32bit boundary, which is totally dopey because the PDU
|
|
// itself is unaligned inside the PDU IEI. Whatever.
|
|
// This structure is write-only; the internal fields are in network order and
|
|
// we dont need to read them, so we dont.
|
|
// The RLCEngine is the primary producer of these things, and always allocates
|
|
// a maximum size (1502 bytes plus headers) so it can just append the data in.
|
|
// The lifetime of these things is quite short; they live in the BSSG outgoing
|
|
// queue until the service thread sends them to the SGSN.
|
|
class BSSGMsgULUnitData : public BSSGUplinkMsg
|
|
{
|
|
public:
|
|
static const unsigned HeaderLength = sizeof(BSSGMsgULUnitDataHeader);
|
|
int mTBFId; // For debugging, the associated tbf that processed us.
|
|
|
|
BSSGMsgULUnitData(unsigned wLen, uint32_t wTLLI);
|
|
|
|
// Return the pointer to the header within the ByteVector (its just 0)
|
|
// what a horrible language.
|
|
BSSGMsgULUnitDataHeader *getHeader() { return (BSSGMsgULUnitDataHeader*) begin(); }
|
|
BSSGMsgULUnitDataHeader *getHeader() const { return const_cast<BSSGMsgULUnitData*>(this)->getHeader(); }
|
|
|
|
//unused: void setBVCI(int wBVCI) { setUInt16(2,wBVCI); }
|
|
unsigned getBVCI() const { return getUInt16(2); }
|
|
//unused: void setTLLI(int wTLLI) { sethtonl(getHeader()->mbuTLLI,wTLLI); }
|
|
int getTLLI() const { return getntohl(getHeader()->mbuTLLI); }
|
|
|
|
ByteVector getPayload() {
|
|
// Now the return value also owns memory.
|
|
//return tail(HeaderLength);
|
|
ByteVector result = *this; // Increments refcnt.
|
|
result.trimLeft(HeaderLength);
|
|
return result;
|
|
}
|
|
|
|
// We set the length after assembling the complete pdu.
|
|
unsigned mLengthPosition; // Where the PDU Length goes in the ByteVector.
|
|
void setLength();
|
|
|
|
void text(std::ostream&os) const;
|
|
};
|
|
|
|
// Make a short BSSG Protocol signaling message.
|
|
BSSGUplinkMsg *BVCFactory(BSPDUType::type bssgtype, int arg1=0);
|
|
// Make a short NS Protocol message.
|
|
NSMsg *NsFactory(NSPDUType::type nstype, int cause=0);
|
|
|
|
//class BSSGMsgULUnitData : public BSSGUplinkMsg {
|
|
// unsigned mbPDUType:8;
|
|
// unsigned mTLLI:32;
|
|
// QoSProfile mQoS;
|
|
// CellIdentifierIEI mCellIdentifier; // 10 bytes
|
|
//};
|
|
|
|
};
|
|
#endif
|