source: UsbWattMeter/trunk/ecnl_lwip/echonet_agent.c@ 165

Last change on this file since 165 was 164, checked in by coas-nagasima, 8 years ago

TOPPERS/ECNLサンプルアプリ「USB充電器電力計」を追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc
File size: 26.6 KB
Line 
1/*
2 * TOPPERS ECHONET Lite Communication Middleware
3 *
4 * Copyright (C) 2015 Cores Co., Ltd. Japan
5 *
6 * ã‹L’˜ìŒ ŽÒ‚́CˆÈ‰º‚Ì(1)`(4)‚ÌðŒ‚ð–ž‚½‚·ê‡‚ÉŒÀ‚èC–{ƒ\ƒtƒgƒEƒF
7 * ƒAi–{ƒ\ƒtƒgƒEƒFƒA‚ð‰ü•Ï‚µ‚½‚à‚Ì‚ðŠÜ‚ށDˆÈ‰º“¯‚¶j‚ðŽg—pE•¡»E‰ü
8 * •ÏEÄ”z•ziˆÈ‰ºC—˜—p‚ƌĂԁj‚·‚邱‚Ƃ𖳏ž‚Å‹–‘ø‚·‚éD
9 * (1) –{ƒ\ƒtƒgƒEƒFƒA‚ðƒ\[ƒXƒR[ƒh‚ÌŒ`‚Å—˜—p‚·‚éê‡‚ɂ́Cã‹L‚Ì’˜ì
10 * Œ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L‚Ì–³•ÛØ‹K’肪C‚»‚Ì‚Ü‚Ü‚ÌŒ`‚Ń\[
11 * ƒXƒR[ƒh’†‚ÉŠÜ‚Ü‚ê‚Ä‚¢‚邱‚ƁD
12 * (2) –{ƒ\ƒtƒgƒEƒFƒA‚ðCƒ‰ƒCƒuƒ‰ƒŠŒ`Ž®‚ȂǁC‘¼‚̃\ƒtƒgƒEƒFƒAŠJ”­‚ÉŽg
13 * —p‚Å‚«‚éŒ`‚ōĔz•z‚·‚éê‡‚ɂ́CÄ”z•z‚É”º‚¤ƒhƒLƒ…
14ƒƒ“ƒgi—˜—p
15 * ŽÒƒ}ƒjƒ…
16ƒAƒ‹‚Ȃǁj‚ɁCã‹L‚Ì’˜ìŒ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L
17 * ‚Ì–³•ÛØ‹K’è‚ðŒfÚ‚·‚邱‚ƁD
18 * (3) –{ƒ\ƒtƒgƒEƒFƒA‚ðC‹@Ší‚É‘g‚ݍž‚ނȂǁC‘¼‚̃\ƒtƒgƒEƒFƒAŠJ”­‚ÉŽg
19 * —p‚Å‚«‚È‚¢Œ`‚ōĔz•z‚·‚éê‡‚ɂ́CŽŸ‚Ì‚¢‚¸‚ê‚©‚ÌðŒ‚ð–ž‚½‚·‚±
20 * ‚ƁD
21 * (a) Ä”z•z‚É”º‚¤ƒhƒLƒ…
22ƒƒ“ƒgi—˜—pŽÒƒ}ƒjƒ…
23ƒAƒ‹‚Ȃǁj‚ɁCã‹L‚Ì’˜
24 * ìŒ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L‚Ì–³•ÛØ‹K’è‚ðŒfÚ‚·‚邱‚ƁD
25 * (b) Ä”z•z‚ÌŒ`‘Ô‚ðC•Ê‚É’è‚ß‚é•û–@‚É‚æ‚Á‚āCTOPPERSƒvƒƒWƒFƒNƒg‚É
26 * •ñ‚·‚邱‚ƁD
27 * (4) –{ƒ\ƒtƒgƒEƒFƒA‚Ì—˜—p‚É‚æ‚è’¼Ú“I‚Ü‚½‚͊ԐړI‚ɐ¶‚¶‚é‚¢‚©‚Ȃ鑹
28 * ŠQ‚©‚ç‚àCã‹L’˜ìŒ ŽÒ‚¨‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚ð–Ɛӂ·‚邱‚ƁD
29 * ‚Ü‚½C–{ƒ\ƒtƒgƒEƒFƒA‚̃†[ƒU‚Ü‚½‚̓Gƒ“ƒhƒ†[ƒU‚©‚ç‚Ì‚¢‚©‚Ȃ闝
30 * —R‚ÉŠî‚­¿‹‚©‚ç‚àCã‹L’˜ìŒ ŽÒ‚¨‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚ð
31 * –Ɛӂ·‚邱‚ƁD
32 *
33 * –{ƒ\ƒtƒgƒEƒFƒA‚́C–³•ÛØ‚Å’ñ‹Ÿ‚³‚ê‚Ä‚¢‚é‚à‚Ì‚Å‚ ‚éDã‹L’˜ìŒ ŽÒ‚¨
34 * ‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚́C–{ƒ\ƒtƒgƒEƒFƒA‚ÉŠÖ‚µ‚āC“Á’è‚ÌŽg—p–Ú“I
35 * ‚ɑ΂·‚é“K‡«‚àŠÜ‚߂āC‚¢‚©‚È‚é•ÛØ‚às‚í‚È‚¢D‚Ü‚½C–{ƒ\ƒtƒgƒEƒF
36 * ƒA‚Ì—˜—p‚É‚æ‚è’¼Ú“I‚Ü‚½‚͊ԐړI‚ɐ¶‚¶‚½‚¢‚©‚Ȃ鑹ŠQ‚ÉŠÖ‚µ‚Ä‚àC‚»
37 * ‚̐ӔC‚𕉂í‚È‚¢D
38 *
39 * @(#) $Id: echonet_agent.c 164 2016-03-07 11:33:50Z coas-nagasima $
40 */
41
42/*
43 * ECHONET Lite “®“I¶¬ƒm[ƒh
44 */
45
46#include <kernel.h>
47#include <stdio.h>
48#include <stdlib.h>
49#include <stdarg.h>
50#include <string.h>
51#include <t_syslog.h>
52#include "echonet.h"
53#include "echonet_fbs.h"
54#include "echonet_agent.h"
55#include "echonet_task.h"
56#include "echonet_lcl_task.h"
57
58typedef struct ecn_agent_buffer
59{
60 union{
61 struct ecn_agent_buffer *free;
62 ecn_agent_queue_t queue;
63 };
64 union{
65 ecn_obj_t obj;
66 ecn_node_t node;
67 ecn_device_t device;
68 };
69} ecn_agent_buffer_t;
70
71typedef struct ecn_agent
72{
73 EPRPINIB eprpinib;
74 ecn_agent_queue_t nodes;
75 ecn_node_t *current_node;
76 bool_t msg_proced;
77 int blkpos;
78 ecn_agent_buffer_t *free;
79 ecn_agent_buffer_t blockes[TNUM_AEOBJID];
80 int requestid;
81} ecn_agent_t;
82
83static ER ecn_agent_proc_get_device_list(ecn_agent_t *agent, ECN_FBS_ID req);
84static ER ecn_agent_proc_get_device_info(ecn_agent_t *agent, ECN_FBS_ID req);
85static void ecn_node_send_set_prop_map(ecn_node_t *node);
86static void ecn_node_send_get_prop_map(ecn_node_t *node);
87static void ecn_node_send_anno_prop_map(ecn_node_t *node);
88static void ecn_node_timeout_on_start(ecn_node_t *node);
89static void ecn_node_next_proc_on_set_prpmap_wait(ecn_node_t *node, ecn_obj_t *sobj);
90static void ecn_node_timeout_on_set_prpmap_wait(ecn_node_t *node);
91static void ecn_node_next_proc_on_get_prpmap_wait(ecn_node_t *node, ecn_obj_t *sobj);
92static void ecn_node_timeout_on_get_prpmap_wait(ecn_node_t *node);
93static void ecn_node_next_proc_on_anno_prpmap_wait(ecn_node_t *node, ecn_obj_t *sobj);
94static void ecn_node_timeout_on_anno_prpmap_wait(ecn_node_t *node);
95
96int ecn_agent_eprpset(const EPRPINIB *item, const void *src, int size, bool_t *anno);
97int ecn_agent_eprpget(const EPRPINIB *item, void *dst, int size);
98
99static ecn_agent_queue_t *cast_queue(ecn_obj_t *obj)
100{
101 return (ecn_agent_queue_t *)((intptr_t)obj - offsetof(ecn_agent_buffer_t, obj));
102}
103
104static ecn_obj_t *cast_obj(ecn_agent_queue_t *queue)
105{
106 return (ecn_obj_t *)((intptr_t)queue + offsetof(ecn_agent_buffer_t, obj));
107}
108
109static ecn_node_t *cast_node(const EOBJCB *eobj)
110{
111 return (ecn_node_t *)((intptr_t)eobj - offsetof(ecn_node_t, eobj));
112}
113
114static ecn_obj_t *cast_obj2(const EOBJINIB *inib)
115{
116 return (ecn_obj_t *)((intptr_t)inib - offsetof(ecn_obj_t, inib));
117}
118
119static ecn_agent_t *cast_agent(const EPRPINIB *inib)
120{
121 return (ecn_agent_t *)((intptr_t)inib - offsetof(ecn_agent_t, eprpinib));
122}
123
124ecn_agent_t g_ecn_agent = {
125 /*eprpinib*/{
126 0x00,
127 EPC_RULE_SET | EPC_RULE_GET,
128 255,
129 (intptr_t)&g_ecn_agent,
130 ecn_agent_eprpset,
131 ecn_agent_eprpget
132 },
133};
134
135ER get_buf(ecn_agent_t *agent, ecn_agent_buffer_t **buf)
136{
137 ER ret = E_OK;
138
139 loc_cpu();
140
141 if (agent->blkpos < TNUM_AEOBJID) {
142 *buf = &agent->blockes[agent->blkpos++];
143 }
144 else if (agent->free == NULL) {
145 ret = E_TMOUT;
146 }
147 else{
148 *buf = agent->free;
149 agent->free = agent->free->free;
150 }
151
152 unl_cpu();
153
154 return ret;
155}
156
157ER rel_buf(ecn_agent_t *agent, ecn_agent_buffer_t *buf)
158{
159 if ((buf < &agent->blockes[0]) || (buf >= &agent->blockes[TNUM_AEOBJID]))
160 return E_PAR;
161
162 if ((((intptr_t)buf - (intptr_t)&agent->blockes[0]) % sizeof(ecn_agent_buffer_t)) != 0)
163 return E_PAR;
164
165 loc_cpu();
166
167 if (agent->free == NULL) {
168 agent->free = buf;
169 agent->free->free = NULL;
170 }
171 else {
172 ecn_agent_buffer_t *next = agent->free;
173 agent->free = buf;
174 agent->free->free = next;
175 }
176
177 unl_cpu();
178
179 return E_OK;
180}
181
182/*
183 * ƒLƒ…
184[‚̏‰Šú‰»
185 *
186 * p_queue‚ɂ̓Lƒ…
187[ƒwƒbƒ_‚ðŽw’è‚·‚éD
188 */
189Inline void
190ecn_agent_queue_init(ecn_agent_queue_t *p_queue)
191{
192#ifdef _DEBUG
193 p_queue->p_parent = p_queue;
194#endif
195 p_queue->p_prev = p_queue;
196 p_queue->p_next = p_queue;
197}
198
199/*
200 * ƒLƒ…
201[‚Ì‘OƒGƒ“ƒgƒŠ‚Ö‚Ì‘}“ü
202 *
203 * p_queue‚Ì‘O‚Ép_entry‚ð‘}“ü‚·‚éDp_queue‚ɃLƒ…
204[ƒwƒbƒ_‚ðŽw’肵‚½ê
205 * ‡‚ɂ́CƒLƒ…
206[‚Ì––”ö‚Ép_entry‚ð‘}“ü‚·‚邱‚Æ‚É‚È‚éD
207 */
208Inline void
209ecn_agent_queue_add(ecn_agent_queue_t *p_queue, ecn_agent_queue_t *p_entry)
210{
211#ifdef _DEBUG
212 assert((p_queue->p_parent == p_queue) && (p_entry->p_parent == NULL));
213 p_entry->p_parent = p_queue;
214#endif
215 p_entry->p_prev = p_queue->p_prev;
216 p_entry->p_next = p_queue;
217 p_queue->p_prev->p_next = p_entry;
218 p_queue->p_prev = p_entry;
219}
220
221/*
222 * ƒGƒ“ƒgƒŠ‚̍폜
223 *
224 * p_entry‚ðƒLƒ…
225[‚©‚çíœ‚·‚éD
226 */
227Inline void
228ecn_agent_queue_remove(ecn_agent_queue_t *p_queue, ecn_agent_queue_t *p_entry)
229{
230#ifdef _DEBUG
231 assert((p_queue->p_parent == p_queue) && (p_entry->p_parent == p_queue));
232 p_entry->p_parent = NULL;
233#endif
234 p_entry->p_prev->p_next = p_entry->p_next;
235 p_entry->p_next->p_prev = p_entry->p_prev;
236}
237
238ecn_node_t *ecn_agent_find_node(ECN_ENOD_ID enodid)
239{
240 ecn_agent_t *agent = &g_ecn_agent;
241 ecn_agent_queue_t *queue = agent->nodes.p_next;
242#ifdef _DEBUG
243 assert(queue->p_parent == &agent->nodes);
244#endif
245 for (; queue != &agent->nodes; queue = queue->p_next) {
246 ecn_node_t *node = (ecn_node_t *)cast_obj(queue);
247 if(node->enodId == enodid)
248 return node;
249 }
250
251 return NULL;
252}
253
254ecn_node_t *ecn_agent_find_node2(const EOBJCB *pk_eobj)
255{
256 ecn_agent_t *agent = &g_ecn_agent;
257 ecn_agent_queue_t *queue;
258
259 if(pk_eobj == NULL)
260 return NULL;
261
262 queue = agent->nodes.p_next;
263#ifdef _DEBUG
264 assert(queue->p_parent == &agent->nodes);
265#endif
266 for (; queue != &agent->nodes; queue = queue->p_next) {
267 ecn_node_t *node = (ecn_node_t *)cast_obj(queue);
268 if(&node->eobj == pk_eobj)
269 return node;
270 }
271
272 return NULL;
273}
274
275ecn_obj_t *ecn_agent_find_eobj(const EOBJCB *pk_nod, T_ECN_EOJ eoj)
276{
277 ecn_agent_queue_t *devices = &cast_node(pk_nod)->devices;
278 ecn_agent_queue_t *queue = devices->p_next;
279#ifdef _DEBUG
280 assert(queue->p_parent == devices);
281#endif
282 for (; queue != devices; queue = queue->p_next) {
283 ecn_obj_t *obj = cast_obj(queue);
284 if (obj->inib.eojx1 != eoj.eojx1)
285 continue;
286 if (obj->inib.eojx2 != eoj.eojx2)
287 continue;
288 if (obj->inib.eojx3 != eoj.eojx3)
289 continue;
290
291 return obj;
292 }
293
294 return NULL;
295}
296
297ecn_obj_t *ecn_agent_find_obj2(ecn_node_t *pk_nod, const EOBJINIB *pk_obj)
298{
299 ecn_agent_queue_t *devices = &pk_nod->devices;
300 ecn_agent_queue_t *queue = devices->p_next;
301#ifdef _DEBUG
302 assert(queue->p_parent == devices);
303#endif
304 for (; queue != devices; queue = queue->p_next) {
305 ecn_obj_t *obj = cast_obj(queue);
306 if (&obj->inib == pk_obj)
307 return obj;
308 }
309
310 return NULL;
311}
312
313ID ecn_agent_get_eobj(const EOBJINIB *pk_obj)
314{
315 return cast_obj2(pk_obj)->eobjId;
316}
317
318const EOBJINIB *ecn_agent_next_eobj(const EOBJCB *pk_nod, const EOBJINIB *pk_obj)
319{
320 ecn_agent_queue_t *devices = &cast_node(pk_nod)->devices;
321 ecn_obj_t *device = (ecn_obj_t *)pk_obj->exinf;
322 ecn_agent_queue_t *queue = cast_queue(device);
323#ifdef _DEBUG
324 assert(queue->p_parent == devices);
325#endif
326 if (queue == devices)
327 return NULL;
328
329 return &cast_obj(queue->p_next)->inib;
330}
331
332bool_t ecn_agent_get_eoj_enodid(ID eobjid, T_ECN_EOJ *eoj, ECN_ENOD_ID *enodid)
333{
334 ecn_agent_t *agent = &g_ecn_agent;
335 ecn_agent_buffer_t *buf;
336 int i = eobjid;
337
338 /* ƒIƒuƒWƒFƒNƒgID‚©‚çŽÀ‘Ì‚ðŽæ“¾ */
339 i -= (tmax_eobjid + 1);
340 if ((i < 0)
341 || (i >= (sizeof(agent->blockes) / sizeof(agent->blockes[0])))){
342 return false;
343 }
344
345 buf = &agent->blockes[i];
346 if(buf->obj.eobjId != eobjid)
347 return false;
348
349 /* ƒIƒuƒWƒFƒNƒg‚ÌEOJ‚ðƒRƒs[ */
350 memcpy(eoj, &buf->obj.inib.eojx1, sizeof(*eoj));
351
352 /* Š‘®‚·‚éƒm[ƒh‚̃IƒuƒWƒFƒNƒgID‚ðŽæ“¾ */
353 if(buf->obj.inib.enodid == 0)
354 i = buf->obj.eobjId;
355 else
356 i = buf->obj.inib.enodid;
357
358 i -= (tmax_eobjid + 1);
359 if ((i < 0)
360 || (i >= (sizeof(agent->blockes) / sizeof(agent->blockes[0])))){
361 return false;
362 }
363
364 /* ƒm[ƒhID‚ðŽæ“¾ */
365 buf = &agent->blockes[i];
366 *enodid = buf->node.enodId;
367
368 return true;
369}
370
371void ecn_agent_set_epc_to_prop_map(uint8_t epc, uint8_t *propMap)
372{
373 int i, j;
374 assert((epc & 0x80) != 0);
375 i = epc & 0xF;
376 j = (epc >> 4) - 8;
377 propMap[i] |= (1 << j);
378}
379
380bool_t ecn_agent_contains_epc_in_prop_map(uint8_t epc, uint8_t *propMap)
381{
382 int i, j;
383 assert((epc & 0x80) != 0);
384 i = epc & 0xF;
385 j = (epc >> 4) - 8;
386 return (propMap[i] & (1 << j)) != 0;
387}
388
389void ecn_agent_init(void)
390{
391 ecn_agent_queue_init(&g_ecn_agent.nodes);
392}
393
394ecn_node_t *ecn_agent_create_node(ecn_agent_t *agent, T_EDATA *esv)
395{
396 ecn_agent_buffer_t *result = NULL;
397 ecn_node_t *node;
398 uint8_t epc;
399 uint8_t pdc;
400 uint8_t edt[256];
401 T_ENUM_EPC enm;
402 ER ret;
403 T_ECN_EOJ *eoj, *end;
404
405 // ƒvƒƒpƒeƒB’Ê’m‚©Žæ“¾‰ž“š‚ŁA
406 switch (esv->hdr.edata.esv) {
407 case ESV_GET_RES:
408 case ESV_GET_SNA:
409 case ESV_INF:
410 break;
411 default:
412 return NULL;
413 }
414
415 // ƒm[ƒhƒvƒƒtƒ@ƒCƒ‹ˆ¶‚̏ꍇ
416 eoj = &esv->hdr.edata.seoj;
417 if ((eoj->eojx1 != EOJ_X1_PROFILE) || (eoj->eojx2 != EOJ_X2_NODE_PROFILE)
418 || (eoj->eojx3 != 0x01))
419 return NULL;
420
421 ret = ecn_itr_ini(&enm, esv);
422 if(ret != E_OK){
423 syslog(LOG_WARNING, "ecn_itr_ini");
424 }
425
426 while (ecn_itr_nxt(&enm, &epc, &pdc, &edt) == E_OK) {
427 switch (epc) {
428 // ƒCƒ“ƒXƒ^ƒ“ƒXƒŠƒXƒg’Ê’m‚̏ꍇ
429 case 0xD5:
430 // Ž©ƒm[ƒhƒCƒ“ƒXƒ^ƒ“ƒXƒŠƒXƒg‚r’Ê’m‚̏ꍇ
431 case 0xD6:
432 // ƒTƒCƒY‚ª‡‚í‚È‚¢ê‡
433 if (pdc != (1 + edt[0] * sizeof(T_ECN_EOJ)))
434 return NULL;
435
436 ret = get_buf(agent, &result);
437 if(ret != E_OK){
438 syslog(LOG_WARNING, "get_buf");
439 return NULL;
440 }
441
442 memset(result, 0, sizeof(*result));
443 node = &result->node;
444 node->enodId = ((T_ECN_FST_BLK *)esv)->hdr.sender.id;
445 node->base.eobjId = tmax_eobjid + 1 + (((intptr_t)result - (intptr_t)agent->blockes) / sizeof(agent->blockes[0]));
446 node->base.inib.enodid = 0;
447 node->base.inib.eobjatr = EOBJ_SYNC_REMOTE_NODE;
448 node->base.inib.exinf = (intptr_t)node;
449 node->base.inib.eojx1 = eoj->eojx1;
450 node->base.inib.eojx2 = eoj->eojx2;
451 node->base.inib.eojx3 = eoj->eojx3;
452 node->base.inib.eprp = &agent->eprpinib;
453 node->base.inib.eprpcnt = 0;
454 ecn_agent_set_epc_to_prop_map(0xD5, node->base.pmapGet);
455 ecn_agent_set_epc_to_prop_map(0xD6, node->base.pmapGet);
456 ecn_agent_set_epc_to_prop_map(0x9D, node->base.pmapGet);
457 ecn_agent_set_epc_to_prop_map(0x9E, node->base.pmapGet);
458 ecn_agent_set_epc_to_prop_map(0x9F, node->base.pmapGet);
459 ecn_agent_queue_init(&node->devices);
460 node->eobj.profile = &node->base.inib;
461 node->eobj.eobjs = NULL;
462 node->eobj.eobjcnt = pdc / 3;
463 node->state = ecn_node_state_idle;
464 node->timer = TMO_FEVR;
465
466 end = (T_ECN_EOJ *)&edt[pdc];
467 for (eoj = (T_ECN_EOJ *)&edt[1]; eoj < end; eoj++) {
468 ecn_device_t *device;
469 ecn_agent_buffer_t *obj;
470
471 ret = get_buf(agent, &obj);
472 if(ret != E_OK){
473 syslog(LOG_WARNING, "get_buf");
474 return NULL;
475 }
476
477 memset(obj, 0, sizeof(*obj));
478 device = &obj->device;
479 device->node = node;
480 device->base.eobjId = tmax_eobjid + 1 + (((intptr_t)obj - (intptr_t)agent->blockes) / sizeof(agent->blockes[0]));
481 device->base.inib.eobjatr = EOBJ_DEVICE;
482 device->base.inib.enodid = node->base.eobjId;
483 device->base.inib.exinf = (intptr_t)device;
484 device->base.inib.eojx1 = eoj->eojx1;
485 device->base.inib.eojx2 = eoj->eojx2;
486 device->base.inib.eojx3 = eoj->eojx3;
487 device->base.inib.eprp = &agent->eprpinib;
488 device->base.inib.eprpcnt = 0;
489 ecn_agent_set_epc_to_prop_map(0x9D, device->base.pmapGet);
490 ecn_agent_set_epc_to_prop_map(0x9E, device->base.pmapGet);
491 ecn_agent_set_epc_to_prop_map(0x9F, device->base.pmapGet);
492
493 ecn_agent_queue_add(&node->devices, &obj->queue);
494 }
495 break;
496 default:
497 continue;
498 }
499 break;
500 }
501
502 if (result == NULL)
503 return NULL;
504
505 ecn_agent_queue_add(&agent->nodes, &result->queue);
506
507 return node;
508}
509
510static ER ecn_agent_proc_get_device_list(ecn_agent_t *agent, ECN_FBS_ID req)
511{
512 ER ret;
513 ECN_FBS_ID res;
514 ecn_inm_get_device_list_req_t msg;
515 ECN_FBS_SSIZE_T len;
516 ecn_agent_buffer_t *pos, *end = &agent->blockes[TNUM_AEOBJID];
517 ecn_inm_get_device_item_t item;
518
519 ret = _ecn_fbs_get_data(req, &msg, sizeof(msg), &len);
520 if (ret != E_OK) {
521 return ret;
522 }
523
524 ret = _ecn_tsk_cre_res_fbs(req, ECN_INM_GET_DEVICE_LIST_RES, &res);
525 if (ret != E_OK) {
526 return ret;
527 }
528
529 ret = _ecn_fbs_add_data_ex(res, &msg.requestid, sizeof(((ecn_inm_get_device_list_res_t *)0)->requestid));
530 if (ret != E_OK) {
531 _ecn_fbs_del(res);
532 return ret;
533 }
534
535 for (pos = &agent->blockes[0]; pos < end; pos++){
536 if(pos->obj.eobjId == 0)
537 continue;
538
539 item.eobjid = pos->obj.eobjId;
540 item.enodid = pos->obj.inib.enodid;
541 item.eojx1 = pos->obj.inib.eojx1;
542 item.eojx2 = pos->obj.inib.eojx2;
543 item.eojx3 = pos->obj.inib.eojx3;
544
545 if(pos->device.node != NULL)
546 item.addrid = pos->device.node->enodId;
547 else
548 item.addrid = pos->node.enodId;
549
550 ret = _ecn_fbs_add_data_ex(res, &item, sizeof(item));
551 if (ret != E_OK) {
552 _ecn_fbs_del(res);
553 return ret;
554 }
555 }
556
557 ret = psnd_dtq(res.ptr->hdr.target.mbxid, (intptr_t)res.ptr);
558 if (ret != E_OK) {
559 _ecn_fbs_del(res);
560 return ret;
561 }
562
563 return E_OK;
564}
565
566static ER ecn_agent_proc_get_device_info(ecn_agent_t *agent, ECN_FBS_ID req)
567{
568 ER ret;
569 ECN_FBS_ID res;
570 ecn_inm_get_device_info_req_t msg;
571 ecn_inm_get_device_info_res_t rmsg;
572 ECN_FBS_SSIZE_T len;
573 int eobjId;
574 ecn_agent_buffer_t *pos;
575
576 ret = _ecn_fbs_get_data(req, &msg, sizeof(msg), &len);
577 if (ret != E_OK) {
578 return ret;
579 }
580
581 eobjId = msg.eobjid - tmax_eobjid - 1;
582 pos = &agent->blockes[eobjId];
583
584 ret = _ecn_tsk_cre_res_fbs(req, ECN_INM_GET_DEVICE_INFO_RES, &res);
585 if (ret != E_OK) {
586 return ret;
587 }
588
589 rmsg.requestid = msg.requestid;
590 rmsg.eobjid = pos->obj.eobjId;
591 memcpy(rmsg.pmapSet, pos->obj.pmapSet, sizeof(rmsg.pmapSet));
592 memcpy(rmsg.pmapGet, pos->obj.pmapGet, sizeof(rmsg.pmapGet));
593 memcpy(rmsg.pmapAnno, pos->obj.pmapAnno, sizeof(rmsg.pmapAnno));
594 rmsg.eprpcnt = pos->obj.eprpcnt;
595
596 ret = _ecn_fbs_add_data_ex(res, &rmsg, sizeof(rmsg));
597 if (ret != E_OK) {
598 _ecn_fbs_del(res);
599 return ret;
600 }
601
602 ret = psnd_dtq(res.ptr->hdr.target.mbxid, (intptr_t)res.ptr);
603 if (ret != E_OK) {
604 _ecn_fbs_del(res);
605 return ret;
606 }
607
608 return E_OK;
609}
610
611TMO ecn_agent_get_timer()
612{
613 TMO timer = TMO_FEVR, temp;
614 ecn_agent_t *agent = &g_ecn_agent;
615 ecn_node_t *node;
616 ecn_agent_queue_t *queue;
617
618 queue = &agent->nodes;
619 for (;;) {
620 queue = queue->p_next;
621#ifdef _DEBUG
622 assert(queue->p_parent == &agent->nodes);
623#endif
624 if(&agent->nodes == queue)
625 break;
626
627 node = (ecn_node_t *)cast_obj(queue);
628 temp = node->timer;
629 if (temp != TMO_FEVR) {
630 if ((timer == TMO_FEVR) || (temp < timer)) {
631 timer = temp;
632 }
633 }
634 }
635
636 return timer;
637}
638
639void ecn_agent_progress(TMO interval)
640{
641 ecn_agent_t *agent = &g_ecn_agent;
642 ecn_node_t *node;
643 ecn_agent_queue_t *queue;
644
645 queue = &agent->nodes;
646 for (;;) {
647 queue = queue->p_next;
648#ifdef _DEBUG
649 assert(queue->p_parent == &agent->nodes);
650#endif
651 if(&agent->nodes == queue)
652 break;
653
654 node = (ecn_node_t *)cast_obj(queue);
655 if (node->timer == TMO_FEVR)
656 continue;
657
658 node->timer -= interval;
659 if (node->timer <= 0) {
660 node->timer = 0;
661 }
662 }
663}
664
665void ecn_agent_timeout()
666{
667 ecn_agent_t *agent = &g_ecn_agent;
668 ecn_node_t *node;
669 ecn_agent_queue_t *queue;
670
671 queue = &agent->nodes;
672 for (;;) {
673 queue = queue->p_next;
674#ifdef _DEBUG
675 assert(queue->p_parent == &agent->nodes);
676#endif
677 if(&agent->nodes == queue)
678 break;
679
680 node = (ecn_node_t *)cast_obj(queue);
681 if (node->timer != 0)
682 continue;
683
684 switch (node->state) {
685 case ecn_node_state_start:
686 ecn_node_timeout_on_start(node);
687 break;
688 case ecn_node_state_set_prpmap_wait:
689 ecn_node_timeout_on_set_prpmap_wait(node);
690 break;
691 case ecn_node_state_get_prpmap_wait:
692 ecn_node_timeout_on_get_prpmap_wait(node);
693 break;
694 case ecn_node_state_anno_prpmap_wait:
695 ecn_node_timeout_on_anno_prpmap_wait(node);
696 break;
697 default:
698 assert(0);
699 }
700 }
701}
702
703bool_t ecn_agent_proc_int_msg(ECN_FBS_ID fbs, uint8_t cmd)
704{
705 ecn_agent_t *agent = &g_ecn_agent;
706
707 switch(cmd)
708 {
709 case ECN_INM_GET_DEVICE_LIST_REQ:
710 ecn_agent_proc_get_device_list(agent, fbs);
711 break;
712 case ECN_INM_GET_DEVICE_INFO_REQ:
713 ecn_agent_proc_get_device_info(agent, fbs);
714 break;
715 default:
716 return false;
717 }
718
719 return true;
720}
721
722void ecn_agent_proc_ecn_msg(const EOBJCB **ppk_snod, const EOBJINIB **ppk_sobj, T_EDATA *esv)
723{
724 ecn_agent_t *agent = &g_ecn_agent;
725 ecn_node_t *snod;
726 ecn_obj_t *sobj;
727
728 /* Ã“I‚É’è‹`‚³‚ꂽ‘—MŒ³‚̏ꍇ */
729 if ((*ppk_snod != NULL) && (*ppk_snod)->eobjs != NULL) {
730 /* ˆ—‚µ‚È‚¢ */
731 return;
732 }
733
734 snod = ecn_agent_find_node2(*ppk_snod);
735
736 /* ‘—MŒ³‚ð’m‚ç‚È‚©‚Á‚½‚ç */
737 if (snod == NULL) {
738 /* ‘—MŒ³‚̃m[ƒhî•ñ‚ðV‹K‚ɍ쐬 */
739 snod = ecn_agent_create_node(agent, esv);
740 if (snod == NULL)
741 return;
742 }
743
744 sobj = ecn_agent_find_obj2(snod, *ppk_sobj);
745
746 /* ƒm[ƒhƒvƒƒtƒ@ƒCƒ‹‚̏ꍇ */
747 if ((esv->hdr.edata.seoj.eojx1 == EOJ_X1_PROFILE)
748 && (esv->hdr.edata.seoj.eojx2 == EOJ_X2_NODE_PROFILE)) {
749 sobj = &snod->base;
750 }
751 /* ‹@ŠíƒIƒuƒWƒFƒNƒg‚̏ꍇ */
752 else {
753 sobj = ecn_agent_find_eobj(&snod->eobj, esv->hdr.edata.seoj);
754 }
755
756 *ppk_snod = &snod->eobj;
757 *ppk_sobj = &sobj->inib;
758
759 agent->current_node = snod;
760 agent->msg_proced = false;
761}
762
763void ecn_agent_proc_ecn_msg_end()
764{
765 ecn_agent_t *agent = &g_ecn_agent;
766 ecn_node_t *node = agent->current_node;
767 ecn_obj_t *sobj;
768
769 if(node == NULL)
770 return;
771
772 sobj = node->current;
773 if(sobj == NULL)
774 return;
775
776 if (agent->msg_proced) {
777 switch (node->state) {
778 case ecn_node_state_set_prpmap_wait:
779 ecn_node_next_proc_on_set_prpmap_wait(node, sobj);
780 break;
781 case ecn_node_state_get_prpmap_wait:
782 ecn_node_next_proc_on_get_prpmap_wait(node, sobj);
783 break;
784 case ecn_node_state_anno_prpmap_wait:
785 ecn_node_next_proc_on_anno_prpmap_wait(node, sobj);
786 break;
787 }
788 }
789}
790
791static void ecn_node_send_set_prop_map(ecn_node_t *node)
792{
793 T_EDATA *esv;
794 ecn_obj_t *obj = node->current;
795
796 // ƒvƒƒpƒeƒB’l“ǂݏo‚µ—v‹
797 ecn_esv_get(&esv, obj->eobjId, 0x9E);
798 ecn_snd_esv(esv);
799
800 node->state = ecn_node_state_set_prpmap_wait;
801 node->timer = (TMO)5000;
802}
803
804static void ecn_node_send_get_prop_map(ecn_node_t *node)
805{
806 T_EDATA *esv;
807 ecn_obj_t *obj = node->current;
808
809 // ƒvƒƒpƒeƒB’l“ǂݏo‚µ—v‹
810 ecn_esv_get(&esv, obj->eobjId, 0x9F);
811 ecn_snd_esv(esv);
812
813 node->state = ecn_node_state_get_prpmap_wait;
814 node->timer = (TMO)5000;
815}
816
817static void ecn_node_send_anno_prop_map(ecn_node_t *node)
818{
819 T_EDATA *esv;
820 ecn_obj_t *obj = node->current;
821
822 // ƒvƒƒpƒeƒB’l“ǂݏo‚µ—v‹
823 ecn_esv_get(&esv, obj->eobjId, 0x9D);
824 ecn_snd_esv(esv);
825
826 node->state = ecn_node_state_anno_prpmap_wait;
827 node->timer = (TMO)5000;
828}
829
830static void ecn_node_next_obj(ecn_node_t *node)
831{
832 ecn_obj_t *obj = node->current;
833 ecn_agent_queue_t *queue;
834 ecn_device_t *device;
835
836 /* obj‚ªŽw’肳‚ê‚Ä‚¢‚È‚¢ê‡ */
837 if(obj == NULL){
838 /* ‚±‚̃m[ƒh‚ð•Ô‚· */
839 node->current = &node->base;
840 return;
841 }
842 /* ƒm[ƒh‚̏ꍇ */
843 else if((obj->inib.eojx1 == EOJ_X1_PROFILE) && (obj->inib.eojx2 == EOJ_X2_NODE_PROFILE)){
844 node = (ecn_node_t *)obj;
845
846 /* ”z‰º‚Ì‹@Ší‚ð•Ô‚· */
847 queue = node->devices.p_next;
848 device = (ecn_device_t *)cast_obj(queue);
849 }
850 /* ‹@Ší‚̏ꍇ */
851 else{
852 /* ŽŸ‚Ì‹@Ší‚ð•Ô‚· */
853 node = ((ecn_device_t *)obj)->node;
854 queue = cast_queue(obj)->p_next;
855 device = (ecn_device_t *)cast_obj(queue);
856 }
857
858 /* ‚»‚Ì‹@Ší‚ª––”ö‚¾‚Á‚½ê‡ */
859 if(&node->devices == queue){
860 node->current = NULL;
861 }
862 else {
863 node->current = &device->base;
864 }
865}
866
867static void ecn_node_timeout_on_start(ecn_node_t *node)
868{
869 for (;;) {
870 ecn_obj_t *obj = node->current;
871 if (obj == NULL) {
872 node->state = ecn_node_state_idle;
873 node->timer = TMO_FEVR;
874 return;
875 }
876
877 if((obj->pmapFlag & PMAP_FLAG_SET) == 0){
878 ecn_node_send_set_prop_map(node);
879 break;
880 }
881 else if((obj->pmapFlag & PMAP_FLAG_GET) == 0){
882 ecn_node_send_get_prop_map(node);
883 break;
884 }
885 else if((obj->pmapFlag & PMAP_FLAG_ANNO) == 0){
886 ecn_node_send_anno_prop_map(node);
887 break;
888 }
889 else{
890 ecn_node_next_obj(node);
891 }
892 }
893}
894
895static void ecn_node_next_proc_on_set_prpmap_wait(ecn_node_t *node, ecn_obj_t *sobj)
896{
897 if((sobj->pmapFlag & PMAP_FLAG_GET) == 0){
898 ecn_node_send_get_prop_map(node);
899 }
900 else if((sobj->pmapFlag & PMAP_FLAG_ANNO) == 0){
901 ecn_node_send_anno_prop_map(node);
902 }
903 else if((sobj->pmapFlag & PMAP_FLAG_SET) == 0){
904 ecn_node_send_set_prop_map(node);
905 }
906 else{
907 ecn_node_next_obj(node);
908 ecn_node_timeout_on_start(node);
909 }
910}
911
912static void ecn_node_timeout_on_set_prpmap_wait(ecn_node_t *node)
913{
914 ecn_obj_t *obj = node->current;
915 if(obj == NULL){
916 node->state = ecn_node_state_idle;
917 node->timer = TMO_FEVR;
918 return;
919 }
920
921 ecn_node_next_proc_on_set_prpmap_wait(node, obj);
922}
923
924static void ecn_node_next_proc_on_get_prpmap_wait(ecn_node_t *node, ecn_obj_t *sobj)
925{
926 if((sobj->pmapFlag & PMAP_FLAG_ANNO) == 0){
927 ecn_node_send_anno_prop_map(node);
928 }
929 else if((sobj->pmapFlag & PMAP_FLAG_SET) == 0){
930 ecn_node_send_set_prop_map(node);
931 }
932 else if((sobj->pmapFlag & PMAP_FLAG_GET) == 0){
933 ecn_node_send_get_prop_map(node);
934 }
935 else{
936 ecn_node_next_obj(node);
937 ecn_node_timeout_on_start(node);
938 }
939}
940
941static void ecn_node_timeout_on_get_prpmap_wait(ecn_node_t *node)
942{
943 ecn_obj_t *obj = node->current;
944 if(obj == NULL){
945 node->state = ecn_node_state_idle;
946 node->timer = TMO_FEVR;
947 return;
948 }
949
950 ecn_node_next_proc_on_get_prpmap_wait(node, obj);
951}
952
953static void ecn_node_next_proc_on_anno_prpmap_wait(ecn_node_t *node, ecn_obj_t *sobj)
954{
955 if((sobj->pmapFlag & PMAP_FLAG_SET) == 0){
956 ecn_node_send_set_prop_map(node);
957 }
958 else if((sobj->pmapFlag & PMAP_FLAG_GET) == 0){
959 ecn_node_send_get_prop_map(node);
960 }
961 else if((sobj->pmapFlag & PMAP_FLAG_ANNO) == 0){
962 ecn_node_send_anno_prop_map(node);
963 }
964 else{
965 ecn_node_next_obj(node);
966 ecn_node_timeout_on_start(node);
967 }
968}
969
970static void ecn_node_timeout_on_anno_prpmap_wait(ecn_node_t *node)
971{
972 ecn_obj_t *obj = node->current;
973 if(obj == NULL){
974 node->state = ecn_node_state_idle;
975 node->timer = TMO_FEVR;
976 return;
977 }
978
979 ecn_node_next_proc_on_anno_prpmap_wait(node, obj);
980}
981
982const EPRPINIB *ecn_agent_get_property(const EOBJINIB *fp_obj, uint8_t fa_epc, const EPRPINIB *item)
983{
984 ecn_obj_t *obj = cast_obj2(fp_obj);
985 bool_t has = false;
986
987 /* ƒm[ƒh‚̏ꍇ‚̓Cƒ“ƒXƒ^ƒ“ƒXƒŠƒXƒg’Ê’m‚ÆŽ©ƒm[ƒhƒCƒ“ƒXƒ^ƒ“ƒXƒŠƒXƒg‚r’Ê’m‚ð•K{‚Ŏ󂯎æ‚é */
988 if ((fp_obj->enodid == 0) && ((fa_epc == 0xD5) || (fa_epc == 0xD6)))
989 has = true;
990 else if (ecn_agent_contains_epc_in_prop_map(fa_epc, obj->pmapGet))
991 has = true;
992 else if (ecn_agent_contains_epc_in_prop_map(fa_epc, obj->pmapSet))
993 has = true;
994 else if (ecn_agent_contains_epc_in_prop_map(fa_epc, obj->pmapAnno))
995 has = true;
996
997 if(!has)
998 return NULL;
999
1000 ((EPRPINIB *)item)->eprpcd = fa_epc;
1001 ((EPRPINIB *)item)->exinf = (intptr_t)fp_obj;
1002
1003 return item;
1004}
1005
1006int ecn_agent_eprpget(const EPRPINIB *item, void *dst, int size)
1007{
1008 return 0;
1009}
1010
1011int ecn_agent_eprpset(const EPRPINIB *item, const void *src, int size, bool_t *anno)
1012{
1013 ecn_agent_t *agent = cast_agent(item);
1014 ecn_node_t *node = agent->current_node;
1015 const uint8_t *edt = (const uint8_t *)src;
1016 ecn_obj_t *sobj = cast_obj2((const EOBJINIB *)item->exinf);
1017 uint8_t eprpcnt;
1018 int i;
1019
1020 switch (item->eprpcd) {
1021 /* ƒCƒ“ƒXƒ^ƒ“ƒXƒŠƒXƒg’Ê’m‚̏ꍇ */
1022 case 0xD5:
1023 /* Ž©ƒm[ƒhƒCƒ“ƒXƒ^ƒ“ƒXƒŠƒXƒg‚r’Ê’m‚̏ꍇ */
1024 case 0xD6:
1025 if ((node != NULL) && (node->state == ecn_node_state_idle)) {
1026 ecn_agent_queue_t *devices = &node->devices;
1027 ecn_agent_queue_t *queue = devices->p_next;
1028#ifdef _DEBUG
1029 assert(queue->p_parent == devices);
1030#endif
1031 for (; queue != devices; queue = queue->p_next) {
1032 ecn_obj_t *obj = cast_obj(queue);
1033 obj->pmapFlag = 0;
1034 }
1035 node->base.pmapFlag = 0;
1036 node->state = ecn_node_state_start;
1037 node->timer = (TMO)1000;
1038 node->current = sobj;
1039 }
1040 break;
1041 /* ’Ê’mƒvƒƒpƒeƒBƒ}ƒbƒv‚̏ꍇ */
1042 case 0x9D:
1043 eprpcnt = edt[0];
1044
1045 if (eprpcnt < 16) {
1046 /* ƒTƒCƒYƒ`ƒFƒbƒN */
1047 if (eprpcnt + 1 != size)
1048 return 0;
1049
1050 for (i = 1; i < size; i++)
1051 ecn_agent_set_epc_to_prop_map(edt[i], sobj->pmapAnno);
1052 }
1053 else {
1054 /* ƒTƒCƒYƒ`ƒFƒbƒN */
1055 if (size != 17)
1056 return 0;
1057
1058 memcpy(sobj->pmapAnno, &edt[1], 16);
1059 }
1060 sobj->eprpcnt = eprpcnt;
1061 sobj->pmapFlag |= PMAP_FLAG_ANNO;
1062 break;
1063 /* SETƒvƒƒpƒeƒBƒ}ƒbƒv‚̏ꍇ */
1064 case 0x9E:
1065 eprpcnt = edt[0];
1066
1067 if (eprpcnt < 16) {
1068 /* ƒTƒCƒYƒ`ƒFƒbƒN */
1069 if (eprpcnt + 1 != size)
1070 return 0;
1071
1072 for (i = 1; i < size; i++)
1073 ecn_agent_set_epc_to_prop_map(edt[i], sobj->pmapSet);
1074 }
1075 else {
1076 /* ƒTƒCƒYƒ`ƒFƒbƒN */
1077 if (size != 17)
1078 return 0;
1079
1080 memcpy(sobj->pmapSet, &edt[1], 16);
1081 }
1082 sobj->eprpcnt = eprpcnt;
1083 sobj->pmapFlag |= PMAP_FLAG_SET;
1084 break;
1085 /* GETƒvƒƒpƒeƒBƒ}ƒbƒv‚̏ꍇ */
1086 case 0x9F:
1087 eprpcnt = edt[0];
1088
1089 if (eprpcnt < 16) {
1090 /* ƒTƒCƒYƒ`ƒFƒbƒN */
1091 if (eprpcnt + 1 != size)
1092 return 0;
1093
1094 for (i = 1; i < size; i++)
1095 ecn_agent_set_epc_to_prop_map(edt[i], sobj->pmapGet);
1096 }
1097 else {
1098 /* ƒTƒCƒYƒ`ƒFƒbƒN */
1099 if (size != 17)
1100 return 0;
1101
1102 memcpy(sobj->pmapGet, &edt[1], 16);
1103 }
1104 sobj->eprpcnt = eprpcnt;
1105 sobj->pmapFlag |= PMAP_FLAG_GET;
1106 break;
1107 default:
1108 return 0;
1109 }
1110
1111 agent->msg_proced = true;
1112
1113 return size;
1114}
1115
1116ER ecn_agent_get_device_list(ID sender, int requestid, ECN_FBS_ID *pk_req)
1117{
1118 ER a_ret;
1119 ECN_FBS_ID req;
1120
1121 a_ret = _ecn_tsk_cre_req_fbs(sender, ECN_INM_GET_DEVICE_LIST_REQ, &req);
1122 if (a_ret != E_OK) {
1123 return a_ret;
1124 }
1125
1126 a_ret = _ecn_fbs_add_data_ex(req, &requestid, sizeof(((ecn_inm_get_device_list_req_t *)0)->requestid));
1127 if (a_ret != E_OK) {
1128 _ecn_fbs_del(req);
1129 return a_ret;
1130 }
1131
1132 *pk_req = req;
1133
1134 return E_OK;
1135}
1136
1137ER ecn_agent_get_device_info(ID sender, int requestid, ID eobjid, ECN_FBS_ID *pk_req)
1138{
1139 ER a_ret;
1140 ECN_FBS_ID req;
1141
1142 a_ret = _ecn_tsk_cre_req_fbs(sender, ECN_INM_GET_DEVICE_INFO_REQ, &req);
1143 if (a_ret != E_OK) {
1144 return a_ret;
1145 }
1146
1147 a_ret = _ecn_fbs_add_data_ex(req, &requestid, sizeof(((ecn_inm_get_device_info_req_t *)0)->requestid));
1148 if (a_ret != E_OK) {
1149 _ecn_fbs_del(req);
1150 return a_ret;
1151 }
1152
1153 a_ret = _ecn_fbs_add_data_ex(req, &eobjid, sizeof(((ecn_inm_get_device_info_req_t *)0)->eobjid));
1154 if (a_ret != E_OK) {
1155 _ecn_fbs_del(req);
1156 return a_ret;
1157 }
1158
1159 *pk_req = req;
1160
1161 return E_OK;
1162}
Note: See TracBrowser for help on using the repository browser.