Commit ec95f511 authored by Claes Sjofors's avatar Claes Sjofors

Mh status message with alarmlist correction added

parent d3cdd959
......@@ -231,7 +231,8 @@ JNIEXPORT jobject JNICALL Java_jpwr_rt_Mh_outunitConnect
ev_mh_clear_alarmlist_bc,
NULL,
ev_mh_info_bc,
ev_mh_return_bc
ev_mh_return_bc,
NULL
);
jsts = (jint) sts;
......
......@@ -11,6 +11,7 @@ link = $(ldxx) -shared -DHW_X86 -DOS_LINUX \
${pwre_broot}/${pwre_target}/bld/lib/msg_dummy/msg_dummy_wb.o \
${pwre_broot}/${pwre_target}/bld/lib/msg_dummy/msg_dummy_ge.o \
${pwre_broot}/${pwre_target}/bld/lib/msg_dummy/msg_dummy_flow.o \
${pwre_broot}/${pwre_target}/bld/lib/msg_dummy/msg_dummy_glow.o \
${pwre_broot}/${pwre_target}/bld/lib/msg_dummy/msg_dummy_pwrp.o \
${pwre_broot}/${pwre_target}/bld/lib/rt/*.o \
${pwre_broot}/${pwre_target}/exp/obj/rt_io_user.o \
......
......@@ -131,7 +131,8 @@ main ()
NULL,
NULL,
(mh_cbOutunitInfo)Insert,
(mh_cbOutunitReturn)Insert
(mh_cbOutunitReturn)Insert,
NULL
);
If_Error_Log_Exit(sts, "mh_OutunitConnect");
......
......@@ -348,12 +348,15 @@ struct s_Outunit {
pwr_tTime birthTime; /* Time when outunit was started */
pwr_tObjid outunit; /* Object id of outunit object */
mh_eOutunitType type; /* Type of outunit */
pwr_tUInt32 ver; /* Outunit version */
pwr_tUInt32 ackGen; /* Generation of last ack received from outunit */
pwr_tUInt32 blockGen; /* Generation of last block received from outunit */
pwr_tUInt32 eventIdx; /* Index of last sent event to outunit */
pwr_tUInt32 eventGen; /* Generation of eventlist when last sent to outunit */
pwr_tUInt32 maxIdx; /* */
pwr_tUInt32 syncedIdx; /* */
pwr_tUInt32 lastSentIdx; /* Last event sent to outunit */
pwr_tTime lastSentTime; /* Time when last event is sent to outunit */
pwr_tBoolean check;
pwr_tBoolean linkUp;
pwr_mEventTypeMask selEventType;
......@@ -509,6 +512,7 @@ static void outunitInfo(mh_sHead*, sOutunit*);
static void outunitDisconnect(mh_sHead*, sOutunit*);
static void outunitLog(sOutunit*, char*);
static void outunitSync(mh_sHead *, sOutunit*);
static void outunitAlarmReq(mh_sHead *hp, sOutunit *op);
static void procDown(qcom_sAid*);
static void receive(qcom_sQid);
static void reInitSupList();
......@@ -1249,6 +1253,97 @@ cancelAlarm (
activeListRemove(ap);
eventToOutunits(ep);
}
static void
sendAlarmStatus( sOutunit *op)
{
LstLink(sActive) *al;
sEvent *ep;
sActive *ap;
mh_sAlarmStatus *msg;
int msg_size;
int sts;
pwr_tBoolean is_for_outunit;
/* Count alarms */
int count = 0;
for (al = LstFir(&l.active_l); al != LstEnd(&l.active_l); al = LstNex(al)) {
ap = LstObj(al);
switch (ap->detect_etp->event) {
case mh_eEvent_Info:
case mh_eEvent_Alarm:
case mh_eEvent_MaintenanceAlarm:
case mh_eEvent_SystemAlarm:
case mh_eEvent_UserAlarm1:
case mh_eEvent_UserAlarm2:
case mh_eEvent_UserAlarm3:
case mh_eEvent_UserAlarm4:
ep = ap->detect_etp->ep;
if ( ep)
is_for_outunit = isForOutunit(op, ep->outunit, ep->object.Objid, ep->objName, ep->msg.info.EventFlags,
ep->eventType, ep->local);
else
is_for_outunit = isForOutunit(op, ap->outunit, ap->object.Objid, ap->objName, ap->eventFlags,
ap->eventType, ap->local);
if ( is_for_outunit)
count++;
break;
default: ;
}
}
msg_size = sizeof(mh_sAlarmStatus) + (count - 1) * sizeof(mh_sAlarmSts);
msg = (mh_sAlarmStatus *)calloc( 1, msg_size);
msg->Nix = l.head.nix;
msg->Count = count;
count = 0;
for (al = LstFir(&l.active_l); al != LstEnd(&l.active_l); al = LstNex(al)) {
ap = LstObj(al);
switch (ap->detect_etp->event) {
case mh_eEvent_Info:
case mh_eEvent_Alarm:
case mh_eEvent_MaintenanceAlarm:
case mh_eEvent_SystemAlarm:
case mh_eEvent_UserAlarm1:
case mh_eEvent_UserAlarm2:
case mh_eEvent_UserAlarm3:
case mh_eEvent_UserAlarm4:
ep = ap->detect_etp->ep;
if ( ep)
is_for_outunit = isForOutunit(op, ep->outunit, ep->object.Objid, ep->objName, ep->msg.info.EventFlags,
ep->eventType, ep->local);
else
is_for_outunit = isForOutunit(op, ap->outunit, ap->object.Objid, ap->objName, ap->eventFlags,
ap->eventType, ap->local);
if ( is_for_outunit) {
msg->Sts[count].Idx = ap->idx;
msg->Sts[count].Status = ap->status.Event.Status;
count++;
#if 0
// Test
int sts = ap->status.Event.Status;
int idx = ap->idx;
printf( "idx: %d sts: %d\n", idx, sts);
// End test
#endif
}
break;
default: ;
}
}
sts = sendToOutunit(op, mh_eMsg_HandlerAlarmStatus, 0, msg, msg_size);
free( (char *)msg);
}
static void
checkOutunits ()
......@@ -1258,17 +1353,26 @@ checkOutunits ()
for (ol = LstFir(&l.outunit_l); ol != LstEnd(&l.outunit_l); ol = LstNex(ol)) {
op = LstObj(ol);
if (op->linkUp && op->syncedIdx != op->eventIdx) {
if (op->check) {
if ( op->linkUp &&
op->type == mh_eOutunitType_Operator &&
op->ver >= 5)
/* Set alarm status to operator */
sendAlarmStatus(op);
else {
/* Send sync */
if (op->linkUp && op->syncedIdx != op->eventIdx) {
if (op->check) {
#if 0
errh_Info("Sending sync request to outunit qid: %s, oid: %s\n %d =! %d",
qcom_QidToString(NULL, &op->link.qid, 1),
cdh_ObjidToString(NULL, op->outunit, 1),
op->syncedIdx, op->eventIdx);
errh_Info("Sending sync request to outunit qid: %s, oid: %s\n %d =! %d",
qcom_QidToString(NULL, &op->link.qid, 1),
cdh_ObjidToString(NULL, op->outunit, 1),
op->syncedIdx, op->eventIdx);
#endif
sendToOutunit(op, mh_eMsg_HandlerSync, 0, NULL, 0);
} else {
op->check = 1;
sendToOutunit(op, mh_eMsg_HandlerSync, 0, NULL, 0);
} else {
op->check = 1;
}
}
}
}
......@@ -1955,8 +2059,9 @@ fromHandler (
switch (hp->type) {
case mh_eMsg_ProcDown:
if (hp->ver != mh_cVersion) {
/* Different versions, not yet implemented */
if (!(hp->ver == mh_cVersion ||
(mh_cVersion == 5 && (hp->ver == 3 || hp->ver == 4)))) {
/* Different versions, not yet implemented (V5 is compatible with V3 and V4 */
errh_Info("fromHandler, Received a Message with different version");
break;
}
......@@ -2029,6 +2134,9 @@ fromOutunit (
case mh_eMsg_OutunitSync:
sendToOutunit(op, mh_eMsg_Sync, 0, NULL, 0);
break;
case mh_eMsg_OutunitAlarmReq:
outunitAlarmReq(hp, op);
break;
default:
errh_Error("fromOutunit, program error, type: %d", hp->type);
break;
......@@ -3141,7 +3249,7 @@ isValidApplication (
LstLink(sAppl) *al;
if (!(hp->ver == mh_cVersion ||
(mh_cVersion == 4 && hp->ver == 3))) { /* V4 is compatible with V3 */
(mh_cVersion == 5 && (hp->ver == 4 || hp->ver == 3)))) { /* V5 is compatible with V3 and V4 */
/* Different versions, not yet implemented */
errh_Info("isValidApplication: Received a Message with different version");
Reply->Sts = MH__VERSION;
......@@ -3206,7 +3314,7 @@ isValidOutunit (
LstLink(sOutunit) *ol;
if (!(hp->ver == mh_cVersion ||
(mh_cVersion == 4 && hp->ver == 3))) { /* V4 is compatible with V3 */
(mh_cVersion == 5 && (hp->ver == 4 || hp->ver == 3)))) { /* V5 is compatible with V3 and V4 */
/* Different versions, not yet implemented */
errh_Info("isValidOutunit: Received a Message with different version");
return FALSE;
......@@ -3231,6 +3339,7 @@ isValidOutunit (
op->link.platform = hp->platform;
op->link.nix = hp->nix;
op->birthTime = net_NetTimeToTime( &hp->birthTime);
op->ver = hp->ver;
op->outunit = hp->outunit;
/* Insert in outunit list */
LstIns(&l.outunit_l, op, outunit_l);
......@@ -3628,6 +3737,8 @@ outunitSync (
if (hp->eventGen != op->eventGen)
return;
// printf( "Sync: hp: %d opidx %d opsync %d\n", hp->eventIdx, op->eventIdx, op->syncedIdx);
if (op->eventIdx == op->syncedIdx)
return;
......@@ -3647,6 +3758,54 @@ outunitSync (
}
sendEventListToOutunit(op);
}
static void
outunitAlarmReq (
mh_sHead *hp,
sOutunit *op
)
{
mh_sOutunitAlarmReq *msg = (mh_sOutunitAlarmReq*) (hp + 1);
int i;
LstLink(sActive) *al;
sActive *ap;
int ok;
#if 0
printf( "outunitAlarmReq: ");
for ( i = 0; i < msg->Count; i++)
printf( " %d,", msg->Idx[i]);
printf("\n");
#endif
/* Find events in active list */
for ( i = 0; i < msg->Count; i++) {
for (al = LstFir(&l.active_l); al != LstEnd(&l.active_l); al = LstNex(al)) {
ap = LstObj(al);
if ( ap->idx == msg->Idx[i]) {
ok = reSendEventToOutunit( op, ap->detect_etp);
#if 0
if (ap->detect_etp->ep != NULL)
ok = sendEventToOutunit( op, ap->detect_etp);
else
ok = reSendEventToOutunit(op, ap->detect_etp);
printf( "Resend %d\n", ap->idx);
#endif
if (ok) {
if ( ap->idx > op->eventIdx)
op->eventIdx = ap->idx; /* Message was sent, update last sent index */
op->maxIdx = l.event_l->idx;
op->check = 0;
}
}
}
}
/* Avoid sync mismatch */
op->syncedIdx = op->eventIdx;
}
static void
procDown (
......@@ -4077,16 +4236,36 @@ sendEventListToOutunit (
if (etp == NULL)
return;
//#if 0
// Test
if ( op->lastSentIdx == etp->idx) {
/* Wait before resending it */
pwr_tTime current;
pwr_tDeltaTime dt;
float df;
time_GetTime(&current);
time_Adiff( &dt, &current, &op->lastSentTime);
df = time_DToFloat( 0, &dt);
if ( df < 1)
return;
}
if (etp->ep != NULL) {
ok = sendEventToOutunit(op, etp);
} else {
ok = reSendEventToOutunit(op, etp);
}
// printf( "eventListToOutunit: %d idx: %d ok: %d opidx %d opsynced %d\n", etp->ap ? etp->ap->idx : -1, etp->idx, ok, op->eventIdx, op->syncedIdx);
//#endif
//ok = 0; // Test
if (ok) {
op->eventIdx = etp->idx; /* Message was sent, update last sent index */
op->maxIdx = l.event_l->idx;
op->check = 0;
op->lastSentIdx = etp->idx;
time_GetTime(&op->lastSentTime);
}
}
......@@ -4193,6 +4372,7 @@ sendToOutunit (
hp->blockGen = op->blockGen;
hp->selGen = op->selGen;
// printf( "sendToOutunit: eventIdx %d\n", hp->eventIdx);
sts = mh_NetSendMessage(&op->link.qid, &op->link.platform, prio, subType, (mh_sHead *)mp, size);
if (EVEN(sts) && sts != QCOM__LINKDOWN) {
errh_Error("%s\n%m", "SendMessage: mh_NetSendMessage", sts);
......
......@@ -527,7 +527,8 @@ int main(int argc, char *argv[])
NULL,
NULL,
(mh_cbOutunitInfo)PrintEvent,
(mh_cbOutunitReturn)PrintEvent
(mh_cbOutunitReturn)PrintEvent,
NULL
);
if (EVEN(sts)) {
......
......@@ -111,7 +111,8 @@ void rt_post::open()
mh_clear_alarmlist_bc,
mh_clear_blocklist_bc,
mh_info_bc,
mh_return_bc
mh_return_bc,
NULL
);
if ( EVEN(sts)) {
errh_Error( "Post terminated: %m", sts);
......
......@@ -91,6 +91,7 @@
#define RTT_RXMIN 500 /* ms */
#define RTT_RXMAX 10000 /* ms */
#define RACK_TMO 1
#define ALLOC_WARNING_LEVEL 500000
#define max(Dragon,Eagle) ((Dragon) > (Eagle) ? (Dragon) : (Eagle))
......@@ -191,6 +192,7 @@ struct sLink {
qdb_sBuffer *bp;
char *p;
sIseg tmo;
int alloc_cnt;
};
......@@ -349,6 +351,7 @@ static void window_remove (sLink*, sEseg*);
static sEseg* window_tmo (sLink*);
static void check_link_status ();
static void set_status (pwr_tStatus);
static void panic (void);
int
......@@ -774,6 +777,10 @@ eseg_build (
sp->head.flags.b.middle = 1;
lst_InsertPred(NULL, &msp->le_seg, &sp->le_seg, sp);
}
lp->alloc_cnt += sp->size;
if ( lp->alloc_cnt > ALLOC_WARNING_LEVEL && qcom_sts != QCOM__BUFFHIGH)
set_status(QCOM__BUFFHIGH);
//printf( "qmon alloc: %d (%d)\n", sp->lp->alloc_cnt, sp->size);
}
sp->head.flags.b.middle = 0;
......@@ -827,6 +834,9 @@ eseg_free (
if (bcast) thread_MutexLock(&l.bcast);
sp->lp->alloc_cnt -= sp->size;
//printf( "qmon free: %d (%d)\n", sp->lp->alloc_cnt, sp->size);
lst_Remove(NULL, &sp->c.le);
if (lst_IsEmpty(NULL, &sp->le_bcast) && lst_IsEmpty(NULL, &sp->le_seg)) {
if (sp->bp != NULL) {
......@@ -839,6 +849,7 @@ eseg_free (
lst_Remove(NULL, &sp->le_seg);
}
if (bcast) thread_MutexUnlock(&l.bcast);
memset(sp, 0, sizeof(*sp));
......@@ -1165,7 +1176,11 @@ iseg_import (
decode_info(ip);
qdb_ScopeLock {
lp->bp = qdb_Alloc(&sts, qdb_eBuffer_base, ip->size);
} qdb_ScopeUnlock;
} qdb_ScopeUnlock;
if ( lp->bp == NULL) {
panic();
return;
}
lp->bp->c.flags.m |= ip->flags.m & qdb_mBuffer_maskExport;
lp->p = (char *)&lp->bp->b.info;
} else if (!sp->head.flags.b.first) {
......@@ -1333,8 +1348,9 @@ link_disconnect (
errh_Info("Disconnected, link to %s (%s)",
lp->np->name, cdh_NodeIdToString(NULL, lp->np->nid, 0, 0));
qdb_ScopeLock {
if (lp->bp != NULL)
if (lp->bp != NULL) {
qdb_Free(NULL, lp->bp);
}
lp->np->flags.b.active = 0;
lp->np->flags.b.connected = 0;
qdb_NetEvent(&sts, lp->np, qcom_eStype_linkDisconnect);
......@@ -1342,6 +1358,7 @@ link_disconnect (
lp->bp = NULL;
lp->p = NULL;
lp->alloc_cnt = 0;
sp = create_connect(lp);
lst_InsertSucc(NULL, &lp->lh_send, &sp->c.le, sp);
......@@ -2068,3 +2085,14 @@ pwr_tStatus sts
}
}
static void
panic (void)
{
pwr_tStatus sts;
sLink *lp;
errh_Error("Panic, qdb pool exhausted");
for (lp = tree_Minimum(&sts, l.links.table); lp != NULL; lp = tree_Successor(&sts, l.links.table, lp))
link_disconnect(lp);
}
......@@ -1375,7 +1375,8 @@ int rt_sevhistmon::init_events()
mh_clear_alarmlist_bc,
mh_clear_blocklist_bc,
mh_info_bc,
mh_return_bc);
mh_return_bc,
0);
if (EVEN(sts)) return sts;
m_sevhistevents = h;
......
......@@ -71,7 +71,7 @@ pwrs_Node_Exec (
static int supervise[80] = {
0,0,0,0,1,1,1,0,1,1,
1,1,1,0,0,1,0,1,1,1,
1,1,1,0,0,0,0,0,0,0,
1,1,1,0,0,1,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
......
......@@ -42,7 +42,7 @@
%#endif
%
%#define mh_cMsgClass 201
%#define mh_cVersion 4
%#define mh_cVersion 5
%#define mh_cProcHandler 111
%#define mh_cProcAllHandlers qcom_cQmhAllHandlers
%#define mh_cProcAllOutunits qcom_cQmhAllOutunits
......@@ -147,6 +147,7 @@ enum mh_eMsg {
mh_eMsg_HandlerDisconnect = 10,
mh_eMsg_HandlerHello = 11,
mh_eMsg_HandlerSync = 12,
mh_eMsg_HandlerAlarmStatus = 13,
mh_eMsg_OutunitAck = 15,
mh_eMsg_OutunitBlock = 16,
......@@ -155,6 +156,7 @@ enum mh_eMsg {
mh_eMsg_OutunitInfo = 20,
mh_eMsg_OutunitSync = 21,
mh_eMsg_OutunitClear = 22,
mh_eMsg_OutunitAlarmReq = 23,
mh_eMsg_ProcDown = 24,
......@@ -402,6 +404,12 @@ struct mh_sReturn {
pwr_tAName EventName;
};
struct mh_sOutunitAlarmReq {
pwr_tNodeIndex Nix;
pwr_tUInt32 Count; /* # of entries */
pwr_tUInt32 Idx[20];
};
#ifdef RPC_HDR
%struct mh_sOutunitInfo {
% pwr_tUInt16 type;
......@@ -479,3 +487,48 @@ struct mh_sReturn {
%
%#endif
#endif
struct mh_sAlarmSts {
pwr_tUInt32 Idx;
mh_mEventStatus Status;
};
#ifdef RPC_HDR
%
%typedef struct {
% pwr_tNodeIndex Nix;
% pwr_tUInt32 Count; /* # of entries */
% mh_sAlarmSts Sts[1]; /* Specifications (dynamic) */
%} mh_sAlarmStatus;
%
%bool_t
%xdr_mh_sAlarmStatus();
%
#elif defined RPC_XDR
%
%bool_t
%xdr_mh_sAlarmStatus(xdrs, objp)
% XDR *xdrs;
% mh_sAlarmStatus *objp;
%{
% int count;
%
% if (xdrs->x_op == XDR_DECODE) {
% count = (int) ntohl(objp->Count);
% } else {
% count = objp->Count;
% }
%
% if (!xdr_pwr_tUInt32(xdrs, &objp->Nix)) {
% return (FALSE);
% }
% if (!xdr_pwr_tUInt32(xdrs, &objp->Count)) {
% return (FALSE);
% }
% if (!xdr_vector(xdrs, (char *)objp->Sts, count, sizeof(mh_sAlarmSts), (xdrproc_t)xdr_mh_sAlarmSts)) {
% return (FALSE);
% }
% return (TRUE);
%}
#endif
......@@ -117,6 +117,7 @@ typedef struct {
pwr_tStatus (*cbClearBlockList)(pwr_tNodeIndex);
pwr_tStatus (*cbInfo)(mh_sMessage *);
pwr_tStatus (*cbReturn)(mh_sReturn *);
pwr_tStatus (*cbAlarmStatus)(mh_sAlarmStatus *);
LstHead(sHandler) handler_l;
LstHead(sHandler) sync_l;
pwr_tUInt32 selGen;
......@@ -153,6 +154,7 @@ static void getSelectList();
static void handlerEvent(sHandler*, mh_sHead*);
static void handlerLog(sHandler*, char*);
static void handlerSync(sHandler*, mh_sHead*);
static void handlerAlarmStatus(sHandler*, mh_sHead*);
static pwr_tBoolean isValidHandler(mh_sHead*, qcom_sAid*, sHandler**);
static void linkDown(qcom_sNode*);
static void linkUp(qcom_sNode*);
......@@ -250,11 +252,12 @@ mh_OutunitConnect (
mh_cbOutunitBlock cbBlock, /**< Address of a function to receive blocking messages.*/
mh_cbOutunitCancel cbCancel, /**< Address of a function to receive cancel messages.*/
mh_cbOutunitClearAlarmList cbClearAlarmList, /**< Address of a function to clear alarm list from alarms
generated by the node corresponding to PAMS_ADDRESS. */
generated by the node. */
mh_cbOutunitClearBlockList cbClearBlockList, /**< Address of a function to clear block list from blocks
generated by the node corresponding to PAMS_ADDRESS.*/
mh_cbOutunitInfo cbInfo, /**< ZZZ */
mh_cbOutunitReturn cbReturn /**< ZZZ */
generated by the node.*/
mh_cbOutunitInfo cbInfo, /**< Address of a function to receive info messages. */
mh_cbOutunitReturn cbReturn, /**< Address of a function to receive alarm return messages. */
mh_cbOutunitAlarmStatus cbAlarmStatus /**< Address of a function to receive alarm status messages. */
)
{
pwr_tStatus sts;
......@@ -362,6 +365,7 @@ mh_OutunitConnect (
l.cbClearBlockList = cbClearBlockList;
l.cbInfo = cbInfo;
l.cbReturn = cbReturn;
l.cbAlarmStatus = cbAlarmStatus;
LstIni(&l.handler_l);
LstIni(&l.sync_l);
......@@ -509,7 +513,37 @@ mh_OutunitUpdate ()
return MH__SUCCESS;
}
/**
*@brief Request info about missing alarms.
*@return pwr_tStatus
*/
pwr_tStatus
mh_OutunitAlarmRequest (
mh_sOutunitAlarmReq *msg
)
{
sHandler *hp;
LstLink(sHandler) *hl;
/* Find originating handler */
for (hl = LstFir(&l.handler_l); hl != LstEnd(&l.handler_l); hl = LstNex(hl))
if (LstObj(hl)->nix == msg->Nix)
break;
if (hl == LstEnd(&l.handler_l)) {
return MH__HANDLERDOWN;
} else {
hp = LstObj(hl);
}
sendToHandler(hp, mh_eMsg_OutunitAlarmReq, sizeof(*msg), (void *) msg);
return MH__SUCCESS;
}
static void
ackListDelete (
......@@ -766,10 +800,13 @@ fromHandler (
sendInfo(hp);
break;
case mh_eMsg_OutunitClear:
printf( "Clear alarmlist received\n");
if (l.cbClearAlarmList != NULL)
l.cbClearAlarmList(hp->nix);
break;
case mh_eMsg_HandlerAlarmStatus:
handlerAlarmStatus(hp, p);
handlerSync(hp, p);
break;
default:
errh_Warning("Received unhandled messagetype: %d", p->type);
break;
......@@ -962,6 +999,27 @@ handlerSync (
checkSyncListDelete(hp);
}
}
static void
handlerAlarmStatus (
sHandler *hp,
mh_sHead *p
)
{
pwr_tStatus sts;
mh_sAlarmStatus *mp = (mh_sAlarmStatus *) (p + 1);
int i;
/* Skip events sent from an old select list. */
if (p->selGen != l.selGen)
return;
if (l.cbAlarmStatus != NULL)
sts = l.cbAlarmStatus( mp);
}
static pwr_tBoolean
isValidHandler (
......@@ -974,7 +1032,7 @@ isValidHandler (
LstLink(sHandler) *hl;
if (!(p->ver == mh_cVersion ||
(mh_cVersion == 4 && p->ver == 3))) { /* V4 is compatible with V3 */
(mh_cVersion == 5 && (p->ver == 3 || p->ver == 4)))) { /* V5 is compatible with V3 and V4 */
/* Different versions, not yet implemented */
errh_Warning("Received a Message with different version: %d != %d", p->ver, mh_cVersion);
*h = NULL;
......
......@@ -164,6 +164,18 @@ typedef pwr_tStatus (*mh_cbOutunitInfo)(mh_sMessage *);
*/
typedef pwr_tStatus (*mh_cbOutunitReturn)(mh_sReturn *);
/**
* @brief Callback function to handle alarm status messages.
*
* It should be declared to the mh_Outunit API at the mh_OutunitConnect call.
* The function can have any name, but the address to the routine should be passed
* in the mh_OutunitConnect call.
* The mh_Outunit API calls this function if an alarm status message arrives.
* @param mh_cbOutunitAlarmStatus Address of a alarm status message.
* @return pwr_tStatus - Status return in standard VMS-format.
*/
typedef pwr_tStatus (*mh_cbOutunitAlarmStatus)(mh_sAlarmStatus *);
/* Exported functions */
......@@ -188,7 +200,8 @@ pwr_tStatus mh_OutunitConnect(
mh_cbOutunitClearAlarmList Callback_ClearAlarmList,
mh_cbOutunitClearBlockList Callback_ClearBlockList,
mh_cbOutunitInfo Callback_Info,
mh_cbOutunitReturn Callback_Return
mh_cbOutunitReturn Callback_Return,
mh_cbOutunitAlarmStatus Callback_AlarmStatus
);
pwr_tStatus mh_OutunitDisconnect();
......@@ -202,6 +215,9 @@ pwr_tStatus mh_OutunitSetTimeout(int Timeout);
pwr_tStatus mh_OutunitUpdate();
pwr_tStatus
mh_OutunitAlarmRequest(mh_sOutunitAlarmReq *msg);
/** @} */
#if defined __cplusplus
}
......
......@@ -707,7 +707,8 @@ int rtt_alarm_connect (
rtt_mh_clear_alarmlist_bc,
rtt_mh_clear_blocklist_bc,
rtt_mh_info_bc,
rtt_mh_return_bc
rtt_mh_return_bc,
0
);
if (EVEN(sts)) return sts;
......
......@@ -71,6 +71,7 @@ notinited <Qcom not inited for application> /error
allrattached <queue is already attached> /error
notattachable <queue can not be attached> /error
down <Link down> /warning
buffhigh <High buffer level> /warning
.end
......
......@@ -904,6 +904,7 @@ static pwr_tUInt32 tlog_alarm_connect( pwr_tObjid user_object)
NULL,
NULL,
tlog_mh_info_bc,
NULL,
NULL
);
if (EVEN(sts)) return sts;
......
......@@ -81,7 +81,7 @@ Ev::Ev( void *ev_parent_ctx,
start_trace_cb(NULL), display_in_xnav_cb(NULL), update_info_cb(NULL),
help_cb(NULL), popup_menu_cb(0), sound_cb(0), pop_cb(0), is_authorized_cb(0), eve(NULL), ala(NULL),
blk(0), connected(0), ala_displayed(0), eve_displayed(0), beep(ev_beep), pop_mask(ev_pop_mask),
eventname_seg(ev_eventname_seg), sala_cnt(0), seve_cnt(0)
eventname_seg(ev_eventname_seg), sala_cnt(0), seve_cnt(0), modified(0)
{
}
......@@ -305,6 +305,9 @@ void Ev::eve_activate_ack_last()
sala[i]->ack( id);
for ( int i = 0; i < seve_cnt; i++)
seve[i]->ack( id);
if ( update_info_cb)
update_info_cb( parent_ctx);
ala->fill_alarm_tables();
mh_OutunitAck( &lid);
}
......@@ -345,6 +348,9 @@ void Ev::ala_activate_ack_last()
sala[i]->ack( id);
for ( int i = 0; i < seve_cnt; i++)
seve[i]->ack( id);
if ( update_info_cb)
update_info_cb( parent_ctx);
ala->fill_alarm_tables();
mh_OutunitAck( &lid);
}
......@@ -425,7 +431,8 @@ int Ev::outunit_connect( pwr_tObjid user)
mh_clear_alarmlist_bc,
mh_clear_blocklist_bc,
mh_info_bc,
mh_return_bc
mh_return_bc,
mh_alarmstatus_bc
);
if (EVEN(sts)) return sts;
......@@ -437,6 +444,7 @@ void Ev::update( double scantime)
{
int sts;
int nodraw_set = 0;
int redraw = 0;
sts = mh_OutunitReceive();
while (ODD(sts))
......@@ -448,11 +456,17 @@ void Ev::update( double scantime)
nodraw_set = 1;
}
sts = mh_OutunitReceive();
redraw = redraw | ev->modified;
}
if ( nodraw_set)
{
eve->reset_nodraw();
ala->reset_nodraw();
if ( nodraw_set) {
if ( redraw) {
eve->reset_nodraw();
ala->reset_nodraw();
}
else {
brow_ResetNodraw( eve->brow->ctx);
brow_ResetNodraw( ala->brow->ctx);
}
}
ala->flash();
......@@ -481,18 +495,30 @@ void Ev::ack_last_prio( unsigned long type, unsigned long prio)
sala[i]->ack( id);
for ( int i = 0; i < seve_cnt; i++)
seve[i]->ack( id);
if ( update_info_cb)
update_info_cb( parent_ctx);
ala->fill_alarm_tables();
mh_OutunitAck( &lid);
}
}
void Ev::ack_all()
{
mh_sEventId *id;
mh_sEventId *id, *idv;
int sts;
int num;
int idx;
if (is_authorized_cb && !is_authorized_cb( parent_ctx, pwr_mAccess_RtEventsAck | pwr_mAccess_System))
return;
num = ala->get_num_not_acked();
if ( num == 0)
return;
idv = (mh_sEventId *)calloc( num, sizeof(mh_sEventId));
idx = 0;
sts = ala->get_last_not_acked( &id);
while ( ODD(sts)) {
mh_sEventId lid = *id;
......@@ -502,10 +528,18 @@ void Ev::ack_all()
sala[i]->ack( id);
for ( int i = 0; i < seve_cnt; i++)
seve[i]->ack( id);
mh_OutunitAck( &lid);
idv[idx++] = lid;
sts = ala->get_last_not_acked( &id);
}
if ( update_info_cb)
update_info_cb( parent_ctx);
ala->fill_alarm_tables();
for ( int i = 0; i < idx; i++)
mh_OutunitAck( &idv[i]);
free( (char *)idv);
}
int Ev::get_last_not_acked_prio( mh_sEventId **id, unsigned long type,
......@@ -591,6 +625,7 @@ pwr_tStatus Ev::mh_ack_bc( mh_sAck *MsgP)
if ( ev->update_info_cb)
ev->update_info_cb( ev->parent_ctx);
ev->ala->fill_alarm_tables();
ev->modified = 1;
return 1;
}
......@@ -610,6 +645,7 @@ pwr_tStatus Ev::mh_return_bc( mh_sReturn *MsgP)
if ( ev->update_info_cb)
ev->update_info_cb( ev->parent_ctx);
ev->ala->fill_alarm_tables();
ev->modified = 1;
return 1;
}
......@@ -649,6 +685,7 @@ pwr_tStatus Ev::mh_alarm_bc( mh_sMessage *MsgP)
if ( pop)
ev->pop_cb( ev->parent_ctx);
}
ev->modified = 1;
return 1;
}
......@@ -659,6 +696,7 @@ pwr_tStatus Ev::mh_block_bc( mh_sBlock *MsgP)
if ( ev->update_info_cb)
ev->update_info_cb( ev->parent_ctx);
ev->ala->fill_alarm_tables();
ev->modified = 1;
return 1;
}
......@@ -671,6 +709,7 @@ pwr_tStatus Ev::mh_cancel_bc( mh_sReturn *MsgP)
if ( ev->update_info_cb)
ev->update_info_cb( ev->parent_ctx);
ev->ala->fill_alarm_tables();
ev->modified = 1;
return 1;
}
......@@ -687,6 +726,7 @@ pwr_tStatus Ev::mh_info_bc( mh_sMessage *MsgP)
ev->ala->fill_alarm_tables();
if ( ev->pop_mask & pwr_mOpWindPopMask_InfoMsg)
ev->pop_cb( ev->parent_ctx);
ev->modified = 1;
return 1;
}
......@@ -700,12 +740,142 @@ pwr_tStatus Ev::mh_clear_alarmlist_bc( pwr_tNodeIndex nix)
if ( ev->update_info_cb)
ev->update_info_cb( ev->parent_ctx);
ev->ala->fill_alarm_tables();
ev->modified = 1;
return 1;
}
pwr_tStatus Ev::mh_clear_blocklist_bc( pwr_tNodeIndex nix)
{
ev->blk->event_clear_alarmlist( nix);
ev->modified = 1;
return 1;
}
pwr_tStatus Ev::mh_alarmstatus_bc( mh_sAlarmStatus *MsgP)
{
brow_tObject *object_list;
int object_cnt;
ItemAlarm *item;
int i;
unsigned int j;
int *found;
mh_sOutunitAlarmReq *rmsg;
int modified = 0;
found = (int *)calloc( 1, MsgP->Count * sizeof(int));
brow_GetObjectList( ev->ala->browbase->ctx, &object_list, &object_cnt);
// Reset check to find obsolete items
for ( i = 0; i < object_cnt; i++) {
brow_GetUserData( object_list[i], (void **)&item);
switch( item->type) {
case evlist_eItemType_Alarm:
if ( MsgP->Nix == item->eventid.Nix)
item->check = 0;
break;
default: ;
}
}
for ( i = 0; i < object_cnt; i++) {
brow_GetUserData( object_list[i], (void **)&item);
switch( item->type) {
case evlist_eItemType_Alarm:
for ( j = 0; j < MsgP->Count; j++) {
if ( MsgP->Nix == item->eventid.Nix &&
MsgP->Sts[j].Idx == item->eventid.Idx) {
found[j] = 1;
item->check = 1;
if ( !(MsgP->Sts[j].Status & mh_mEventStatus_NotRet) &&
(item->status & mh_mEventStatus_NotRet)) {
pwr_tUInt32 status = item->status;
mh_sReturn retmsg;
memset( &retmsg, 0, sizeof(retmsg));
retmsg.TargetId = item->eventid;
ev->ala->event_return( &retmsg);
for ( int k = 0; k < ev->sala_cnt; k++)
ev->sala[k]->mh_return( &retmsg);
modified = 1;
if ( !(status & mh_mEventStatus_NotAck)) {
// Item was removed
i--;
object_cnt--;
continue;
}
}
if ( !(MsgP->Sts[j].Status & mh_mEventStatus_NotAck) &&
(item->status & mh_mEventStatus_NotAck)) {
pwr_tUInt32 status = item->status;
mh_sAck ackmsg;
memset( &ackmsg, 0, sizeof(ackmsg));
ackmsg.TargetId = item->eventid;
ev->ala->event_ack( &ackmsg);
for ( int k = 0; k < ev->sala_cnt; k++)
ev->sala[k]->mh_ack( &ackmsg);
modified = 1;
if ( !(status & mh_mEventStatus_NotRet)) {
// Item was removed
i--;
object_cnt--;
continue;
}
}
}
}
break;
default:
;
}
}
// Find and remove the obsolete items
brow_GetObjectList( ev->ala->browbase->ctx, &object_list, &object_cnt);
for ( i = 0; i < object_cnt; i++) {
brow_GetUserData( object_list[i], (void **)&item);
switch( item->type) {
case evlist_eItemType_Alarm:
if ( MsgP->Nix == item->eventid.Nix && !item->check) {
ev->ala->event_delete( &item->eventid);
for ( int k = 0; k < ev->sala_cnt; k++)
ev->sala[k]->event_delete( &item->eventid);
i--;
object_cnt--;
modified = 1;
}
break;
default: ;
}
}
if ( modified) {
if ( ev->update_info_cb)
ev->update_info_cb( ev->parent_ctx);
ev->ala->fill_alarm_tables();
}
// Request info about any missing ids
rmsg = (mh_sOutunitAlarmReq *) calloc( 1, sizeof(*rmsg));
rmsg->Nix = MsgP->Nix;
for ( j = 0; j < MsgP->Count; j++) {
if ( !found[j]) {
// Request info about this id
rmsg->Idx[rmsg->Count] = MsgP->Sts[j].Idx;
rmsg->Count++;
}
if ( rmsg->Count >= sizeof(rmsg->Idx)/sizeof(rmsg->Idx[0]))
break;
}
if ( rmsg->Count > 0)
mh_OutunitAlarmRequest( rmsg);
free( (char *)rmsg);
free( (char *)found);
ev->modified = modified;
return 1;
}
......
......@@ -126,6 +126,7 @@ class Ev {
int sala_cnt;
EvEve *seve[20];
int seve_cnt;
int modified;
virtual void map_eve( unsigned int options) {}
virtual void map_ala( unsigned int options) {}
......@@ -202,6 +203,7 @@ class Ev {
static pwr_tStatus mh_info_bc( mh_sMessage *MsgP);
static pwr_tStatus mh_clear_alarmlist_bc( pwr_tNodeIndex nix);
static pwr_tStatus mh_clear_blocklist_bc( pwr_tNodeIndex nix);
static pwr_tStatus mh_alarmstatus_bc( mh_sAlarmStatus *MsgP);
};
......
......@@ -239,6 +239,11 @@ void EvAla::update()
ala->flash();
}
int EvAla::event_delete( mh_sEventId *id)
{
return ala->event_delete( id);
}
void EvAla::ack_last_prio( unsigned long type, unsigned long prio)
{
mh_sEventId *id;
......
......@@ -123,6 +123,8 @@ class EvAla {
void ack( mh_sEventId *id) { ala->ack(id);}
int get_last_not_acked_prio( mh_sEventId **id, unsigned long type,
unsigned long prio);
int event_delete( mh_sEventId *id);
static void ala_display_in_xnav_cb( void *ctx, pwr_tAttrRef *arp);
static void ala_start_trace_cb( void *ctx, pwr_tObjid objid, char *name);
......
......@@ -1229,6 +1229,26 @@ void EvList::event_return( mh_sReturn *msg)
}
}
int EvList::event_delete( mh_sEventId *id)
{
if ( type == ev_eType_AlarmList) {
// Alarmlist
ItemAlarm *item;
if ( !id_to_item( id, (void **)&item))
return 0;
brow_DeleteNode( browbase->ctx, item->node);
if ( browtree) {
if ( item->tree_node)
brow_DeleteNode( browtree->ctx, item->tree_node);
view_configure();
}
size--;
}
return 1;
}
void EvList::print_nodia( char *filename)
{
brow_Print( brow->ctx, filename);
......@@ -1791,7 +1811,8 @@ ItemAlarm::ItemAlarm( EvList *item_evlist, const char *item_name, pwr_tTime item
brow_tNode dest, flow_eDest dest_code, int *rsts):
event_type(item_event_type), evlist(item_evlist), tree_node(0), time(item_time),
eventtype(item_eventtype), eventflags(item_eventflags), eventprio(item_eventprio),
eventid(item_eventid), object(*item_object), status(item_status), supobject(*item_supobject)
eventid(item_eventid), object(*item_object), status(item_status), supobject(*item_supobject),
check(0)
{
type = evlist_eItemType_Alarm;
brow_tNodeClass nc;
......@@ -2356,6 +2377,29 @@ void ItemCategory::flash( EvList *evlist)
}
}
int EvList::get_num_not_acked()
{
int i;
brow_tObject *object_list;
int object_cnt;
ItemAlarm *object_item;
int num = 0;
brow_GetObjectList( browbase->ctx, &object_list, &object_cnt);
for ( i = 0; i < object_cnt; i++) {
brow_GetUserData( object_list[i], (void **)&object_item);
switch( object_item->type) {
case evlist_eItemType_Alarm:
if ( object_item->status & mh_mEventStatus_NotAck)
num++;
break;
default:
;
}
}
return num;
}
int EvList::get_last_not_acked( mh_sEventId **id)
{
int i;
......
......@@ -234,6 +234,8 @@ class EvList {
void event_ack( mh_sAck *msg);
void event_return( mh_sReturn *msg);
void event_clear_alarmlist( pwr_tNodeIndex nix);
int event_delete( mh_sEventId *id);
int get_num_not_acked();
int get_last_not_acked( mh_sEventId **id);
int get_last_not_acked_beep( mh_sEventId **id);
int id_to_item( mh_sEventId *id, void **item);
......@@ -301,11 +303,12 @@ class ItemAlarm : public ItemEvBase {
unsigned long eventprio;
mh_sEventId eventid;
pwr_tAttrRef object;
unsigned long status;
mh_mEventStatus status;
char alias[40];
pwr_tAttrRef eventsound;
pwr_tText256 eventmoretext;
pwr_tAttrRef supobject;
int check;
void update_text(int tree_node);
};
......
......@@ -4456,6 +4456,9 @@ static int xnav_open_func( void *client_data,
sts = gdh_GetObjectInfo( hist_name, &plot, sizeof(plot));
if ( EVEN(sts)) return sts;
if ( plot.Layout & pwr_mCurveLayoutMask_AttrDescrFirst)
options |= curve_mOptions_ShowDescrFirst;
for ( j = 0; j < 20; j++) {
if ( cdh_ObjidIsNull( plot.YObjectName[j].Objid))
break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment