提交 bed1e350 编写于 作者: C calincerchez

finished s1ap

finished subscriber
上级 c8703846
......@@ -14,7 +14,7 @@ Directors for 4Gsim:
util/ general utility classes
asn/ utility classes for ASN.1 encoding/decoding
headerserializers/ serialize/parse methods for LTE protocols
4g/ utility classes for 4G
subscriber/ utility classes for subscriber
......
......@@ -115,7 +115,7 @@ public:
/*
* Method for finding a Diameter connection with a specific message based
* on the association id specified in the control info. The method
* returns the session if it is found, or NULL otherwise.
* returns the connection if it is found, or NULL otherwise.
*/
DiameterConnection *findConnection(cMessage *msg);
......
......@@ -156,7 +156,7 @@ public:
void processTimer(cMessage *timer);
/*
* Utility methods for state processing.
* Utility methods for state processing and printing.
*/
void performStateTransition(PeerEvent &event, DiameterMessage *msg);
void stateEntered();
......
......@@ -96,9 +96,8 @@ public:
DiameterSession *findSession(std::string id);
/*
* Method for deleting Diameter sessions. The method calls first
* the destructor for each session between start and end position
* and removes them afterwards.
* Method for deleting S1AP connections. The method calls first the destructor
* for each connection between start and end position and removes them afterwards.
*/
void erase(unsigned start, unsigned end);
......
//
// Copyright (C) 2012 Calin Cerchez
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
......
......@@ -38,10 +38,6 @@ S1APConnection::~S1APConnection() {
delete socket;
}
void S1APConnection::processMessage(cMessage *msg) {
socket->processMessage(PK(msg));
}
void S1APConnection::socketEstablished(int32 connId, void *yourPtr, uint64 buffer) {
if (module->getType() == CONNECTOR) {
S1APConnectionEvent event = SCTPEstablished;
......@@ -177,6 +173,7 @@ void S1APConnection::performStateTransition(S1APConnectionEvent &event, OpenType
}
default:
EV << "S1AP: Received unexpected event\n";
break;
}
break;
case S1AP_PENDING:
......@@ -199,10 +196,12 @@ void S1APConnection::performStateTransition(S1APConnectionEvent &event, OpenType
break;
default:
EV << "S1AP: Received unexpected event\n";
break;
}
break;
default:
EV << "S1AP: Unknown state\n";
break;
}
if (oldState != fsm->getState())
......@@ -696,57 +695,6 @@ ProtocolIeField *S1APConnection::processUplinkNasTransport(OpenType *val) {
return NULL;
}
//std::string S1APConnection::info() const {
//
// std::stringstream out;
//
// out << "conn nr.: " << socket->getConnectionId() << endl;
// if (plmnId != NULL)
// out << "plmnId: " << LTEUtils().toASCIIString(plmnId, PLMNID_CODED_SIZE) << endl;
// if (cellId != NULL)
// out << "cellId: " << LTEUtils().toASCIIString(cellId, CELLID_CODED_SIZE) << endl;
// if (suppTas.size() > 0) {
// out << "suppTas: {\n";
// for (unsigned j = 0; j < suppTas.size(); j++) {
// out << "\tsuppTa nr. " << j << ": {\n";
// out << "\t\ttac: " << LTEUtils().toASCIIString((suppTas.at(j))->tac, TAC_CODED_SIZE) << endl;
// out << "\t\tbPlmns: {\n";
// std::vector<char*>bplmns = (suppTas.at(j))->bplmns;
// for (unsigned k = 0; k < bplmns.size(); k++) {
// out << "\t\t\tbPlmn nr. " << k << ": " << LTEUtils().toASCIIString(bplmns.at(k), PLMNID_CODED_SIZE) << endl;
// }
// out << "\t\t}\n\t}\n";
// }
// out << "}\n";
// }
// if (servGummeis.size() > 0) {
// out << "servGummeis: {\n";
// for (unsigned j = 0; j < servGummeis.size(); j++) {
// out << "\tservGummei nr. " << j << ": {\n";
// out << "\t\tservPlmns: {\n";
// std::vector<char*>servPlmns = (servGummeis.at(j))->servPlmns;
// for (unsigned k = 0; k < servPlmns.size(); k++) {
// out << "\t\t\tservPlmn nr. " << k << ": " << LTEUtils().toASCIIString(servPlmns.at(k), PLMNID_CODED_SIZE) << endl;
// }
// out << "\t\t}\n";
// out << "\t\tservGrIds: {\n";
// std::vector<char*>servGrIds = (servGummeis.at(j))->servGrIds;
// for (unsigned k = 0; k < servGrIds.size(); k++) {
// out << "\t\t\tservGrId nr. " << k << ": " << LTEUtils().toASCIIString(servGrIds.at(k), 2) << endl;
// }
// out << "\t\t}\n";
// out << "\t\tservMmecs: {\n";
// std::vector<char*>servMmecs = (servGummeis.at(j))->servMmecs;
// for (unsigned k = 0; k < servMmecs.size(); k++) {
// out << "\t\t\tservMmec nr. " << k << ": " << LTEUtils().toASCIIString(servMmecs.at(k), 1) << endl;
// }
// out << "\t\t}\n\t}\n";
// }
// out << "}\n";
// }
// return out.str();
//}
const char *S1APConnection::stateName(int state) {
#define CASE(x) case x: s=#x; break
const char *s = "unknown";
......@@ -771,3 +719,51 @@ const char *S1APConnection::eventName(int event) {
return s;
#undef CASE
}
S1APConnectionTable::S1APConnectionTable() {
// TODO Auto-generated constructor stub
}
S1APConnectionTable::~S1APConnectionTable() {
// TODO Auto-generated destructor stub
erase(0, conns.size());
}
S1APConnection *S1APConnectionTable::findConnectionForId(int connId) {
for (unsigned i = 0; i < conns.size(); i++) {
S1APConnection *conn = conns[i];
if (conn->getConnectionId() == connId)
return conn;
}
return NULL;
}
S1APConnection *S1APConnectionTable::findConnectionForCellId(char *cellId) {
if (cellId == NULL)
return NULL;
for (unsigned i = 0; i < conns.size(); i++) {
S1APConnection *conn = conns[i];
if (!strncmp(conn->getCellId(), cellId, CELLID_CODED_SIZE))
return conn;
}
return NULL;
}
S1APConnection *S1APConnectionTable::findConnectionForState(int state) {
for (unsigned i = 0; i < conns.size(); i++) {
S1APConnection *conn = conns[i];
if (conn->getState() == state)
return conn;
}
return NULL;
}
void S1APConnectionTable::erase(unsigned start, unsigned end) {
S1APConnections::iterator first = conns.begin() + start;
S1APConnections::iterator last = conns.begin() + end;
S1APConnections::iterator i = first;
for (;i != last; ++i)
delete *i;
conns.erase(first, last);
}
......@@ -49,27 +49,28 @@ class S1AP;
* in the specification and it helps setting up a connection between the
* entities.
*
* +-------------------+
| S1AP_DISCONNECTED |
+-------------------+
^ |
| |
S1APRcvSetupFailure | | SCTPEstablished
/InvalidResponse | |
| |
| v
+--------------+
| S1AP_PENDING |
+--------------+
| |
| |
| | S1APRcvSetupFailure
| | /CorrectResponse
| |
| v
+----------------+
| S1AP_CONNECTED |-------------------+
+----------------+
* +-------------------+
* | S1AP_DISCONNECTED |-----------+
* +-------------------+ |
* ^ | |
* | | |
* S1APRcvSetupFailure | | SCTPEstablished |
* /InvalidResponse | | |
* | | |
* | v |
* +--------------+ | S1APRcvSetupRequest
* | S1AP_PENDING | | /CorrectRequest
* +--------------+ |
* | |
* | |
* S1APRcvSetupResponse | |
* /CorrectResponse | |
* | |
* | |
* v |
* +----------------+ |
* | S1AP_CONNECTED |<------------+
* +----------------+
*/
class S1APConnection : public SCTPSocket::CallbackInterface {
private:
......@@ -98,49 +99,119 @@ private:
void socketFailure(int32 connId, void *yourPtr, int32 code);
void socketStatusArrived(int32 connId, void *yourPtr, SCTPStatusInfo *status) { delete status; }
/*
* Methods for sending and processing S1AP connection setup messages.
* These methods will be used internally between two S1AP connections.
*/
void sendS1SetupRequest();
ProtocolIeField *processS1SetupRequest(OpenType *val);
void sendS1SetupResponse();
ProtocolIeField *processS1SetupResponse(OpenType *val);
void sendS1SetupFailure(ProtocolIeField *cause);
const char *stateName(int state);
const char *eventName(int event);
public:
S1APConnection(S1AP *module);
virtual ~S1APConnection();
void processMessage(cMessage *msg);
void setSocket(SCTPSocket *socket) { this->socket = socket; }
void setAddresses(AddressVector addresses) { this->addresses = addresses; }
void setPort(int port) { this->port = port; }
int getConnectionId() { return socket->getConnectionId(); }
int getState() { return fsm->getState(); }
void connect() { socket->connectx(addresses, port); }
/*
* Method for sending S1AP messages. It creates and sends a SCTPSimpleMessage
* after encoding S1APPdu according to rules described in the ASN.1
* implementation and S1AP messages description.
*/
void send(S1APPdu *msg);
void setPlmnId(char *plmnId) { this->plmnId = plmnId; }
void setCellId(char *cellId) { this->cellId = cellId; }
void setSupportedTas(std::vector<SupportedTaItem> suppTas) { this->suppTas = suppTas; }
void setServedGummeis(std::vector<ServedGummeiItem> servGummeis) { this->servGummeis =servGummeis; }
char *getCellId() { return cellId; }
char *getPlmnId() { return plmnId; }
std::vector<SupportedTaItem> getSupportedTas() { return suppTas; }
/*
* Methods for sending and processing S1AP messages that are not
* related to S1AP connection management.
*/
void sendInitialUeMessage(Subscriber *sub, NasPdu *nasPdu);
ProtocolIeField *processInitialUeMessage(OpenType *val);
void sendInitialContextSetupRequest(Subscriber *sub, NasPdu *nasPdu);
ProtocolIeField *processInitialContextSetupRequest(OpenType *va);
void sendInitialContextSetupResponse(Subscriber *sub);
ProtocolIeField *processInitialContextSetupResponse(OpenType *val);
void sendDownlinkNasTransport(Subscriber *sub, NasPdu *pdu);
ProtocolIeField *processDownlinkNasTransport(OpenType *val);
void sendUplinkNasTransport(Subscriber *sub, NasPdu *nasPdu);
ProtocolIeField *processUplinkNasTransport(OpenType *val);
/*
* Utility methods for state processing and printing.
*/
const char *stateName(int state);
const char *eventName(int event);
void performStateTransition(S1APConnectionEvent &event, OpenType *val = NULL);
void sendInitialUeMessage(Subscriber *sub, NasPdu *nasPdu);
ProtocolIeField *processInitialUeMessage(OpenType *val);
void sendInitialContextSetupRequest(Subscriber *sub, NasPdu *nasPdu);
ProtocolIeField *processInitialContextSetupRequest(OpenType *va);
void sendInitialContextSetupResponse(Subscriber *sub);
ProtocolIeField *processInitialContextSetupResponse(OpenType *val);
void sendDownlinkNasTransport(Subscriber *sub, NasPdu *pdu);
ProtocolIeField *processDownlinkNasTransport(OpenType *val);
void sendUplinkNasTransport(Subscriber *sub, NasPdu *nasPdu);
ProtocolIeField *processUplinkNasTransport(OpenType *val);
/*
* Setter methods.
*/
void setPlmnId(char *plmnId) { this->plmnId = plmnId; }
void setCellId(char *cellId) { this->cellId = cellId; }
void setSupportedTas(std::vector<SupportedTaItem> suppTas) { this->suppTas = suppTas; }
void setServedGummeis(std::vector<ServedGummeiItem> servGummeis) { this->servGummeis =servGummeis; }
void setSocket(SCTPSocket *socket) { this->socket = socket; }
void setAddresses(AddressVector addresses) { this->addresses = addresses; }
void setPort(int port) { this->port = port; }
/*
* Getter methods.
*/
int getConnectionId() { return socket->getConnectionId(); }
int getState() { return fsm->getState(); }
char *getCellId() { return cellId; }
char *getPlmnId() { return plmnId; }
std::vector<SupportedTaItem> getSupportedTas() { return suppTas; }
/*
* Wrapper methods.
*/
void connect() { socket->connectx(addresses, port); }
void processMessage(cMessage *msg) { socket->processMessage(PK(msg)); }
};
/*
* Class for S1AP connection table. This table will hold all the connections
* owned by the S1AP protocol model implementation.
*/
class S1APConnectionTable {
private:
typedef std::vector<S1APConnection*> S1APConnections;
S1APConnections conns;
public:
S1APConnectionTable();
virtual ~S1APConnectionTable();
/*
* Method for finding a S1AP connection for a given connection id.
* The method returns the connection, if it is found, or NULL otherwise.
*/
S1APConnection *findConnectionForId(int connId);
/*
* Method for finding a S1AP connection for a given cell id.
* The method returns the connection, if it is found, or NULL otherwise.
*/
S1APConnection *findConnectionForCellId(char *cellId);
/*
* Method for finding a S1AP connection for a given state.
* The method returns the connection, if it is found, or NULL otherwise.
*/
S1APConnection *findConnectionForState(int state);
/*
* Method for deleting a S1AP connection. The method calls first
* the destructor for the connection and removes it afterwards.
*/
void erase(unsigned start, unsigned end);
/*
* Wrapper methods.
*/
unsigned int size() {return conns.size();}
void push_back(S1APConnection *conn) { conns.push_back(conn); }
S1APConnection *at(unsigned i) { return conns.at(i); }
};
......
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see http://www.gnu.org/licenses/.
//
#include "S1APConnectionTable.h"
#include "LTEUtils.h"
#include "S1APUtils.h"
S1APConnectionTable::S1APConnectionTable() {
// TODO Auto-generated constructor stub
}
S1APConnectionTable::~S1APConnectionTable() {
// TODO Auto-generated destructor stub
erase(0, conns.size());
}
S1APConnection *S1APConnectionTable::findConnectionForId(int connId) {
for (unsigned i = 0; i < conns.size(); i++) {
S1APConnection *conn = conns[i];
if (conn->getConnectionId() == connId)
return conn;
}
return NULL;
}
S1APConnection *S1APConnectionTable::findConnectionForCellId(char *cellId) {
if (cellId == NULL)
return NULL;
for (unsigned i = 0; i < conns.size(); i++) {
S1APConnection *conn = conns[i];
if (!strncmp(conn->getCellId(), cellId, CELLID_CODED_SIZE))
return conn;
}
return NULL;
}
S1APConnection *S1APConnectionTable::findConnectionForState(int state) {
for (unsigned i = 0; i < conns.size(); i++) {
S1APConnection *conn = conns[i];
if (conn->getState() == state)
return conn;
}
return NULL;
}
void S1APConnectionTable::erase(unsigned start, unsigned end) {
ConnTable::iterator first = conns.begin() + start;
ConnTable::iterator last = conns.begin() + end;
ConnTable::iterator i = first;
for (;i != last; ++i)
delete *i;
conns.erase(first, last);
}
//void S1APConnectionTable::printTable() {
// EV << "==================================\n"
// << "S1AP Connection Table:{\n";
// for (unsigned i = 0; i < conns.size(); i++) {
// S1APConnection *conn = conns.at(i);
// EV << " Connection nr. " << conn->getConnectionId() << ": {\n";
// EV << " PLMN id: "; LTEUtils().printBytes(conn->getPlmnId(), PLMNID_CODED_SIZE);
// EV << " Cell Id: "; LTEUtils().printBytes(conn->getCellId(), CELLID_CODED_SIZE);
// EV << " SupportedTas: {\n";
// std::vector<SupportedTaItem*>suppTas = conn->getSupportedTas();
// for (unsigned j = 0; j < suppTas.size(); j++) {
// EV << " SupportedTa nr. " << j << ": {\n";
// EV << " TAC: "; LTEUtils().printBytes((suppTas.at(j))->tac, TAC_CODED_SIZE);
// EV << " Broadcast PLMNs: {\n";
// std::vector<char*>bplmns = (suppTas.at(j))->bplmns;
// for (unsigned k = 0; k < bplmns.size(); k++) {
// EV << " Broadcast PLMN nr. " << k << ": "; LTEUtils().printBytes(bplmns.at(k), PLMNID_CODED_SIZE);
// }
// EV << " }\n }\n";
// }
// EV << " }\n";
// }
// EV << " }\n}\n";
// EV << "==================================\n";
//
//}
//
// Copyright (C) 2012 Calin Cerchez
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
......
//
// Copyright (C) 2012 Calin Cerchez
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
......@@ -22,6 +24,12 @@
#define MMECODE_CODED_SIZE 2
#define GROUPID_CODED_SIZE 4
/*
* Utility class for storing information about SupportedTa's. Each item will
* be read, during the initialization phase of the module, from the configuration
* file and will be stored in a vector in the module class. This information
* is used mainly during the establishment of S1AP connections.
*/
class SupportedTaItem {
public:
char *tac;
......@@ -33,6 +41,12 @@ public:
SupportedTaItem& operator=(const SupportedTaItem& other);
};
/*
* Utility class for storing information about ServedGummei's. Each item will
* be read, during the initialization phase of the module, from the configuration
* file and will be stored in a vector in the module class. This information
* is used mainly during the establishment of S1AP connections.
*/
class ServedGummeiItem {
public:
std::vector<char*> servPlmns;
......
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see http://www.gnu.org/licenses/.
//
#ifndef SUBSCRIBERTABLE_H_
#define SUBSCRIBERTABLE_H_
#include "Subscriber.h"
#include "NotificationBoard.h"
#define INACTIVE_TIMER_TIMEOUT 10
class SubscriberTable : public cSimpleModule, public INotifiable {
private:
unsigned enbIds;
unsigned mmeIds;
cMessage *inactiveTimer;
NotificationBoard *nb;
typedef std::vector<Subscriber*> Subscribers;
Subscribers subs;
void loadPDNConnectionsFromXML(const cXMLElement& subElem, Subscriber *sub);
void loadSubscribersFromXML(const cXMLElement& config);
virtual void receiveChangeNotification(int category, const cPolymorphic *details) {}
public:
SubscriberTable();
virtual ~SubscriberTable();
virtual void initialize(int stage);
virtual void handleMessage(cMessage *msg);
Subscriber *findSubscriberForId(unsigned enbId, unsigned mmeId);
Subscriber *findSubscriberForChannel(int channelNr);
Subscriber *findSubscriberForIMSI(char *imsi);
Subscriber *findSubscriberForSeqNr(unsigned seqNr);
Subscriber *at(unsigned it) { return subs.at(it); }
void push_back(Subscriber *sub) { subs.push_back(sub); }
void erase(unsigned it);
void erase(unsigned start, unsigned end);
unsigned size() {return subs.size();}
unsigned genEnbId() { return ++enbIds; }
unsigned genMmeId() { return ++mmeIds; }
// void notify(int category, const cPolymorphic *details) { nb->fireChangeNotification(category, details); }
};
#endif /* SUBSCRIBERTABLE_H_ */
/*
* SubscriberTableAccess.h
*
* Created on: Mar 5, 2012
* Author: root
*/
#ifndef SUBSCRIBERTABLEACCESS_H_
#define SUBSCRIBERTABLEACCESS_H_
#include <omnetpp.h>
#include "ModuleAccess.h"
#include "SubscriberTable.h"
/**
* Gives access to the SubsciberTable.
*/
class SubscriberTableAccess : public ModuleAccess<SubscriberTable>
{
public:
SubscriberTableAccess() : ModuleAccess<SubscriberTable>("subscriberTable") {}
};
#endif /* SUBSCRIBERTABLEACCESS_H_ */
//
// Copyright (C) 2012 Calin Cerchez
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
......@@ -82,15 +84,6 @@ const char *Subscriber::statusName() const {
#undef CASE
}
//BearerContext *Subscriber::findBearerContext(unsigned char id) {
// for (unsigned i = 0; i < conns.size(); i++) {
// BearerContext *bearerCtxt = conns[i]->findBearerContext(id);
// if (bearerCtxt != NULL)
// return bearerCtxt;
// }
// return NULL;
//}
void Subscriber::initEntities(unsigned char appType) {
ESMEntity *esm = new ESMEntity(appType);
EMMEntity *emm = new EMMEntity(appType);
......@@ -106,26 +99,3 @@ unsigned Subscriber::popSeqNr() {
return seqNr;
}
//PDNConnection *Subscriber::findPDNConnection(std::string apn)
//{
// PDNConnections::iterator i = conns.find(apn);
// ASSERT(i == conns.end() || i->first == i->second->getAPN());
// return (i == conns.end()) ? NULL : i->second;
//}
//
//void Subscriber::addPDNConnection(PDNConnection *conn)
//{
// ASSERT(conns.find(conn->getAPN()) == conns.end());
// conns[conn->getAPN()] = conn;
//
// //printSocketMap();
//}
//
//PDNConnection *Subscriber::removePDNConnection(PDNConnection *conn)
//{
// PDNConnections::iterator i = conns.find(conn->getAPN());
// if (i != conns.end())
// conns.erase(i);
//// printConnectionMap();
// return conn;
//}
//
// Copyright (C) 2012 Calin Cerchez
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
......@@ -33,30 +35,89 @@ enum SubscriberGTPProcedure {
EUTRANInitAttachRes = 3,
};
/*
* Class that describes a 4G subscriber.
*
* The subscriber object stores information about the channel number for the
* particular UE. This channel number will be used for LTE radio model.
*
* From the information regarding S1AP protocol, the most important are eNB id
* and MME id, based on them the subscriber will be identified in eNB and MME
* subscriber tables. Other parameters serve mainly for message creation purposes.
* More info about S1AP protocol implementation can be found in the source files
* of s1ap directory.
*
* S11 tunnel endpoint is the endpoint for the GTP control tunnel in one network
* entity for this subscriber. All GTP control messages between MME and S-GW will
* be exchanged through this tunnel. More info about GTP protocol and tunnels can be
* found in the source files of gtp directory.
*
* NAS protocol from subscriber point of view is divided in two entities, ESM and EMM.
* EMM entity will manage the subscriber mobility and ESM entity will manage its
* IP sessions. Both entities are linked to NAS model. EMM entity implements the mobility
* state machine and ESM entity holds all the PDN connections for the subscriber. More
* info about the entities can be found in the source files of nas directory.
*
* Sequence number list holds message sequence numbers, arrived in different modules,
* the last message in the list being the latest. The list can hold sequence numbers
* from GTP messages, Diameter messages etc.
*
* GTP procedure number holds an identifier of the last GTP procedure initiated in the
* GTP module. This number is important because message processing in this module is
* done based on this number.
*
* Status of the subscriber is a mini implementation of a state machine. Initially the
* subscriber will be in INACTIVE state, in which it has no information stored, it will
* go to PENDING if some operations are done upon it and will become ACTIVE if some
* conditions are fulfilled. The ACTIVE transition is done in various modules, for more
* info consult the sources for GTP, S1AP and SubscriberTable. If the subscriber stays
* too much outside ACTIVE state it will be cleaned.
*/
class Subscriber : public cPolymorphic {
private:
// radio info
int channelNr;
// s1ap info
unsigned enbId;
unsigned mmeId;
int channelNr;
// char *imsi;
char *plmnId;
char *cellId;
char *tac;
char *mmeCode;
char *mmeGrId;
// diameter/gtp info
char *msisdn;
char ratType;
char status; // for deleting the subscriber
// control tunnel over S11 interface
TunnelEndpoint *s11Tunn;
std::list<unsigned> seqNrs;
// nas entities
EMMEntity *emm;
ESMEntity *esm;
// message sequence numbers (multiple protocols)
std::list<unsigned> seqNrs;
// for gtp message processing
unsigned char gtpProc;
// for cleaning the subscriber
char status;
public:
Subscriber();
virtual ~Subscriber();
/* setter */
/*
* Method for initiating NAS entities for the subscriber.
*/
void initEntities(unsigned char appType);
/*
* Setter methods.
*/
void setEnbId(unsigned enbId) { this->enbId = enbId; }
void setMmeId(unsigned mmeId) { this->mmeId = mmeId; }
void setMmeGroupId(char *mmeGrId) { this->mmeGrId = mmeGrId; }
......@@ -73,7 +134,9 @@ public:
void setStatus(char status) { this->status = status; }
void setGTPProcedure(unsigned gtpProc) { this->gtpProc = gtpProc; }
/* getter */
/*
* Getter methods.
*/
unsigned getEnbId() { return enbId; }
unsigned getMmeId() { return mmeId; }
char *getMmeCode() { return mmeCode; }
......@@ -93,14 +156,21 @@ public:
const char *statusName() const;
unsigned char getGTPProcedure() { return gtpProc; }
/* message sequence numbers */
/*
* Methods for managing the message sequence numbers stored for the subscriber.
*/
void pushSeqNr(unsigned seqNr) { seqNrs.push_back(seqNr); }
unsigned popSeqNr();
unsigned backSeqNr() { return seqNrs.back(); }
void initEntities(unsigned char appType);
/*
* Method for printing information about a specific subscriber. This method
* will be called in the graphical user interface if the user wants to get
* details about the subscriber. For different entities this method will
* generate different output.
*/
std::string info() const;
};
#endif /* SUBSCRIBER_H_ */
//
// Copyright (C) 2012 Calin Cerchez
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
......@@ -33,18 +35,14 @@ SubscriberTable::~SubscriberTable() {
// TODO Auto-generated destructor stub
erase(0, subs.size());
if (inactiveTimer != NULL) {
if (inactiveTimer->getContextPointer() != NULL)
this->cancelEvent(inactiveTimer);
delete inactiveTimer;
if (cleanTimer != NULL) {
if (cleanTimer->getContextPointer() != NULL)
this->cancelEvent(cleanTimer);
delete cleanTimer;
}
}
void SubscriberTable::initialize(int stage) {
nb = NotificationBoardAccess().get();
// nb->subscribe(this, NF_SUBSCRIBER_STATE_CHANGED);
if (findPar("configFile") != -1) {
const char *fileName = par("configFile");
if ((fileName != NULL) && (strcmp(fileName, ""))) {
......@@ -59,14 +57,14 @@ void SubscriberTable::initialize(int stage) {
}
WATCH_PTRVECTOR(subs);
inactiveTimer = new cMessage("INACTIVE-TIMER");
inactiveTimer->setContextPointer(this);
this->scheduleAt(simTime() + INACTIVE_TIMER_TIMEOUT, inactiveTimer);
cleanTimer = new cMessage("INACTIVE-TIMER");
cleanTimer->setContextPointer(this);
this->scheduleAt(simTime() + CLEAN_TIMER_TIMEOUT, cleanTimer);
}
void SubscriberTable::handleMessage(cMessage *msg) {
if (msg->isSelfMessage()) {
if (msg == inactiveTimer) {
if (msg == cleanTimer) {
EV << "SubscriberTable: Inactive subscriber timer expired. Cleaning inactive subscribers.\n";
Subscribers::iterator i = subs.begin();
Subscribers::iterator last = subs.end();
......@@ -78,8 +76,8 @@ void SubscriberTable::handleMessage(cMessage *msg) {
subs.erase(i);
}
}
this->cancelEvent(inactiveTimer);
this->scheduleAt(simTime() + INACTIVE_TIMER_TIMEOUT, inactiveTimer);
this->cancelEvent(cleanTimer);
this->scheduleAt(simTime() + CLEAN_TIMER_TIMEOUT, cleanTimer);
}
} else
delete msg;
......@@ -168,8 +166,6 @@ void SubscriberTable::loadPDNConnectionsFromXML(const cXMLElement& subElem, Subs
} else {
esm->addPDNConnection(conn, false);
}
// nb->fireChangeNotification(NF_SUBSCRIBER_PDN_CONN_ADDED, conn);
}
}
}
......@@ -197,11 +193,9 @@ void SubscriberTable::loadSubscribersFromXML(const cXMLElement& config) {
emm->setImsi(LTEUtils().toIMSI(imsi));
sub->setMsisdn(LTEUtils().toTBCDString(msisdn, MSISDN_UNCODED_SIZE));
sub->setStatus(SUB_ACTIVE);
// sub->setId(generateId());
loadPDNConnectionsFromXML(*(*subIt), sub);
EV << "SubscriberTable: Subscriber nr. " << size() << endl;
push_back(sub);
// nb->fireChangeNotification(NF_SUBSCRIBER_CREATED, sub);
}
}
}
......
//
// Copyright (C) 2012 Calin Cerchez
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see http://www.gnu.org/licenses/.
//
#ifndef SUBSCRIBERTABLE_H_
#define SUBSCRIBERTABLE_H_
#include "Subscriber.h"
#define CLEAN_TIMER_TIMEOUT 10
/*
* Class for Subscriber table. This table will hold all the subscribers in a
* particular network node.
*/
class SubscriberTable : public cSimpleModule {
private:
unsigned enbIds;
unsigned mmeIds;
cMessage *cleanTimer;
typedef std::vector<Subscriber*> Subscribers;
Subscribers subs;
/*
* Methods for parsing the XML configuration file. First the subscribers will
* be created, filled with info and afterwards their PDN connections will be
* stored in ESM entity.
* ex.
* <Subscriber
* imsi="578195505601234"
* msisdn="491999792001">
* <PDNConns>
* <PDNConn def="true" apn="home.test" pdnGwAddr="192.168.4.2" pdnAllocAddr="10.10.10.1"/>
* <!-- <PDNConn def="false" apn="work.test" pdnGwAddr="192.168.4.2" pdnAllocAddr="10.10.20.1"/> -->
* </PDNConns>
* </Subscriber>
*/
void loadPDNConnectionsFromXML(const cXMLElement& subElem, Subscriber *sub);
void loadSubscribersFromXML(const cXMLElement& config);
public:
SubscriberTable();
virtual ~SubscriberTable();
/*
* Method for initializing the subscriber table. It will read the configuration
* from the XML file and fill the table with the generated subscribers. Also
* it schedules the clean timer in order to remove inactive subscribers.
*/
virtual void initialize(int stage);
/*
* Method for handling messages that arrive for the subscriber table. No external
* messages should arrive, but only the self message when the clean timer expires.
*/
virtual void handleMessage(cMessage *msg);
/*
* Method for finding a subscriber for a given eNB and MME id. The method returns
* the subscriber, if it is found, or NULL otherwise.
*/
Subscriber *findSubscriberForId(unsigned enbId, unsigned mmeId);
/*
* Method for finding a subscriber for a given channel id. The method returns
* the subscriber, if it is found, or NULL otherwise.
*/
Subscriber *findSubscriberForChannel(int channelNr);
/*
* Method for finding a subscriber for a given IMSI. The method returns
* the subscriber, if it is found, or NULL otherwise.
*/
Subscriber *findSubscriberForIMSI(char *imsi);
/*
* Method for finding a subscriber for a message sequence number. The method
* returns the subscriber, if it is found, or NULL otherwise.
*/
Subscriber *findSubscriberForSeqNr(unsigned seqNr);
/*
* Method for deleting a range of subscribers. The method calls first the
* destructor for the subscribers and removes them afterwards from the table.
*/
void erase(unsigned start, unsigned end);
/*
* Method for delete a subscriber, at a specific position. The method calls
* first the destructor for the subscriber and removes it from the table
* afterwards.
*/
void erase(unsigned it);
/*
* Wrapper methods.
*/
unsigned int size() {return subs.size();}
void push_back(Subscriber *sub) { subs.push_back(sub); }
S1APConnection *at(unsigned i) { return subs.at(i); }
/*
* Utility methods.
*/
unsigned genEnbId() { return ++enbIds; }
unsigned genMmeId() { return ++mmeIds; }
};
#endif /* SUBSCRIBERTABLE_H_ */
//
// Copyright (C) 2012 Calin Cerchez
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
......@@ -13,7 +15,7 @@
// along with this program. If not, see http://www.gnu.org/licenses/.
//
package inet.util.lte;
package inet.util.subscriber;
simple SubscriberTable
{
......
//
// Copyright (C) 2012 Calin Cerchez
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
//
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see http://www.gnu.org/licenses/.
//
//
#ifndef S1APPEERTABLE_H_
#define S1APPEERTABLE_H_
#ifndef SUBSCRIBERTABLEACCESS_H_
#define SUBSCRIBERTABLEACCESS_H_
#include "S1APConnection.h"
#include <omnetpp.h>
#include "ModuleAccess.h"
#include "SubscriberTable.h"
class S1APConnectionTable {
private:
typedef std::vector<S1APConnection*> ConnTable;
ConnTable conns;
/**
* Gives access to the SubscriberTable.
*/
class SubscriberTableAccess : public ModuleAccess<SubscriberTable> {
public:
S1APConnectionTable();
virtual ~S1APConnectionTable();
S1APConnection *findConnectionForId(int connId);
S1APConnection *findConnectionForCellId(char *cellId);
S1APConnection *findConnectionForState(int state);
S1APConnection *at(unsigned i) { return conns.at(i); }
void push_back(S1APConnection *conn) { conns.push_back(conn); }
void erase(unsigned start, unsigned end);
void clear() { conns.clear(); }
unsigned int size() {return conns.size();}
// void printTable();
SubscriberTableAccess() : ModuleAccess<SubscriberTable>("subscriberTable") {}
};
#endif /* S1APPEERTABLE_H_ */
#endif /* SUBSCRIBERTABLEACCESS_H_ */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册