KM3NeT CLB  2.0
KM3NeT CLB v2 Embedded Software
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
monitor.c
1 /*
2  * KM3NeT CLB v2 Firmware
3  * ----------------------
4  *
5  * Copyright 2012-2014 KM3NeT Collaboration
6  *
7  * All Rights Reserved.
8  *
9  *
10  * File : monitor.c
11  * Created : 7 jul. 2014
12  * Author : Vincent van Beveren
13  */
14 
15 #include <errorcode.h>
16 #include <kernel/err.h>
17 #include <pv/access.h>
18 #include <pv/monitor.h>
19 #include <pv/varid.h>
20 #include <util/log.h>
21 
22 LOG_DEF(Monitor);
23 
24 #define _FREE_ENTRY 0
25 #define _UNDEFINED -1
26 
27 static int32_t _varIds[MON_MAX_VARS];
28 static uint8_t _rates[MON_MAX_VARS];
29 static int _varIdsMax = 0;
30 static int _firstFree = _UNDEFINED;
31 static int _blobSize = 2;
32 static int _varCount = 0;
33 
34 // find not only finds the variable, but also expands the list, such that the variable could be
35 // added.
36 static int find(int32_t varId)
37 {
38  int i;
39 
40  for (i = 0; i < _varIdsMax; ++i)
41  {
42  if (_varIds[i] == varId) return i;
43  if (_varIds[i] == _FREE_ENTRY && _firstFree == _UNDEFINED) _firstFree = i;
44  }
45  // expand to create space
46  if(_firstFree == _UNDEFINED && _varIdsMax < MON_MAX_VARS) {
47  _firstFree = _varIdsMax;
48  _varIdsMax++;
49  }
50  return _UNDEFINED;
51 }
52 
53 bool monSubscribeVar(int32_t varId, int rate)
54 {
55  logTrace("Subscribe variable %08x with rate %d", varId, rate);
56 
57  if (!vidIsReadable(varId)) return errSet(ERROR_CTX(E_INVARGUMENT));
58  if (!xsVarExists(varId)) return errSet(ERROR_CTX(E_NOTFOUND));
59 
60  int pos, s;
61  pos = find(varId);
62  if (pos == _UNDEFINED) {
63 
64  s = vidVarSize(varId) + 4;
65 
66  if (_firstFree != _UNDEFINED && ( _blobSize + s ) <= MON_MAX_BLOB) {
67  _varIds[_firstFree] = varId;
68  _rates[_firstFree] = rate;
69  _firstFree = _UNDEFINED;
70  _varCount ++;
71  _blobSize += s;
72  } else {
73  return errSet(ERROR_CTX(E_OUTOFMEMORY));
74  }
75  } else {
76  // maybe just a rate update?
77  _rates[pos] = rate;
78  }
79  return true;
80 }
81 
82 
83 bool monSubscribeVars(int32_t * varIds, int count, int rate)
84 {
85  int i;
86 
87  for (i = 0; i < count; ++i)
88  {
89  if (!monSubscribeVar(varIds[i], rate)) return false;
90  }
91  return true;
92 }
93 
94 
95 void monUnsubscribeVar(int32_t varId)
96 {
97  int pos;
98  pos = find(varId);
99  if (pos == _UNDEFINED) return;
100  _blobSize -= vidVarSize(varId) + 4;
101  _varIds[pos] = _FREE_ENTRY;
102  _varCount --;
103  if (_firstFree == _UNDEFINED || _firstFree > pos) _firstFree = pos;
104 }
105 
106 
107 void monUnsubscribe(int32_t * varIds, int count)
108 {
109  int i;
110  for (i = 0; i < count; ++i)
111  {
112  monUnsubscribeVar(varIds[i]);
113  }
114  // XXX compact array?
115 }
116 
117 
118 
119 int monUpdate(DataBuffer * buffer, int offset, int rate)
120 {
121  int i;
122 
123  logTrace("Configured rate: %d", rate);
124 
125  int varCount = 0;
126 
127  // okay, so we don't really know the count up-front.
128  uint8_t * tmp;
129  uint8_t * varCountPtr = buffer->cur;
130  if (!dbWriteU16(buffer, 0)) return -1;
131 
132  for (i = offset; i < _varIdsMax; ++i)
133  {
134  if (_varIds[i] == _FREE_ENTRY) continue;
135 
136  if (rate < _rates[i]) continue;
137 
138  logTrace("Variable %08x rate %d", _varIds[i], _rates[i]);
139 
140  int size = vidVarSize(_varIds[i]);
141 
142  if (dbFree(buffer) < 4 + size) {
143  tmp = buffer->cur;
144  buffer->cur = varCountPtr;
145  dbWriteU16(buffer, varCount);
146  buffer->cur = tmp;
147  return i;
148  }
149 
150  dbWriteI32(buffer, _varIds[i]);
151  varCount++;
152  if (!xsReadDB(_varIds[i], buffer)) return -1;
153  }
154  tmp = buffer->cur;
155  buffer->cur = varCountPtr;
156  dbWriteU16(buffer, varCount);
157  buffer->cur = tmp;
158 
159  return 0;
160 }
bool monSubscribeVars(int32_t *varIds, int count, int rate)
Subscribe to array of variables.
Definition: monitor.c:83
#define MON_MAX_VARS
Maximum number of variables which can be monitored.
Definition: monitor.h:37
bool dbWriteI32(DataBuffer *buf, int32_t i)
Writes an 32 bits signed integer.
Definition: databuffer.c:213
#define E_NOTFOUND
Generic error: not found (ID or resource.
Definition: errorcode.h:121
static int vidVarSize(int varID)
Returns the total size of the variable.
Definition: varid.h:132
bool xsVarExists(int varID)
Returns whether or not the specified variable exists.
Definition: access.c:139
Defines a DataBuffer structure.
Definition: databuffer.h:45
#define E_INVARGUMENT
Generic error: invalid argument.
Definition: errorcode.h:112
static uint32_t dbFree(DataBuffer *buf)
Returns the number of bytes still free in the buffer.
Definition: databuffer.h:95
bool monSubscribeVar(int32_t varId, int rate)
Subscribe to a variable.
Definition: monitor.c:53
void monUnsubscribeVar(int32_t varId)
Unsubscribe to a variable.
Definition: monitor.c:95
Manages the global system error.
bool xsReadDB(int varID, DataBuffer *target)
Reads variable into target data buffer from variable structure.
Definition: access.c:149
#define E_OUTOFMEMORY
Generic error: There is no more memory.
Definition: errorcode.h:107
This module is responsible for distributing error codes.
#define LOG_DEF(NAME,...)
Define a logger for a module.
Definition: log.h:129
int monUpdate(DataBuffer *buffer, int offset, int rate)
Write update variable information into the specified buffer.
Definition: monitor.c:119
The monitor module is responsible for sending variables to the remote party based on subscription...
#define MON_MAX_BLOB
Maximim blob size.
Definition: monitor.h:40
static bool vidIsReadable(int varID)
Checks if a variable is readable.
Definition: varid.h:145
bool errSet(uint32_t code, const char *error, const char *name)
Sets an error.
Implements a generic logger facility.
Access provides &#39;introspective&#39; access to process variables.
uint8_t * cur
Current Pointer.
Definition: databuffer.h:49
Defines the variable ID format.
bool dbWriteU16(DataBuffer *buf, uint16_t u)
Writes a unsigned short (16 bits unsigned) integer.
Definition: databuffer.c:162