Dawn Framework 1.0
Universal data acquisition framework for embedded systems
gateway.cxx
1// dawn/src/prog/gateway.cxx
2//
3// SPDX-License-Identifier: Apache-2.0
4//
5
6#include "dawn/prog/gateway.hxx"
7
8#include <new>
9
10#include "dawn/debug.hxx"
11#include "dawn/io/common.hxx"
12#include "dawn/io/ddata.hxx"
13#include "dawn/io/virt.hxx"
14
15using namespace dawn;
16
17void CProgGateway::io1SetCb(CIOVirt *io, void *priv)
18{
19 SGatewayBind *b = static_cast<SGatewayBind *>(priv);
20 int ret;
21
22 ret = io->getVal(b->iodata->getDataPtr(), b->iodata->getDataSize());
23 if (ret != OK)
24 {
25 DAWNERR("gateway io1SetCb getVal: %d\n", ret);
26 return;
27 }
28
29 b->vio2->setVal(b->iodata->getDataPtr(), b->iodata->getDataSize());
30}
31
32void CProgGateway::io2SetCb(CIOVirt *io, void *priv)
33{
34 SGatewayBind *b = static_cast<SGatewayBind *>(priv);
35 int ret;
36
37 ret = io->getVal(b->iodata->getDataPtr(), b->iodata->getDataSize());
38 if (ret != OK)
39 {
40 DAWNERR("gateway io2SetCb getVal: %d\n", ret);
41 return;
42 }
43
44 b->vio1->setVal(b->iodata->getDataPtr(), b->iodata->getDataSize());
45}
46
47void CProgGateway::io1GetCb(CIOVirt *io, void *priv)
48{
49 SGatewayBind *b = static_cast<SGatewayBind *>(priv);
50 int ret;
51
52 ret = b->vio2->getVal(b->iodata->getDataPtr(), b->iodata->getDataSize());
53 if (ret != OK)
54 {
55 DAWNERR("gateway io1GetCb getVal from io2: %d\n", ret);
56 return;
57 }
58
59 io->setVal(b->iodata->getDataPtr(), b->iodata->getDataSize());
60}
61
62void CProgGateway::io2GetCb(CIOVirt *io, void *priv)
63{
64 SGatewayBind *b = static_cast<SGatewayBind *>(priv);
65 int ret;
66
67 ret = b->vio1->getVal(b->iodata->getDataPtr(), b->iodata->getDataSize());
68 if (ret != OK)
69 {
70 DAWNERR("gateway io2GetCb getVal from io1: %d\n", ret);
71 return;
72 }
73
74 io->setVal(b->iodata->getDataPtr(), b->iodata->getDataSize());
75}
76
77int CProgGateway::configureDesc(const CDescObject &desc)
78{
79 const SObjectCfg::SObjectCfgItem *item = nullptr;
80 const SProgGatewayIOBind *tmp;
81 size_t offset = 0;
82 size_t nbinds;
83 size_t j;
84 int ret;
85
86 for (size_t i = 0; i < desc.getSize(); i++)
87 {
88 item = desc.objectCfgItemNext(offset);
89
91 {
92 DAWNERR("unsupported gateway cfg 0x%08" PRIx32 "\n", item->cfgid.v);
93 return -EINVAL;
94 }
95
96 switch (item->cfgid.s.id)
97 {
98 case PROG_GATEWAY_CFG_IOBIND:
99 {
100 if (item->cfgid.s.size == 0 ||
101 item->cfgid.s.size % (sizeof(SProgGatewayIOBind) / 4) != 0)
102 {
103 DAWNERR("invalid IOBIND size %d\n", item->cfgid.s.size);
104 return -EINVAL;
105 }
106
107 nbinds = item->cfgid.s.size / (sizeof(SProgGatewayIOBind) / 4);
108
109 tmp = reinterpret_cast<const SProgGatewayIOBind *>(item->data);
110
111 for (j = 0; j < nbinds; j++)
112 {
113 ret = allocObject(&tmp[j]);
114 if (ret != OK)
115 {
116 return ret;
117 }
118 }
119
120 break;
121 }
122
123 default:
124 {
125 DAWNERR("unsupported gateway cfg 0x%08" PRIx32 "\n", item->cfgid.v);
126 return -EINVAL;
127 }
128 }
129 }
130
131 return OK;
132}
133
134int CProgGateway::allocObject(const SProgGatewayIOBind *cfg)
135{
136 SGatewayBind *b;
137
138 if (cfg->dim == 0)
139 {
140 DAWNERR(
141 "gateway bind 0x%" PRIx32 " <-> 0x%" PRIx32 ": dim must be > 0\n", cfg->io1.v, cfg->io2.v);
142 return -EINVAL;
143 }
144
145 b = new (std::nothrow) SGatewayBind();
146 if (!b)
147 {
148 return -ENOMEM;
149 }
150
151 b->cfg = *cfg;
152 b->vio1 = nullptr;
153 b->vio2 = nullptr;
154 b->iodata = nullptr;
155
156 DAWNINFO("gateway bind 0x%" PRIx32 " <-> 0x%" PRIx32 " flags=0x%08" PRIx32 " dim=%" PRIu32 "\n",
157 b->cfg.io1.v,
158 b->cfg.io2.v,
159 b->cfg.flags,
160 b->cfg.dim);
161
162 setObjectMapItem(b->cfg.io1.v, nullptr);
163 setObjectMapItem(b->cfg.io2.v, nullptr);
164 binds.push_back(b);
165
166 return OK;
167}
168
169CProgGateway::~CProgGateway()
170{
171 deinit();
172}
173
175{
176 int ret;
177
178 ret = configureDesc(getDesc());
179 if (ret != OK)
180 {
181 DAWNERR("gateway configure failed: %d\n", ret);
182 return ret;
183 }
184
185 if (binds.empty())
186 {
187 DAWNERR("gateway: no IO bindings configured\n");
188 return -EINVAL;
189 }
190
191 return OK;
192}
193
195{
196 size_t i;
197
198 for (i = 0; i < binds.size(); i++)
199 {
200 delete binds[i]->iodata;
201 delete binds[i];
202 }
203
204 binds.clear();
205
206 return OK;
207}
208
210{
211 SGatewayBind *b;
212 size_t i;
213 int ret;
214
215 for (i = 0; i < binds.size(); i++)
216 {
217 b = binds[i];
218
219 b->vio1 = reinterpret_cast<CIOVirt *>(getIO(b->cfg.io1.v));
220 if (!b->vio1)
221 {
222 DAWNERR("gateway: io1[%zu] 0x%" PRIx32 " not found\n", i, b->cfg.io1.v);
223 return -EIO;
224 }
225
226 b->vio2 = reinterpret_cast<CIOVirt *>(getIO(b->cfg.io2.v));
227 if (!b->vio2)
228 {
229 DAWNERR("gateway: io2[%zu] 0x%" PRIx32 " not found\n", i, b->cfg.io2.v);
230 return -EIO;
231 }
232
233 ret = prepareWritableTarget(b->vio1, b->cfg.dim, false);
234 if (ret != OK)
235 {
236 DAWNERR("gateway: vio1[%zu] initialize failed: %d\n", i, ret);
237 return ret;
238 }
239
240 ret = prepareWritableTarget(b->vio2, b->cfg.dim, false);
241 if (ret != OK)
242 {
243 DAWNERR("gateway: vio2[%zu] initialize failed: %d\n", i, ret);
244 return ret;
245 }
246
247 b->iodata = b->vio1->ddata_alloc(1);
248 if (!b->iodata)
249 {
250 return -ENOMEM;
251 }
252 }
253
254 return OK;
255}
256
258{
259 SGatewayBind *b;
260 size_t i;
261 int ret;
262
263 for (i = 0; i < binds.size(); i++)
264 {
265 b = binds[i];
266
267 if (b->cfg.flags & FLAG_IO1_WRITE)
268 {
269 ret = b->vio1->setCallbackSet(io1SetCb, b);
270 if (ret != OK)
271 {
272 DAWNERR("gateway[%zu]: io1 set cb failed: %d\n", i, ret);
273 return ret;
274 }
275 }
276
277 if (b->cfg.flags & FLAG_IO2_WRITE)
278 {
279 ret = b->vio2->setCallbackSet(io2SetCb, b);
280 if (ret != OK)
281 {
282 DAWNERR("gateway[%zu]: io2 set cb failed: %d\n", i, ret);
283 return ret;
284 }
285 }
286
287 if (b->cfg.flags & FLAG_IO1_READ)
288 {
289 ret = b->vio1->setCallbackGet(io1GetCb, b);
290 if (ret != OK)
291 {
292 DAWNERR("gateway[%zu]: io1 get cb failed: %d\n", i, ret);
293 return ret;
294 }
295 }
296
297 if (b->cfg.flags & FLAG_IO2_READ)
298 {
299 ret = b->vio2->setCallbackGet(io2GetCb, b);
300 if (ret != OK)
301 {
302 DAWNERR("gateway[%zu]: io2 get cb failed: %d\n", i, ret);
303 return ret;
304 }
305 }
306 }
307
308 return OK;
309}
310
312{
313 SGatewayBind *b;
314 size_t i;
315 int ret;
316
317 for (i = 0; i < binds.size(); i++)
318 {
319 b = binds[i];
320
321 if (b->cfg.flags & FLAG_IO1_WRITE)
322 {
323 ret = b->vio1->setCallbackSet(nullptr, nullptr);
324 if (ret != OK)
325 {
326 DAWNERR("gateway[%zu]: io1 set cb clear failed: %d\n", i, ret);
327 return ret;
328 }
329 }
330
331 if (b->cfg.flags & FLAG_IO2_WRITE)
332 {
333 ret = b->vio2->setCallbackSet(nullptr, nullptr);
334 if (ret != OK)
335 {
336 DAWNERR("gateway[%zu]: io2 set cb clear failed: %d\n", i, ret);
337 return ret;
338 }
339 }
340
341 if (b->cfg.flags & FLAG_IO1_READ)
342 {
343 ret = b->vio1->setCallbackGet(nullptr, nullptr);
344 if (ret != OK)
345 {
346 DAWNERR("gateway[%zu]: io1 get cb clear failed: %d\n", i, ret);
347 return ret;
348 }
349 }
350
351 if (b->cfg.flags & FLAG_IO2_READ)
352 {
353 ret = b->vio2->setCallbackGet(nullptr, nullptr);
354 if (ret != OK)
355 {
356 DAWNERR("gateway[%zu]: io2 get cb clear failed: %d\n", i, ret);
357 return ret;
358 }
359 }
360 }
361
362 return OK;
363}
CIOCommon * getIO(SObjectId::ObjectId id)
Get an I/O object by ID.
Definition bindable.cxx:41
void setObjectMapItem(SObjectId::ObjectId id, CObject *obj)
Set an item in the object map.
Definition bindable.cxx:23
Descriptor wrapper for individual object configuration.
size_t getSize() const
Get number of configuration items for this object.
SObjectCfg::SObjectCfgItem * objectCfgItemNext(size_t &offset) const
Get config item at current offset and advance past it.
Virtual I/O type for user-provided data and callbacks.
Definition virt.hxx:26
CDescObject & getDesc()
Get descriptor object for this object.
Definition object.cxx:190
@ PROG_CLASS_GATEWAY
Protocol-to-protocol IO gateway.
Definition common.hxx:75
int init()
One-time initialize object after bindings are resolved.
Definition gateway.cxx:209
int configure()
Configure object from descriptor data.
Definition gateway.cxx:174
int deinit()
De-initialize object.
Definition gateway.cxx:194
@ FLAG_IO1_WRITE
io1 set callback: propagates to io2.
Definition gateway.hxx:42
@ FLAG_IO2_WRITE
io2 set callback: propagates to io1.
Definition gateway.hxx:44
@ FLAG_IO2_READ
io2 get callback: fetches from io1.
Definition gateway.hxx:43
@ FLAG_IO1_READ
io1 get callback: fetches from io2.
Definition gateway.hxx:41
int doStart()
Start implementation hook.
Definition gateway.cxx:257
int doStop()
Stop implementation hook.
Definition gateway.cxx:311
Out-of-tree user-extension hooks for Dawn.
Definition bindable.hxx:13
Single configuration item within object.
ObjectCfgData_t data[]
Configuration data array (flexible, size from cfgid.s.size).
UObjectCfgId cfgid
Configuration ID header (type, class, id, size, rw, dtype).
ObjectCfgId v
Raw 32-bit ConfigID value (for storage, comparison).
Definition objectcfg.hxx:82
uint32_t cls
Object class (bits 21-29, max 511).
uint32_t id
Configuration identifier (bits 0-4, max 31).
Definition objectcfg.hxx:94
uint32_t size
Configuration data size in 32-bit words (bits 5-14, max 1023).
struct dawn::SObjectCfg::UObjectCfgId::@10 s
Bit-field structure for named member access.