blob: ac20fd4d3f6be8e1fa1b148f10891fd1740770de [file] [log] [blame]
/**
* GGSN.java
*
* Core logic of GGSN
**/
class PDPcontext {
public int nsapi;
public String imsi;
//public int uplinkDataTeid;
//public int downlinkDataTeid;
}
class GGSN extends StateMachine
{
private Charging charging;
private CLI cli;
private NodeConfiguration nodeConfiguration;
private int uplinkData;
private int downlinkData;
private PDPcontext pdpContext;
public GGSN(Charging charging, CLI cli, NodeConfiguration nodeConfiguration)
{
this.charging = charging;
this.cli = cli;
this.nodeConfiguration = nodeConfiguration;
uplinkData = 0;
downlinkData = 0;
// NB: In our simplified view (for now) we only handle a single context,
// but the model can be easily enhanced to handle multiple contexts.
pdpContext = new PDPcontext();
}
private void createPDPcontext(CreatePDPcontext request)
{
// Control incoming data values - Qtronic specific to
// control test data generated for test suite.
/**
* Snippet of how it may look with a more or less
* one-to-one mapping between model and GTPC data:
require request.imsi_digits != null;
require request.imsi_digits.length == IMSI_OCTETS;
for (int i = 0; i < request.imsi_digits.length; i++)
require request.imsi_digits[i] == imsi1[i];
require request.teidDataI != null;
require request.teidDataI.length == TEID_OCTETS;
for (int i = 0; i < request.teidDataI.length; i++)
require request.teidDataI[i] == teid1[i];
**/
// Our simplified view on data
require request.imsi == "240001111231411";
//require request.downlinkDataTeid == 1;
require request.nsapi == 5;
require request.apn == "apn1.com";
// Handle request - in our simplified view we handle
// only one single PDP context. The state machine is
// laid out so that a createPDPcontext will always be
// done before any update, delete, or sending of payload.
pdpContext.imsi = request.imsi;
pdpContext.nsapi = request.nsapi;
//pdpContext.downlinkDataTeid = request.downlinkDataTeid;
//pdpContext.uplinkDataTeid = 3;
}
private void sendRadiusAuthRequest()
{
RadiusAccessRequest request;
GiRadiusOut.send(request);
requirement "Radius/Authentication/Send Access Request";
}
private void confirmCreatePDPcontext()
{
// Send response back
CreatePDPresponse response;
response.causevalue = REQUEST_ACCEPTED;
//response.uplinkDataTeid = pdpContext.uplinkDataTeid;
GnOut.send(response);
requirement "PDP context/Confirm successful creation";
}
private void updatePDPcontext(UpdatePDPcontext request)
{
// TODO: what to do with update??
// Currently it seems TTCN libraries take care of both update
// details and receiving the correct response, as well as doing
// the pass/fail verdict.
// We can have an "empty" update request in the model to just
// trigger a call to the existing library update function, or
// we can add more detail to the model and NOT use the existing
// library update function.
// 100114: we can handle the response to the update on the
// model level for understanding, but regard it as a NOP on
// the QtronicHarness level.
require request.nsapi == pdpContext.nsapi;
//require request.downlinkDataTeid == pdpContext.downlinkDataTeid;
// Send response
UpdatePDPresponse response;
response.causevalue = REQUEST_ACCEPTED;
GnOut.send(response);
requirement "PDP context/Confirm successful update";
}
private void deletePDPcontext(DeletePDPcontext request)
{
// Take care of request parameters
require request.nsapi == pdpContext.nsapi;
// Send response back
DeletePDPresponse response;
response.causevalue = REQUEST_ACCEPTED;
GnOut.send(response);
requirement "PDP context/Confirm successful deletion";
}
// forwardGPDUtoGi() - when a GPDU is recieved on the Gn interface
// the payload should be forwarded to the Gi interface
private void forwardGPDUtoGi(GPDU pdu)
{
//require pdu.header.teid == pdpContext.uplinkDataTeid;
// TODO: how much detail on model level?
uplinkData++;
charging.payload(pdu);
// Forward payload
UDPpdu udpPdu;
udpPdu.data = pdu.data;
GiOut.send(udpPdu);
}
// forwardUdpPduToGn() - when a UDP pdu is recieved on the Gi interface
// it should be forwarded/tunneled to the Gn interface
private void forwardUdpPduToGn(UDPpdu udpPdu)
{
// Forward/tunnel payload
GPDU pdu;
//pdu.header.teid = pdpContext.downlinkDataTeid;
pdu.data = udpPdu.data;
GnOut.send(pdu);
// TODO: how much detail on model level?
downlinkData++;
charging.payload(pdu);
}
}
void main()
{
NodeConfiguration nodeConfiguration = new NodeConfiguration();
Charging charging = new Charging();
CLI cli = new CLI(nodeConfiguration);
GGSN ggsn = new GGSN(charging, cli, nodeConfiguration);
ggsn.start("GGSN");
}