return (TAlarm[])devAlarmList.toArray(new TAlarm[0]);
}
}
private TAlarm getAlarmFromList(int code,byte[] data,short flags,TAlarmWatchEntry awe)
{ // called only by setAlarm() ...
TAlarm alm = null;
int nerr = 0;
int thisTimeStamp = (int)(System.currentTimeMillis()/1000);
boolean keepTimestamp = false;
synchronized (devAlarmList)
{
Iterator<TAlarm> li = devAlarmList.iterator();
if (code == 0) DbgLog.log("getAlarmFromList","searching for alarm code == 0?");
while (li.hasNext())
{
try
{
alm = (TAlarm)li.next();
}
catch (ConcurrentModificationException e)
{ // this shouldn't happen !
// (if a caller uses a 'set' method on the alarm, it's almost gotta be right after this gets called)
nerr++;
MsgLog.log("getAlarmFromList", "concurrent modification error "+nerr,TErrorList.semaphore_error,e,0);
if (nerr > 3) return null;
continue;
}
keepTimestamp = false;
TAlarmDefinition ads = alm.getAlmDef();
if (alm.isTerminated())
{ // is marked for termination
boolean oscPinned = TAlarm.getAlmOscillationWindowPinned();
int oscw = TAlarm.getAlmOscillationWindow();
if (ads != null)
{
if (!oscPinned) oscPinned = ads.isOscillationWindowPinned();
oscw = ads.getAlarmOscillationWindow();
}
if (!alm.isTransient() && !oscPinned)
{ // oscillation window too small ?
int dt = (alm.getTimeStamp()+TAlarm.getTerminationWindow()) - (int)(System.currentTimeMillis()/1000);
if (dt > 0 && dt < TAlarm.ALM_OSCILLATION_MAXIMUM-oscw)
{ // adjust the oscillation window
oscw += dt;
if (ads != null) ads.setAlarmOscillationWindow(oscw);
else TAlarm.setAlmOscillationWindow(oscw,false);
if (TEquipmentModuleFactory.getDebugLevel() > 0)
DbgLog.log("getAlarmFromList","increase alarm oscillation windows to "+oscw+" clear counts");
}
}
continue;
}
else
{ // not marked for termination
if (alm.getCode() == code && alm.getWatchEntry() == awe)
{ // it's already in the list so remove NEW bit !
byte dsc = alm.getDescriptor();
byte[] adata = alm.getData();
int dlen = ads == null ? 0 : ads.getAlarmDataArraySize();
if (dlen > 0 && data != null && adata != null)
{ // check for alarm data changed
for (int n=0; n<dlen && n<adata.length && n<data.length; n++)
{
if (data[n] != adata[n])
{ // remove NEW and add DATACHANGE
dsc &= ~(byte)(TAlarmDescriptor.NEW);
if (alm.isDataChange())
{ // already marked as data change (when was the last time ?)
if (thisTimeStamp - alm.getTimeStamp() < TAlarm.getAlmDataChangeWindow())
{
keepTimestamp = true;
}
}
if (!keepTimestamp) alm.setTimeStamp(thisTimeStamp);
dsc |= (byte)TAlarmDescriptor.DATACHANGE;
if (TEquipmentModuleFactory.getDebugLevel() > 0)
DbgLog.log("getAlarmFromList",alm.getTag() + " : alarm data changed");
break;
}
}
}
if (alm.getClearCount() > 1)
{ // check for oscillating alarm ...
dsc &= ~(byte)(TAlarmDescriptor.NEW);
if (alm.isOscillating()) keepTimestamp = true;
if (!keepTimestamp) alm.setTimeStamp(thisTimeStamp);
dsc |= (byte)TAlarmDescriptor.OSCILLATION;
if (TEquipmentModuleFactory.getDebugLevel() > 0)
DbgLog.log("getAlarmFromList",alm.getTag() + " : mark alarm as oscillating");
}
alm.resetClearCount();
alm.setDescriptor(dsc);
return alm;
}
}
}
// not found, so this is a new one ...
// TODO: worry about 'max_alarms_exceeded', i.e. alarm storms and the length of this list!
if (devAlarmList.size() > maximumAllowedNumberOfAlarms)
{
devAlarmList.removeFirst();
MsgLog.log("TDevice.getAlarmFromList", "alarm buffer full",TErrorList.max_alarms_exceeded,null,1);
}
flags |= TAlarmDescriptor.NEW;
if ((flags & TAlarmDescriptor.TRANSIENT) != 0) flags |= TAlarmDescriptor.TERMINATE;
alm = new TAlarm(code,(byte)flags,data,this);
alm.setWatchEntry(awe);
if (eqm.casReadRequired) alm.blockRemoval();
devAlarmList.add(alm);
}
if (TEquipmentModuleFactory.getDebugLevel() > 0)
DbgLog.log("getAlarmFromList",devName + " : " + alm.getTag() + "(" + code + ") : add alarm to list");
return alm;
}