package com.owera.xaps.tr069.methods;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import com.owera.common.db.NoAvailableConnectionException;
import com.owera.xaps.base.Log;
import com.owera.xaps.base.db.DBAccess;
import com.owera.xaps.base.db.DBAccessSessionTR069;
import com.owera.xaps.dbi.Unit;
import com.owera.xaps.dbi.XAPS;
import com.owera.xaps.dbi.XAPSUnit;
import com.owera.xaps.dbi.tr069.TestCase;
import com.owera.xaps.dbi.tr069.TestDB;
import com.owera.xaps.dbi.util.ProvisioningMode;
import com.owera.xaps.dbi.util.SystemParameters;
import com.owera.xaps.dbi.util.TimestampWrapper;
import com.owera.xaps.tr069.HTTPReqResData;
import com.owera.xaps.tr069.InformParameters;
import com.owera.xaps.tr069.Properties;
import com.owera.xaps.tr069.SessionData;
import com.owera.xaps.tr069.test.system1.TestDatabase;
import com.owera.xaps.tr069.test.system1.TestDatabaseObject;
import com.owera.xaps.tr069.test.system2.TestUnit;
import com.owera.xaps.tr069.test.system2.TestUnit.TestState;
import com.owera.xaps.tr069.test.system2.TestUnitCache;
import com.owera.xaps.tr069.test.system2.Util;
import com.owera.xaps.tr069.xml.ParameterValueStruct;
/**
* EMDecision has to decide what to do after an EM-request. The rules are:
*
* 1. If previous response from server was EM, then we are at the end of the conversation, thus return EM (only true if HoldRequests is set to 1)
* 2. If the conversation was kicked and provisioning mode is not set accordingly, return EM (end conv.)
* 3. If the conversation was not kicked and provisioning mode is not AUTO, return EM (end. conv.)
* 4. If previous response from server was IN or TC, then return either GPN or GPV (depending upon a flag)
* 5. Else return EM
* @author Morten
*
*/
/**
* If a device is in INSPECTION mode, it should only allow kicked or booted
* traffic, not regular periodic traffic. If a device is in mode, all ways
* of initiating the traffic is accepted, but will be treated as regular AUTO
* provisioning.
*
*/
public class EMDecision {
// private static boolean modeCheck(SessionData sessionData) {
// Unit unit = sessionData.getUnit();
// if (unit.isSessionMode() && sessionData.isPeriodic() && !sessionData.isKicked()) {
// Log.warn(EMDecision.class, "EM-Decision is EM since a periodic inform happened in EXTRACTION/INSPECTION mode");
// return true;
// } else if (unit.getProvisioningMode() == ProvisioningMode.KICK) {
// unit.toWriteQueue(SystemParameters.PROVISIONING_MODE, ProvisioningMode.PERIODIC.toString());
// unit.toWriteQueue(SystemParameters.PROVISIONING_STATE, ProvisioningState.READY.toString());
// // Since the parameters above may not be written till the database until later in the session, we
// // must inject the new state into the Unit - without waiting for it to be written to db.
// Map<String, UnitParameter> unitParams = unit.getUnitParameters();
// unitParams.get(SystemParameters.PROVISIONING_MODE).setValue(ProvisioningMode.PERIODIC.toString()); // No chance of NP
// UnitParameter upState = unitParams.get(SystemParameters.PROVISIONING_STATE);
// if (upState != null)
// upState.setValue(ProvisioningState.READY.toString());
// }
// Log.debug(EMDecision.class, "Unit is in " + unit.getProvisioningMode() + " mode and " + unit.getProvisioningState() + " state");
// return false;
// }
private static boolean testExecution(HTTPReqResData reqRes) {
SessionData sessionData = reqRes.getSessionData();
Unit unit = sessionData.getUnit();
if (Util.testEnabled(reqRes, false)) {
// TODO:TF - initiate test - completed
reqRes.getSessionData().setTestMode(true); // This only last for one TR-069 session, not for the entire test (many test-cases and steps)
TestUnit tu = TestUnitCache.get(sessionData.getUnitId());
try {
if (tu == null) {
TestDB testDB = new TestDB(sessionData.getDbAccess().getXaps());
List<TestCase> testCases = testDB.getCompleteTestCases(sessionData.getUnittype(), Util.getTestCaseMethod(unit), Util.getParamFilter(unit), Util.getTagFilter(unit));
tu = new TestUnit(sessionData.getUnittype(), sessionData.getUnit(), testCases);
TestUnitCache.put(sessionData.getUnitId(), tu);
Log.notice(EMDecision.class, "A Test session has been initiated - " + testCases.size() + " will be tested");
}
tu.next(); // Responsible for updating TestState
if (tu.getTestState() == TestState.ENDTEST) {
Log.notice(EMDecision.class, "A Test session has been completed - will return to " + ProvisioningMode.REGULAR + " provisioning");
Log.info(EMDecision.class, "EM-Decision is " + TR069Method.EMPTY);
Util.testDisable(reqRes);
TestUnitCache.remove(tu.getUnit().getId());
reqRes.getResponse().setMethod(TR069Method.EMPTY);
} else {
String tr069Method = Util.step2TR069Method(tu.getCurrentStep(), Util.getTestCaseMethod(tu.getUnit()));
Log.info(EMDecision.class, "EM-Decision is " + tr069Method + " since ACS is in test-mode (new type) and test-state is " + tu.getTestState() + " and case-step is "
+ tu.getCurrentCase().getId() + "," + tu.getCurrentStep());
reqRes.getResponse().setMethod(tr069Method);
}
} catch (Exception te) {
Log.error(EMDecision.class, "Test aborted", te);
reqRes.getResponse().setMethod(TR069Method.EMPTY);
}
return true;
} else {
String row = TestDatabase.database.select(sessionData.getUnitId());
if (row != null) {
// TR069 Plugfest/Torture Test
TestDatabaseObject tdo = new TestDatabaseObject(row);
if (tdo.getRun().equals("true")) {
reqRes.getSessionData().setTestMode(true);
Log.info(EMDecision.class, "EM-Decision is CU since ACS is in test-mode and unitId is found in test-database and run=true");
reqRes.getResponse().setMethod(TR069Method.CUSTOM);
return true;
}
}
}
return false;
}
private static void writeSystemParameters(HTTPReqResData reqRes) throws SQLException {
writeSystemParameters(reqRes, null, true);
}
private static void writeSystemParameters(HTTPReqResData reqRes, List<ParameterValueStruct> params, boolean queue) throws SQLException {
SessionData sessionData = reqRes.getSessionData();
List<ParameterValueStruct> toDB = new ArrayList<ParameterValueStruct>();
if (params != null)
toDB = new ArrayList<ParameterValueStruct>(params);
String timestamp = TimestampWrapper.tmsFormat.format(new Date());
toDB.add(new ParameterValueStruct(SystemParameters.LAST_CONNECT_TMS, timestamp));
if (sessionData.getOweraParameters().getValue(SystemParameters.FIRST_CONNECT_TMS) == null)
toDB.add(new ParameterValueStruct(SystemParameters.FIRST_CONNECT_TMS, timestamp));
String ipAddress = sessionData.getUnit().getParameters().get(SystemParameters.IP_ADDRESS);
if (ipAddress == null || !ipAddress.equals(reqRes.getReq().getRemoteHost()))
toDB.add(new ParameterValueStruct(SystemParameters.IP_ADDRESS, reqRes.getReq().getRemoteHost()));
String swVersion = sessionData.getUnit().getParameters().get(SystemParameters.SOFTWARE_VERSION);
if (swVersion == null || !swVersion.equals(reqRes.getSessionData().getSoftwareVersion()))
toDB.add(new ParameterValueStruct(SystemParameters.SOFTWARE_VERSION, reqRes.getSessionData().getSoftwareVersion()));
// String serialNumber = sessionData.getUnitId().substring(sessionData.getUnitId().lastIndexOf("-") + 1);
// String mac = sessionData.getUnit().getParameters().get(SystemParameters.MAC);
// if (mac == null || !mac.equals(serialNumber))
// toDB.add(new ParameterValueStruct(SystemParameters.MAC, serialNumber));
String sn = sessionData.getUnit().getParameters().get(SystemParameters.SERIAL_NUMBER);
if (sn == null || !sn.equals(sessionData.getSerialNumber()))
toDB.add(new ParameterValueStruct(SystemParameters.SERIAL_NUMBER, sessionData.getSerialNumber()));
InformParameters ifmp = sessionData.getInformParameters();
if (ifmp != null && ifmp.getPvs(ifmp.UDP_CONNECTION_URL) != null && ifmp.getPvs(ifmp.UDP_CONNECTION_URL).getValue() != null) {
String udpUrl = ifmp.getPvs(ifmp.UDP_CONNECTION_URL).getValue();
if (udpUrl != null && !udpUrl.trim().equals("") && !udpUrl.equals(sessionData.getUnit().getParameterValue(ifmp.UDP_CONNECTION_URL))) {
toDB.add(ifmp.getPvs(ifmp.UDP_CONNECTION_URL));
}
}
sessionData.setToDB(toDB);
DBAccessSessionTR069.writeUnitParams(sessionData); // queue-parameters - will be written at end-of-session
if (!queue) { // execute changes immediately - since otherwise these parameters will be lost (in the event of GPNRes.process())
XAPS xaps = reqRes.getSessionData().getDbAccess().getXaps();
XAPSUnit xapsUnit = DBAccess.getXAPSUnit(xaps);
xapsUnit.addOrChangeQueuedUnitParameters(sessionData.getUnit());
}
sessionData.setToDB(null);
}
public static void process(HTTPReqResData reqRes) throws NoAvailableConnectionException, SQLException {
SessionData sessionData = reqRes.getSessionData();
String prevResponseMethod = sessionData.getPreviousResponseMethod();
if (prevResponseMethod == null) {
Log.error(EMDecision.class, "EM-Decision is EM since the CPE did not send an INFORM (or sessionId was not sent by client)");
reqRes.getResponse().setMethod(TR069Method.EMPTY);
} else if (prevResponseMethod.equals(TR069Method.EMPTY)) {
Log.info(EMDecision.class, "EM-Decision is EM since two last responses from CPE was EM");
reqRes.getResponse().setMethod(TR069Method.EMPTY);
} else if (prevResponseMethod.equals(TR069Method.INFORM) || prevResponseMethod.equals(TR069Method.TRANSFER_COMPLETE) || prevResponseMethod.equals(TR069Method.GET_RPC_METHODS_RES)) {
if (sessionData.getUnittype() == null) {
Log.info(EMDecision.class, "EM-Decision is EM since unittype is not found");
reqRes.getResponse().setMethod(TR069Method.EMPTY);
} else if (Properties.isTestMode() && testExecution(reqRes)) {
writeSystemParameters(reqRes);
return;
} else if (sessionData.discoverUnittype()) {
writeSystemParameters(reqRes, Arrays.asList(new ParameterValueStruct[] { new ParameterValueStruct(SystemParameters.DISCOVER, "0") }), false);
Log.info(EMDecision.class, "EM-Decision is GPN since unit has DISCOVER parameter set to 1");
reqRes.getResponse().setMethod(TR069Method.GET_PARAMETER_NAMES);
} else if ((Properties.isDiscoveryMode() && !sessionData.isUnittypeCreated() && sessionData.isFirstConnect())) {
writeSystemParameters(reqRes, null, false);
Log.info(EMDecision.class, "EM-Decision is GPN since ACS is in discovery-mode");
reqRes.getResponse().setMethod(TR069Method.GET_PARAMETER_NAMES);
} else if (Properties.isDiscoveryMode() && !sessionData.getUnittype().getUnittypeParameters().hasDeviceParameters()) {
writeSystemParameters(reqRes);
Log.info(EMDecision.class, "EM-Decision is GPN since ACS is in discovery-mode and no device parameters found");
reqRes.getResponse().setMethod(TR069Method.GET_PARAMETER_NAMES);
} else {
writeSystemParameters(reqRes);
Log.info(EMDecision.class, "EM-Decision is GPV since everything is normal and previous method was either IN or TC (updating LCT and possibly FCT)");
reqRes.getResponse().setMethod(TR069Method.GET_PARAMETER_VALUES);
}
} else {
Log.info(EMDecision.class, "EM-Decision is EM since it is the default method choice (nothing else fits)");
reqRes.getResponse().setMethod(TR069Method.EMPTY);
}
}
}