ProviewR Programmer's Reference Manual  V7.0.0
rt_sevcli.c
Go to the documentation of this file.
1 /*
2  * ProviewR Open Source Process Control.
3  * Copyright (C) 2005-2026 SSAB EMEA AB.
4  *
5  * This file is part of ProviewR.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License as
9  * published by the Free Software Foundation, either version 2 of
10  * the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with ProviewR. If not, see <http://www.gnu.org/licenses/>
19  *
20  * Linking ProviewR statically or dynamically with other modules is
21  * making a combined work based on ProviewR. Thus, the terms and
22  * conditions of the GNU General Public License cover the whole
23  * combination.
24  *
25  * In addition, as a special exception, the copyright holders of
26  * ProviewR give you permission to, from the build function in the
27  * ProviewR Configurator, combine ProviewR with modules generated by the
28  * ProviewR PLC Editor to a PLC program, regardless of the license
29  * terms of these modules. You may copy and distribute the resulting
30  * combined work under the terms of your choice, provided that every
31  * copy of the combined work is accompanied by a complete copy of
32  * the source code of ProviewR (the version used to produce the
33  * combined work), being distributed under the terms of the GNU
34  * General Public License plus this exception.
35  */
36 
41 #include "co_cdh.h"
42 #include "co_cnf.h"
43 #include "co_string.h"
44 #include "co_time.h"
45 
46 #include "rt_qcom_msg.h"
47 #include "rt_sev_msg.h"
48 #include "rt_sevcli.h"
49 #include "rt_sev_net.h"
50 
51 static sevcli_tCtx stored_ctx = 0;
52 
63 {
64  // Create a queue to server
65  qcom_sQattr attr;
66 
67  *ctx = calloc(1, sizeof(sevcli_sCtx));
68 
69  (*ctx)->qid.qix = 0;
70  (*ctx)->qid.nid = 0;
71  attr.type = qcom_eQtype_private;
72  attr.quota = 100;
73 
74  if (!qcom_CreateQ(sts, &(*ctx)->qid, &attr, "SevXtt")) {
75  return 0;
76  }
77  *sts = SEV__SUCCESS;
78  return 1;
79 }
80 
87 {
88  // Delete queue
89  if (!qcom_DeleteQ(sts, &ctx->qid)) {
90  return 0;
91  }
92  if (ctx == stored_ctx)
93  stored_ctx = 0;
94  free(ctx);
95  *sts = SEV__SUCCESS;
96  return 1;
97 }
98 
106 {
107  ctx->server = nid;
108 }
109 
118 int sevcli_set_servernode(pwr_tStatus* sts, sevcli_tCtx ctx, char* nodename)
119 {
120  qcom_sNode node;
121  pwr_tNid nid;
122 
123  if (!nodename || streq(nodename, "")) {
124  ctx->server = ctx->qid.nid;
125  *sts = SEV__SUCCESS;
126  return 1;
127  }
128 
129  // Try this node
130  qcom_MyNode(sts, &node);
131  if (EVEN(*sts))
132  return 0;
133 
134  if (str_NoCaseStrcmp(node.name, nodename) == 0 || str_NoCaseStrcmp(nodename, "localhost") == 0) {
135  ctx->server = node.nid;
136  *sts = SEV__SUCCESS;
137  return 1;
138  }
139 
140  // Try other qcom nodes
141  for (nid = qcom_cNNid; qcom_NextNode(sts, &node, nid); nid = node.nid) {
142  if (str_NoCaseStrcmp(nodename, node.name) == 0) {
143  ctx->server = node.nid;
144  *sts = SEV__SUCCESS;
145  return 1;
146  }
147  }
148  *sts = SEV__NOSUCHNODE;
149  return 0;
150 }
151 
157  sevcli_sHistItem** list, unsigned int* cnt)
158 {
159  sev_sMsgAny* msg;
160  qcom_sQid tgt;
161  qcom_sPut put;
162  pwr_tStatus lsts;
163  int tmo = 10000;
164  qcom_sGet get;
165  sevcli_sHistItem* lp;
166  int i;
167 
168  if (ctx->server)
169  tgt.nid = ctx->server;
170  else
171  tgt.nid = ctx->qid.nid;
172  tgt.qix = sev_eProcSevServer;
173 
174  put.reply = ctx->qid;
175  put.type.b = (qcom_eBtype)sev_cMsgClass;
176  put.type.s = (qcom_eStype)sev_eMsgType_HistItemsRequest;
177  put.msg_id = ctx->msg_id++;
178  put.size = sizeof(*msg);
179  put.allocate = 0;
180  msg = (sev_sMsgAny*)qcom_Alloc(sts, put.size);
181 
182  put.data = msg;
183 
184  msg->Type = sev_eMsgType_HistItemsRequest;
185  msg->Version = sev_cNetVersion;
186 
187  if (!qcom_Put(sts, &tgt, &put)) {
188  qcom_Free(&lsts, put.data);
189  return 0;
190  }
191 
192  sev_sMsgHistItems* rmsg;
193 
194  memset(&get, 0, sizeof(get));
195 
196  for (;;) {
197  rmsg = (sev_sMsgHistItems*)qcom_Get(sts, &ctx->qid, &get, tmo);
198  if (*sts == QCOM__TMO || !rmsg) {
199  return 0;
200  }
201 
202  if (get.type.b == sev_cMsgClass
203  && get.type.s == (qcom_eStype)sev_eMsgType_HistItems)
204  break;
205 
206  qcom_Free(sts, rmsg);
207  }
208 
209  *sts = rmsg->Status;
210  if (EVEN(*sts))
211  return 0;
212 
213  // int item_cnt = (get.size - sizeof(sev_sMsgHistItems)) /
214  // sizeof(sev_sHistItem) + 1;
215  int item_cnt = rmsg->NumItems;
216  int attr_cnt = rmsg->NumAttributes;
217 
218  unsigned int data_size = (item_cnt * sizeof(sevcli_sHistItem))
219  + ((attr_cnt - item_cnt) * sizeof(sevcli_sHistAttr));
220  lp = (sevcli_sHistItem*)malloc(data_size);
221  sevcli_sHistItem* lp2 = lp;
222 
223  sev_sHistItem* itemPtr = ((sev_sMsgHistItems*)rmsg)->Items;
224  for (i = 0; i < item_cnt; i++) {
225  lp->oid = itemPtr->oid;
226  strncpy(lp->oname, itemPtr->oname, sizeof(lp->oname));
227  lp->storagetime = net_NetTimeToDeltaTime(&itemPtr->storagetime);
228  lp->deadband = itemPtr->deadband;
229  lp->options = itemPtr->options;
230  lp->creatime = net_NetTimeToTime(&itemPtr->creatime);
231  lp->modtime = net_NetTimeToTime(&itemPtr->modtime);
232  strncpy(lp->description, itemPtr->description, sizeof(lp->description));
233  str_Cut(lp->description, sizeof(lp->description));
234  lp->scantime = itemPtr->scantime;
235 
236  lp->attrnum = itemPtr->attrnum;
237  size_t j = 0;
238  for (j = 0; j < lp->attrnum; j++) {
239  lp->attr[j].type = itemPtr->attr[j].type;
240  lp->attr[j].size = itemPtr->attr[j].size;
241  strncpy(
242  lp->attr[j].aname, itemPtr->attr[j].aname, sizeof(lp->attr[0].aname));
243  strncpy(
244  lp->attr[j].unit, itemPtr->attr[j].unit, sizeof(lp->attr[0].unit));
245  }
246  itemPtr = (sev_sHistItem*)&itemPtr->attr[j];
247  lp = (sevcli_sHistItem*)&lp->attr[j];
248  }
249 
250  qcom_Free(sts, rmsg);
251 
252  *cnt = item_cnt;
253  *list = lp2;
254  *sts = SEV__SUCCESS;
255  return 1;
256 }
257 /*
258 int sevcli_get_itemlist( pwr_tStatus *sts, sevcli_tCtx ctx, sevcli_sHistItem
259 **list,
260  unsigned int *cnt)
261 {
262  sev_sMsgAny *msg;
263  qcom_sQid tgt;
264  qcom_sPut put;
265  pwr_tStatus lsts;
266  int tmo = 1000;
267  qcom_sGet get;
268  sevcli_sHistItem *lp;
269  int i;
270 
271  if ( ctx->server)
272  tgt.nid = ctx->server;
273  else
274  tgt.nid = ctx->qid.nid;
275  tgt.qix = sev_eProcSevServer;
276 
277 
278  put.reply = ctx->qid;
279  put.type.b = (qcom_eBtype) sev_cMsgClass;
280  put.type.s = (qcom_eStype) sev_eMsgType_HistItemsRequest;
281  put.msg_id = ctx->msg_id++;
282  put.size = sizeof(*msg);
283  put.allocate = 0;
284  msg = (sev_sMsgAny *) qcom_Alloc( sts, put.size);
285 
286  put.data = msg;
287 
288  msg->Type = sev_eMsgType_HistItemsRequest;
289  msg->Version = sev_cNetVersion;
290 
291  if ( !qcom_Put( sts, &tgt, &put)) {
292  qcom_Free( &lsts, put.data);
293  return 0;
294  }
295 
296  sev_sMsgHistItems *rmsg;
297 
298  memset( &get, 0, sizeof(get));
299 
300  for (;;) {
301  rmsg = (sev_sMsgHistItems *) qcom_Get( sts, &ctx->qid, &get, tmo);
302  if ( *sts == QCOM__TMO || !rmsg) {
303  return 0;
304  }
305 
306  if ( get.type.b == sev_cMsgClass &&
307  get.type.s == (qcom_eStype) sev_eMsgType_HistItems)
308  break;
309 
310  qcom_Free( sts, rmsg);
311  }
312 
313  *sts = rmsg->Status;
314  if ( EVEN(*sts))
315  return 0;
316 
317  int item_cnt = (get.size - sizeof(sev_sMsgHistItems)) / sizeof(sev_sHistItem)
318 + 1;
319 
320  lp = (sevcli_sHistItem *) calloc( item_cnt, sizeof(sevcli_sHistItem));
321 
322  for ( i = 0; i < item_cnt; i++) {
323  lp[i].oid = rmsg->Items[i].oid;
324  strncpy( lp[i].oname, rmsg->Items[i].oname, sizeof(lp[0].oname));
325  lp[i].storagetime = net_NetTimeToDeltaTime( &rmsg->Items[i].storagetime);
326  lp[i].deadband = rmsg->Items[i].deadband;
327  lp[i].options = rmsg->Items[i].options;
328  lp[i].creatime = net_NetTimeToTime( &rmsg->Items[i].creatime);
329  lp[i].modtime = net_NetTimeToTime( &rmsg->Items[i].modtime);
330  strncpy( lp[i].description, rmsg->Items[i].description,
331 sizeof(lp[0].description));
332  str_Cut(lp[i]->description, sizeof(lp[0]->description);
333  lp[i].scantime = rmsg->Items[i].scantime;
334  lp[i].attrnum = 1;
335  lp[i].attr[0].type = rmsg->Items[i].attr[0].type;
336  lp[i].attr[0].size = rmsg->Items[i].attr[0].size;
337  strncpy( lp[i].attr[0].aname, rmsg->Items[i].attr[0].aname,
338 sizeof(lp[0].attr[0].aname));
339  strncpy( lp[i].attr[0].unit, rmsg->Items[i].attr[0].unit,
340 sizeof(lp[0].attr[0].unit));
341  }
342 
343  qcom_Free( sts, rmsg);
344 
345  *cnt = item_cnt;
346  *list = lp;
347  *sts = SEV__SUCCESS;
348  return 1;
349 }
350 */
351 
358  char* aname, pwr_tTime starttime, pwr_tTime endtime, int numpoints,
359  pwr_tTime** tbuf, void** vbuf, int* rows, pwr_eType* vtype,
360  unsigned int* vsize)
361 {
362  sev_sMsgHistDataGetRequest* msg;
363  qcom_sQid tgt;
364  qcom_sPut put;
365  static int tmo = 0;
366  qcom_sGet get;
367  pwr_tStatus lsts;
368 
369  if (tmo == 0) {
370  int value;
371  char value_str[20];
372  int nr;
373 
374  if (cnf_get_value("sevTimeout", value_str, sizeof(value_str))) {
375  nr = sscanf(value_str, "%d", &value);
376  if (nr != 1)
377  tmo = 30000;
378  else
379  tmo = 1000 * value;
380  } else
381  tmo = 30000;
382  }
383 
384  if (ctx->server)
385  tgt.nid = ctx->server;
386  else
387  tgt.nid = ctx->qid.nid;
388  tgt.qix = sev_eProcSevServer;
389 
390  put.reply = ctx->qid;
391  put.type.b = (qcom_eBtype)sev_cMsgClass;
392  put.type.s = (qcom_eStype)sev_eMsgType_HistDataGetRequest;
393  put.msg_id = ctx->msg_id++;
394  put.size = sizeof(*msg);
395  put.allocate = 0;
396  msg = (sev_sMsgHistDataGetRequest*)qcom_Alloc(sts, put.size);
397 
398  put.data = msg;
399 
400  msg->Type = sev_eMsgType_HistDataGetRequest;
401  msg->Version = sev_cNetVersion;
402  msg->Oid = oid;
403  strncpy(msg->AName, aname, sizeof(msg->AName));
404  msg->StartTime = net_TimeToNetTime(&starttime);
405  msg->EndTime = net_TimeToNetTime(&endtime);
406  msg->NumPoints = numpoints;
407 
408  // Empty queue
409  sev_sMsgHistDataGet* rmsg;
410 
411  memset(&get, 0, sizeof(get));
412  for (;;) {
413  rmsg = (sev_sMsgHistDataGet*)qcom_Get(sts, &ctx->qid, &get, 0);
414 
415  if (!rmsg)
416  break;
417  qcom_Free(sts, rmsg);
418  }
419 
420  if (!qcom_Put(sts, &tgt, &put)) {
421  qcom_Free(&lsts, put.data);
422  return 0;
423  }
424 
425  memset(&get, 0, sizeof(get));
426 
427  for (;;) {
428  rmsg = (sev_sMsgHistDataGet*)qcom_Get(sts, &ctx->qid, &get, tmo);
429  if (*sts == QCOM__TMO || !rmsg) {
430  return 0;
431  }
432 
433  if (get.type.b == sev_cMsgClass
434  && get.type.s == (qcom_eStype)sev_eMsgType_HistDataGet
435  && cdh_ObjidIsEqual(oid, rmsg->Oid)
436  && str_NoCaseStrcmp(aname, rmsg->AName) == 0)
437  break;
438 
439  qcom_Free(sts, rmsg);
440  }
441 
442  *sts = rmsg->Status;
443  if (EVEN(*sts)) {
444  qcom_Free(&lsts, rmsg);
445  return 0;
446  }
447  if (rmsg->NumPoints == 0) {
448  qcom_Free(sts, rmsg);
449  *sts = SEV__NOPOINTS;
450  return 0;
451  }
452 
453  int item_cnt = rmsg->NumPoints;
454 
455  *tbuf = malloc(item_cnt * sizeof(pwr_tTime));
456  *vbuf = malloc(item_cnt * rmsg->VSize);
457 
458  memcpy(*tbuf, &rmsg->Data, item_cnt * sizeof(pwr_tTime));
459  memcpy(*vbuf, (char*)&rmsg->Data + item_cnt * sizeof(pwr_tTime),
460  item_cnt * rmsg->VSize);
461  *rows = item_cnt;
462  *vtype = rmsg->VType;
463  *vsize = rmsg->VSize;
464 
465  qcom_Free(&lsts, rmsg);
466 
467  *sts = SEV__SUCCESS;
468  return 1;
469 }
470 
477  char* aname, pwr_tTime starttime, pwr_tTime endtime, int numpoints,
478  pwr_tTime** tbuf, void** vbuf, int* rows, sevcli_sHistAttr** histattr,
479  int* numattributes)
480 {
481  sev_sMsgHistDataGetRequest* msg;
482  qcom_sQid tgt;
483  qcom_sPut put;
484  int tmo = 30000;
485  qcom_sGet get;
486  pwr_tStatus lsts;
487 
488  if (ctx->server)
489  tgt.nid = ctx->server;
490  else
491  tgt.nid = ctx->qid.nid;
492  tgt.qix = sev_eProcSevServer;
493 
494  put.reply = ctx->qid;
495  put.type.b = (qcom_eBtype)sev_cMsgClass;
496  put.type.s = (qcom_eStype)sev_eMsgType_HistObjectDataGetRequest;
497  put.msg_id = ctx->msg_id++;
498  put.size = sizeof(*msg);
499  put.allocate = 0;
500  msg = (sev_sMsgHistDataGetRequest*)qcom_Alloc(sts, put.size);
501 
502  put.data = msg;
503 
504  msg->Type = sev_eMsgType_HistObjectDataGetRequest;
505  msg->Version = sev_cNetVersion;
506  msg->Oid = oid;
507  strncpy(msg->AName, aname, sizeof(msg->AName));
508  msg->StartTime = net_TimeToNetTime(&starttime);
509  msg->EndTime = net_TimeToNetTime(&endtime);
510  msg->NumPoints = numpoints;
511 
512  // Empty queue
513  sev_sMsgHistObjectDataGet* rmsg;
514 
515  memset(&get, 0, sizeof(get));
516 
517  for (;;) {
518  rmsg = (sev_sMsgHistObjectDataGet*)qcom_Get(sts, &ctx->qid, &get, 0);
519  if (!rmsg)
520  break;
521  }
522 
523  if (!qcom_Put(sts, &tgt, &put)) {
524  qcom_Free(&lsts, put.data);
525  *sts = 0;
526  return 0;
527  }
528 
529  memset(&get, 0, sizeof(get));
530 
531  for (;;) {
532  rmsg = (sev_sMsgHistObjectDataGet*)qcom_Get(sts, &ctx->qid, &get, tmo);
533  if (*sts == QCOM__TMO || !rmsg) {
534  *sts = 0;
535  return 0;
536  }
537 
538  if (get.type.b == sev_cMsgClass
539  && get.type.s == (qcom_eStype)sev_eMsgType_HistObjectDataGet
540  && cdh_ObjidIsEqual(oid, rmsg->Oid)
541  && str_NoCaseStrcmp(aname, rmsg->AName) == 0)
542  break;
543 
544  qcom_Free(sts, rmsg);
545  }
546 
547  *sts = rmsg->Status;
548  if (EVEN(*sts)) {
549  qcom_Free(&lsts, rmsg);
550  return 0;
551  }
552  if (rmsg->NumPoints == 0) {
553  qcom_Free(sts, rmsg);
554  *sts = SEV__NOPOINTS;
555  return 0;
556  }
557 
558  *numattributes = rmsg->NumAttributes;
559  int item_cnt = rmsg->NumPoints;
560  unsigned int timebufsize = item_cnt * sizeof(pwr_tTime);
561  unsigned int databufsize = rmsg->TotalDataSize - timebufsize;
562  *tbuf = malloc(timebufsize);
563  *vbuf = malloc(databufsize);
564  sevcli_sHistAttr* attrptr;
565  attrptr = calloc(rmsg->NumAttributes, sizeof(sevcli_sHistAttr));
566 
567  int attrCount = rmsg->NumAttributes;
568  void* ptr = &rmsg->Attr[attrCount];
569  memcpy(*tbuf, ptr, item_cnt * sizeof(pwr_tTime));
570  memcpy(*vbuf, (char*)ptr + item_cnt * sizeof(pwr_tTime), databufsize);
571  *rows = item_cnt;
572 
573  int i = 0;
574  for (i = 0; i < rmsg->NumAttributes; i++) {
575  strncpy(attrptr[i].aname, rmsg->Attr[i].aname, sizeof(attrptr[0].aname));
576  attrptr[i].type = rmsg->Attr[i].type;
577  attrptr[i].size = rmsg->Attr[i].size;
578  }
579  *histattr = attrptr;
580 
581  qcom_Free(sts, rmsg);
582 
583  *sts = SEV__SUCCESS;
584  return 1;
585 }
586 
593  pwr_tStatus* sts, sevcli_tCtx ctx, pwr_tOid oid, char* aname)
594 {
595  sev_sMsgHistItemDelete* msg;
596  qcom_sQid tgt;
597  qcom_sPut put;
598  int tmo = 10000;
599  qcom_sGet get;
600  pwr_tStatus lsts;
601 
602  if (ctx->server)
603  tgt.nid = ctx->server;
604  else
605  tgt.nid = ctx->qid.nid;
606  tgt.qix = sev_eProcSevServer;
607 
608  put.reply = ctx->qid;
609  put.type.b = (qcom_eBtype)sev_cMsgClass;
610  put.type.s = (qcom_eStype)sev_eMsgType_HistItemDelete;
611  put.msg_id = ctx->msg_id++;
612  put.size = sizeof(*msg);
613  put.allocate = 0;
614  msg = (sev_sMsgHistItemDelete*)qcom_Alloc(sts, put.size);
615 
616  put.data = msg;
617 
618  msg->Type = sev_eMsgType_HistItemDelete;
619  msg->Version = sev_cNetVersion;
620  msg->Oid = oid;
621  strncpy(msg->AName, aname, sizeof(msg->AName));
622 
623  if (!qcom_Put(sts, &tgt, &put)) {
624  qcom_Free(&lsts, put.data);
625  return 0;
626  }
627 
628  sev_sMsgHistItemStatus* rmsg;
629 
630  memset(&get, 0, sizeof(get));
631 
632  for (;;) {
633  rmsg = (sev_sMsgHistItemStatus*)qcom_Get(sts, &ctx->qid, &get, tmo);
634  if (*sts == QCOM__TMO || !rmsg)
635  return 0;
636 
637  if (get.type.b == sev_cMsgClass
638  && get.type.s == (qcom_eStype)sev_eMsgType_HistItemStatus
639  && cdh_ObjidIsEqual(oid, rmsg->Oid)
640  && str_NoCaseStrcmp(aname, rmsg->AName) == 0)
641  break;
642 
643  qcom_Free(sts, rmsg);
644  }
645 
646  *sts = rmsg->Status;
647  if (EVEN(*sts))
648  return 0;
649  qcom_Free(sts, rmsg);
650  return 1;
651 }
652 
653 
659  sevcli_sEventsItem** list, unsigned int* cnt)
660 {
661  sev_sMsgAny* msg;
662  qcom_sQid tgt;
663  qcom_sPut put;
664  pwr_tStatus lsts;
665  int tmo = 10000;
666  qcom_sGet get;
667  sevcli_sEventsItem* lp;
668  int i;
669 
670  if (ctx->server)
671  tgt.nid = ctx->server;
672  else
673  tgt.nid = ctx->qid.nid;
674  tgt.qix = sev_eProcSevServer;
675 
676  put.reply = ctx->qid;
677  put.type.b = (qcom_eBtype)sev_cMsgClass;
678  put.type.s = (qcom_eStype)sev_eMsgType_EventsItemsRequest;
679  put.msg_id = ctx->msg_id++;
680  put.size = sizeof(*msg);
681  put.allocate = 0;
682  msg = (sev_sMsgAny*)qcom_Alloc(sts, put.size);
683 
684  put.data = msg;
685 
686  msg->Type = sev_eMsgType_EventsItemsRequest;
687  msg->Version = sev_cNetVersion;
688 
689  if (!qcom_Put(sts, &tgt, &put)) {
690  qcom_Free(&lsts, put.data);
691  return 0;
692  }
693 
694  sev_sMsgEventsItems* rmsg;
695 
696  memset(&get, 0, sizeof(get));
697 
698  for (;;) {
699  rmsg = (sev_sMsgEventsItems*)qcom_Get(sts, &ctx->qid, &get, tmo);
700  if (*sts == QCOM__TMO || !rmsg) {
701  return 0;
702  }
703 
704  if (get.type.b == sev_cMsgClass
705  && get.type.s == (qcom_eStype)sev_eMsgType_EventsItems)
706  break;
707 
708  qcom_Free(sts, rmsg);
709  }
710 
711  *sts = rmsg->Status;
712  if (EVEN(*sts))
713  return 0;
714 
715  int item_cnt = rmsg->NumItems;
716 
717  unsigned int data_size = (item_cnt * sizeof(sevcli_sEventsItem));
718  lp = (sevcli_sEventsItem*)malloc(data_size);
719  sevcli_sEventsItem* lp2 = lp;
720 
721  sev_sEventsItem* itemPtr = ((sev_sMsgEventsItems*)rmsg)->Items;
722  for (i = 0; i < item_cnt; i++) {
723  lp->oid = itemPtr->oid;
724  strncpy(lp->oname, itemPtr->oname, sizeof(lp->oname));
725  strncpy(lp->description, itemPtr->description, sizeof(lp->description));
726  str_Cut(lp->description, sizeof(lp->description));
727  lp->storagetime = net_NetTimeToDeltaTime(&itemPtr->storagetime);
728  lp->options = itemPtr->options;
729  lp->creatime = net_NetTimeToTime(&itemPtr->creatime);
730  itemPtr++;
731  lp++;
732  }
733 
734  qcom_Free(sts, rmsg);
735 
736  *cnt = item_cnt;
737  *list = lp2;
738  *sts = SEV__SUCCESS;
739  return 1;
740 }
741 
742 
749  pwr_tTime starttime, pwr_tTime endtime, pwr_tUInt32 eventtypemask,
750  pwr_tUInt32 eventpriomask, pwr_tString80 eventtext, pwr_tOName eventname,
751  unsigned int maxevents, sevcli_sEvents **list, unsigned int* cnt)
752 {
753  sev_sMsgEventsGetRequest* msg;
754  qcom_sQid tgt;
755  qcom_sPut put;
756  static int tmo = 0;
757  qcom_sGet get;
758  pwr_tStatus lsts;
759  sevcli_sEvents *lp;
760  sev_sEvents *ip;
761  int i;
762 
763  if (tmo == 0) {
764  int value;
765  char value_str[20];
766  int nr;
767 
768  if (cnf_get_value("sevTimeout", value_str, sizeof(value_str))) {
769  nr = sscanf(value_str, "%d", &value);
770  if (nr != 1)
771  tmo = 30000;
772  else
773  tmo = 1000 * value;
774  } else
775  tmo = 30000;
776  }
777 
778  if (ctx->server)
779  tgt.nid = ctx->server;
780  else
781  tgt.nid = ctx->qid.nid;
782  tgt.qix = sev_eProcSevServer;
783 
784  put.reply = ctx->qid;
785  put.type.b = (qcom_eBtype)sev_cMsgClass;
786  put.type.s = (qcom_eStype)sev_eMsgType_EventsGetRequest;
787  put.msg_id = ctx->msg_id++;
788  put.size = sizeof(*msg);
789  put.allocate = 0;
790  msg = (sev_sMsgEventsGetRequest*)qcom_Alloc(sts, put.size);
791 
792  put.data = msg;
793 
794  msg->Type = sev_eMsgType_EventsGetRequest;
795  msg->Version = sev_cNetVersion;
796  msg->Oid = oid;
797  msg->StartTime = net_TimeToNetTime(&starttime);
798  msg->EndTime = net_TimeToNetTime(&endtime);
799  msg->EventTypeMask = eventtypemask;
800  msg->EventPrioMask = eventpriomask;
801  strncpy(msg->EventText, eventtext, sizeof(msg->EventText));
802  strncpy(msg->EventName, eventname, sizeof(msg->EventName));
803  msg->MaxEvents = maxevents;
804 
805  // Empty queue
806  sev_sMsgEventsGet* rmsg;
807 
808  memset(&get, 0, sizeof(get));
809  for (;;) {
810  rmsg = (sev_sMsgEventsGet*)qcom_Get(sts, &ctx->qid, &get, 0);
811 
812  if (!rmsg)
813  break;
814  qcom_Free(sts, rmsg);
815  }
816 
817  if (!qcom_Put(sts, &tgt, &put)) {
818  qcom_Free(&lsts, put.data);
819  return 0;
820  }
821 
822  memset(&get, 0, sizeof(get));
823 
824  for (;;) {
825  rmsg = (sev_sMsgEventsGet*)qcom_Get(sts, &ctx->qid, &get, tmo);
826  if (*sts == QCOM__TMO || !rmsg) {
827  if (!rmsg)
828  *sts = 0;
829  return 0;
830  }
831 
832  if (get.type.b == sev_cMsgClass
833  && get.type.s == (qcom_eStype)sev_eMsgType_EventsGet
834  && cdh_ObjidIsEqual(oid, rmsg->Oid))
835  break;
836 
837  qcom_Free(sts, rmsg);
838  }
839 
840  *sts = rmsg->Status;
841  if (EVEN(*sts)) {
842  qcom_Free(&lsts, rmsg);
843  return 0;
844  }
845  if (rmsg->NumEvents == 0) {
846  qcom_Free(sts, rmsg);
847  *sts = SEV__NOPOINTS;
848  return 0;
849  }
850 
851  int item_cnt = rmsg->NumEvents;
852 
853  *list = calloc(item_cnt, sizeof(sevcli_sEventsItem));
854 
855  lp = *list;
856  ip = rmsg->Events;
857  for (i = 0; i < item_cnt; i++) {
858  lp->Time = net_NetTimeToTime(&ip->Time);
859  lp->EventType = ip->EventType;
860  lp->EventPrio = ip->EventPrio;
861  lp->SupObjectOid = ip->SupObjectOid;
862  lp->SupObjectOffset = ip->SupObjectOffset;
863  lp->SupObjectSize = ip->SupObjectSize;
864  strncpy(lp->EventText, ip->EventText, sizeof(lp->EventText));
865  strncpy(lp->EventName, ip->EventName, sizeof(lp->EventName));
866  lp->EventId = ip->EventId;
867  lp->EventStatus = ip->EventStatus;
868  lp++;
869  ip++;
870  }
871  *cnt = item_cnt;
872 
873  qcom_Free(&lsts, rmsg);
874 
875  *sts = SEV__SUCCESS;
876  return 1;
877 }
878 
883 {
884  stored_ctx = ctx;
885 }
886 
891 {
892  return stored_ctx;
893 }
894 
Include file for Cdh Class definition handler.
Include file for Time management.
int cdh_ObjidIsEqual(pwr_tOid Object_1, pwr_tOid Object_2)
Test if two object identities are equal.
Definition: co_cdh.c:89
pwr_tBoolean qcom_NextNode(pwr_tStatus *sts, qcom_sNode *node, pwr_tNodeId nid)
Get the next qcom node. If nid is pwr_cNNodeId the first node is returned.
Definition: rt_qcom.c:565
pwr_tBoolean qcom_MyNode(pwr_tStatus *sts, qcom_sNode *node)
Get the local qcom node.
Definition: rt_qcom.c:496
pwr_tBoolean qcom_Put(pwr_tStatus *sts, const qcom_sQid *receiver, qcom_sPut *put)
Put a new message.
Definition: rt_qcom.c:747
pwr_tBoolean qcom_CreateQ(pwr_tStatus *sts, qcom_sQid *myQ, qcom_sQattr *attr, const char *qname)
Create a queue and make an implicit connect to it.
Definition: rt_qcom.c:213
pwr_tBoolean qcom_Free(pwr_tStatus *sts, void *buffer)
Free a previously allocated buffer.
Definition: rt_qcom.c:355
void * qcom_Get(pwr_tStatus *sts, const qcom_sQid *myQ, qcom_sGet *get, int tmo_ms)
Get a new message.
Definition: rt_qcom.c:398
pwr_tBoolean qcom_DeleteQ(pwr_tStatus *sts, const qcom_sQid *myQ)
Delete a queue. Delete a queue and release all resources held by the queue.
Definition: rt_qcom.c:289
void * qcom_Alloc(pwr_tStatus *sts, unsigned int size)
Allocate a buffer in the qcom pool.
Definition: rt_qcom.c:85
int sevcli_get_itemdata(pwr_tStatus *sts, sevcli_tCtx ctx, pwr_tOid oid, char *aname, pwr_tTime starttime, pwr_tTime endtime, int numpoints, pwr_tTime **tbuf, void **vbuf, int *rows, pwr_eType *vtype, unsigned int *vsize)
Fetch stored historical data for an attribute.
Definition: rt_sevcli.c:357
int sevcli_get_events(pwr_tStatus *sts, sevcli_tCtx ctx, pwr_tOid oid, pwr_tTime starttime, pwr_tTime endtime, pwr_tUInt32 eventtypemask, pwr_tUInt32 eventpriomask, pwr_tString80 eventtext, pwr_tOName eventname, unsigned int maxevents, sevcli_sEvents **list, unsigned int *cnt)
Fetch stored historical events for an events item.
Definition: rt_sevcli.c:748
int sevcli_set_servernode(pwr_tStatus *sts, sevcli_tCtx ctx, char *nodename)
Set server from node name. This function is called to state which server node you want to communicate...
Definition: rt_sevcli.c:118
int sevcli_init(pwr_tStatus *sts, sevcli_tCtx *ctx)
Initialization of the client. Creates a context and opens a Qcom queue for the communication....
Definition: rt_sevcli.c:62
void sevcli_store_ctx(sevcli_tCtx ctx)
Store context.
Definition: rt_sevcli.c:882
int sevcli_delete_item(pwr_tStatus *sts, sevcli_tCtx ctx, pwr_tOid oid, char *aname)
Removes all data for a stored attribute in the storage database.
Definition: rt_sevcli.c:592
int sevcli_get_eventsitemlist(pwr_tStatus *sts, sevcli_tCtx ctx, sevcli_sEventsItem **list, unsigned int *cnt)
Fetches a list with the stored eventlists of the server.
Definition: rt_sevcli.c:658
int sevcli_close(pwr_tStatus *sts, sevcli_tCtx ctx)
Close the communication. Removes the Qcom queue and frees the context.
Definition: rt_sevcli.c:86
void sevcli_set_servernid(sevcli_tCtx ctx, pwr_tNid nid)
Set server from node id. This function is called to state which server node you want to communicate w...
Definition: rt_sevcli.c:105
sevcli_tCtx sevcli_get_stored_ctx(void)
Get stored context.
Definition: rt_sevcli.c:890
int sevcli_get_objectitemdata(pwr_tStatus *sts, sevcli_tCtx ctx, pwr_tOid oid, char *aname, pwr_tTime starttime, pwr_tTime endtime, int numpoints, pwr_tTime **tbuf, void **vbuf, int *rows, sevcli_sHistAttr **histattr, int *numattributes)
Fetch stored historical data for an object item.
Definition: rt_sevcli.c:476
int sevcli_get_itemlist(pwr_tStatus *sts, sevcli_tCtx ctx, sevcli_sHistItem **list, unsigned int *cnt)
Fetches a list with the stored attributes of the server.
Definition: rt_sevcli.c:156
#define EVEN(a)
Check if value is even.
Definition: pwr.h:627
unsigned int pwr_tUInt32
32-bit unsigned integer type.
Definition: pwr.h:233
char pwr_tString80[80]
80 byte string type.
Definition: pwr.h:416
int pwr_tStatus
Status type.
Definition: pwr.h:284
char pwr_tOName[199+1]
Full Object Name type.
Definition: pwr.h:396
pwr_tVolumeId pwr_tNid
Node identity type.
Definition: pwr.h:297
Include file for Sevcli SEV Client interface.
Object identity type.
Definition: pwr.h:263
Get data structure.
Definition: rt_qcom.h:185
Data for a Qcom node.
Definition: rt_qcom.h:219
pwr_tNodeId nid
node index
Definition: rt_qcom.h:220
char name[80]
node name
Definition: rt_qcom.h:222
Put data structure.
Definition: rt_qcom.h:174
Queue attributes.
Definition: rt_qcom.h:162
Queue identity.
Definition: rt_qcom.h:125
qcom_tQix qix
Definition: rt_qcom.h:126
pwr_tNodeId nid
Definition: rt_qcom.h:127
qcom_sQid qid
Definition: rt_sevcli.h:64
pwr_tNid server
Definition: rt_sevcli.h:65
unsigned int msg_id
Definition: rt_sevcli.h:66
unsigned int size
Definition: rt_sevcli.h:75
pwr_tAName aname
Definition: rt_sevcli.h:73
pwr_tString16 unit
Definition: rt_sevcli.h:77
pwr_eType type
Definition: rt_sevcli.h:74
pwr_tFloat32 scantime
Definition: rt_sevcli.h:90
pwr_tTime creatime
Definition: rt_sevcli.h:87
pwr_tAName oname
Definition: rt_sevcli.h:85
unsigned int attrnum
Definition: rt_sevcli.h:93
pwr_tString80 description
Definition: rt_sevcli.h:89
pwr_tDeltaTime storagetime
Definition: rt_sevcli.h:86
pwr_tMask options
Definition: rt_sevcli.h:92
sevcli_sHistAttr attr[1]
Definition: rt_sevcli.h:94
pwr_tOid oid
Definition: rt_sevcli.h:84
pwr_tTime modtime
Definition: rt_sevcli.h:88
pwr_tFloat32 deadband
Definition: rt_sevcli.h:91