/**@file @brief GSM Mobility Management messages, from GSM 04.08 9.2. */ /* * Copyright 2008, 2009, 2010 Free Software Foundation, Inc. * * This software is distributed under the terms of the GNU Affero Public License. * See the COPYING file in the main directory for details. * * This use of this software may be subject to additional restrictions. * See the LEGAL file in the main directory for details. This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 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. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ #include #include "GSML3CommonElements.h" #include "GSML3MMMessages.h" #include using namespace std; using namespace GSM; ostream& GSM::operator<<(ostream& os, L3MMMessage::MessageType val) { switch (val) { case L3MMMessage::IMSIDetachIndication: os << "IMSI Detach Indication"; break; case L3MMMessage::CMServiceRequest: os << "CM Service Request"; break; case L3MMMessage::CMServiceAccept: os << "CM Service Accept"; break; case L3MMMessage::CMServiceReject: os << "CM Service Reject"; break; case L3MMMessage::CMServiceAbort: os << "CM Service Abort"; break; case L3MMMessage::CMReestablishmentRequest: os << "CM Re-establishment Request"; break; case L3MMMessage::IdentityResponse: os << "Identity Response"; break; case L3MMMessage::IdentityRequest: os << "Identity Request"; break; case L3MMMessage::MMInformation: os << "MM Information"; break; case L3MMMessage::LocationUpdatingAccept: os << "Location Updating Accept"; break; case L3MMMessage::LocationUpdatingReject: os << "Location Updating Reject"; break; case L3MMMessage::LocationUpdatingRequest: os << "Location Updating Request"; break; case L3MMMessage::MMStatus: os << "MM Status"; break; default: os << hex << "0x" << (int)val << dec; } return os; } L3MMMessage* GSM::L3MMFactory(L3MMMessage::MessageType MTI) { switch (MTI) { case L3MMMessage::LocationUpdatingRequest: return new L3LocationUpdatingRequest; case L3MMMessage::IMSIDetachIndication: return new L3IMSIDetachIndication; case L3MMMessage::CMServiceRequest: return new L3CMServiceRequest; // Since we don't support re-establishment, don't bother parsing this. //case L3MMMessage::CMReestablishmentRequest: return new L3CMReestablishmentRequest; case L3MMMessage::MMStatus: return new L3MMStatus; case L3MMMessage::IdentityResponse: return new L3IdentityResponse; default: LOG(WARN) << "no L3 MM factory support for message " << MTI; return NULL; } } L3MMMessage * GSM::parseL3MM(const L3Frame& source) { L3MMMessage::MessageType MTI = (L3MMMessage::MessageType)(0xbf & source.MTI()); LOG(DEBUG) << "parseL3MM MTI=" << MTI; L3MMMessage *retVal = L3MMFactory(MTI); if (retVal==NULL) return NULL; retVal->parse(source); return retVal; } void L3MMMessage::text(ostream& os) const { os << "MM " << (MessageType) MTI() << " "; } void L3LocationUpdatingRequest::parseBody( const L3Frame &src, size_t &rp ) { // skip updating type rp += 4; // skip ciphering ket sequence number rp += 4; mLAI.parseV(src,rp); mClassmark.parseV(src,rp); mMobileIdentity.parseLV(src, rp); } void L3LocationUpdatingRequest::text(ostream& os) const { L3MMMessage::text(os); os << "LAI=("<"; } size_t L3MMInformation::bodyLength() const { size_t len=0; if (mShortName.lengthV()>1) len += mShortName.lengthTLV(); len += mTime.lengthTV(); return len; } void L3MMInformation::writeBody(L3Frame &dest, size_t &wp) const { if (mShortName.lengthV()>1) mShortName.writeTLV(0x45,dest,wp); mTime.writeTV(0x47,dest,wp); } void L3MMInformation::text(ostream& os) const { L3MMMessage::text(os); os << "short name=(" << mShortName << ")"; os << " time=(" << mTime << ")"; } void L3IdentityRequest::writeBody(L3Frame& dest, size_t &wp) const { dest.writeField(wp,0,4); // spare half octet dest.writeField(wp,mType,4); } void L3IdentityRequest::text(ostream& os) const { L3MMMessage::text(os); os << "type=" << mType; } void L3IdentityResponse::parseBody(const L3Frame& src, size_t& rp) { mMobileID.parseLV(src,rp); } void L3IdentityResponse::text(ostream& os) const { L3MMMessage::text(os); os << "mobile id=" << mMobileID; } // vim: ts=4 sw=4