source: EcnlProtoTool/trunk/mrbgems/mruby-ecnl/src/echonet_task.c@ 270

Last change on this file since 270 was 270, checked in by coas-nagasima, 7 years ago

mruby版ECNLプロトタイピング・ツールを追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc
File size: 63.2 KB
RevLine 
[270]1/*
2 * TOPPERS ECHONET Lite Communication Middleware
3 *
4 * Copyright (C) 2014-2016 Cores Co., Ltd. Japan
5 *
6 * 上記著作権者
7は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
8 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
9 * 変・再é…
10å¸ƒï¼ˆä»¥ä¸‹ï¼Œåˆ©ç”¨ã¨å‘¼ã¶ï¼‰ã™ã‚‹ã“とを無償で許諾する.
11 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
12 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
13 * スコード中に含まれていること.
14 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
15 * 用できる形で再é…
16å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
17å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
18 * 者
19マニュアルなど)に,上記の著作権表示,この利用条件および下記
20 * の無保証規定を掲載すること.
21 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
22 * 用できない形で再é…
23å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®ã„ずれかの条件を満たすこ
24 * と.
25 * (a) 再é…
26å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
27マニュアルなど)に,上記の著
28 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
29 * (b) 再é…
30å¸ƒã®å½¢æ…
31‹ã‚’,別に定める方法によって,TOPPERSプロジェクトに
32 * 報告すること.
33 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
34 * 害からも,上記著作権者
35およびTOPPERSプロジェクトをå…
36è²¬ã™ã‚‹ã“と.
37 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
38 * 由に基づく請求からも,上記著作権者
39およびTOPPERSプロジェクトを
40 * å…
41è²¬ã™ã‚‹ã“と.
42 *
43 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者
44お
45 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
46 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
47 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
48 * の責任を負わない.
49 *
50 */
51
52/*
53 * ECHONET Lite タスク
54 */
55
56#include <mruby.h>
57#include <stdio.h>
58#include <stdlib.h>
59#include <stdarg.h>
60#include <string.h>
61
62#include "echonet.h"
63#include "echonet_fbs.h"
64#include "echonet_task.h"
65#include "echonet_dbg.h"
66#ifdef ECHONET_CONTROLLER_EXTENTION
67#include "echonet_agent.h"
68#endif
69#include "mrb_ecnl.h"
70
71#ifndef ECHONET_TASK_GET_TIMER
72#define ECHONET_TASK_GET_TIMER TMO_FEVR
73#endif /* ECHONET_TASK_GET_TIMER */
74
75#ifndef ECHONET_TASK_PROGRESS
76#define ECHONET_TASK_PROGRESS(timer)
77#endif /* ECHONET_TASK_PROGRESS */
78
79#ifndef ECHONET_TASK_TIMEOUT
80#define ECHONET_TASK_TIMEOUT
81#endif /* ECHONET_TASK_TIMEOUT */
82
83ER _ecn_tsk_snd_mbx(ecnl_svc_task_t *svc, ECN_FBS_ID fa_rsp_fbs, bool_t from_app)
84{
85 ER a_ret;
86 intptr_t msg = (intptr_t)fa_rsp_fbs.ptr;
87 T_ECN_FBS_QUEUE *mbxid = &svc->lcl_mbxid;
88 int i;
89#ifdef ECN_DBG_PUT_ENA
90 intptr_t a_fbs_sub1 = (intptr_t)fa_rsp_fbs.ptr->lnk.p_sub[0];
91#endif
92 if (from_app && (((T_EDATA *)fa_rsp_fbs.ptr)->hdr.edata.esv == ESV_INFC)) {
93 svc->api_tid = ((T_EDATA *)fa_rsp_fbs.ptr)->hdr.ecn_hdr.tid;
94 mbxid = &svc->svc_mbxid;
95 }
96 else {
97 switch (fa_rsp_fbs.ptr->hdr.target.id) {
98 case ENOD_MULTICAST_ID:
99 if (from_app)
100 svc->api_tid = ((T_EDATA *)fa_rsp_fbs.ptr)->hdr.ecn_hdr.tid;
101
102 mbxid = &svc->lcl_mbxid;
103 break;
104 case ENOD_LOCAL_ID:
105 if (from_app)
106 mbxid = &svc->svc_mbxid;
107 else
108 mbxid = &svc->api_mbxid;
109 break;
110 case ENOD_API_ID:
111 mbxid = &svc->api_mbxid;
112 break;
113 default:
114 if (from_app)
115 svc->api_tid = ((T_EDATA *)fa_rsp_fbs.ptr)->hdr.ecn_hdr.tid;
116
117 i = fa_rsp_fbs.ptr->hdr.target.id;
118 if (i < ENOD_REMOTE_ID || !lcl_is_valid_addrid(svc, i))
119 return E_NOEXS;
120 i += - ENOD_REMOTE_ID + 1;
121 if (from_app && (i < svc->tnum_enodid)) {
122 /* 非同期のリモートノードはサービス処理タスクで処理する */
123 switch (svc->eobjcb_table[i].profile->eobjatr) {
124 case EOBJ_SYNC_REMOTE_NODE:
125 mbxid = &svc->lcl_mbxid;
126 break;
127 case EOBJ_ASYNC_REMOTE_NODE:
128 mbxid = &svc->svc_mbxid;
129 break;
130 default:
131 return E_SYS;
132 }
133 }
134 else {
135 mbxid = &svc->lcl_mbxid;
136 }
137 break;
138 }
139 }
140#ifdef ECN_DBG_PUT_ENA
141 ECN_DBG_PUT_3("ecn_fbs_enqueue(%d, 0x%08X-0x%08X)", mbxid, (intptr_t)msg, a_fbs_sub1);
142 _ecn_dbg_bindmp((const uint8_t *)msg, 256);
143#endif
144 a_ret = ecn_fbs_enqueue(mbxid, (T_ECN_FST_BLK *)msg);
145#ifdef ECN_DBG_PUT_ENA
146 ECN_DBG_PUT_5("ecn_fbs_enqueue(%d, 0x%08X-0x%08X) result = %d:%s", mbxid, (intptr_t)msg, a_fbs_sub1, a_ret, itron_strerror(a_ret));
147#endif
148 return a_ret;
149}
150
151static void _ecn_tsk_int_module_init(ecnl_svc_task_t *svc);
152static uint16_t _ecn_tsk_new_tid(ecnl_svc_task_t *svc);
153static void _ecn_tsk_int_msg(ecnl_svc_task_t *svc, intptr_t fa_exinf, ECN_FBS_ID fa_fbs_id);
154static void _ecn_tsk_ecn_msg(ecnl_svc_task_t *svc, intptr_t fa_exinf, ECN_FBS_ID fa_fbs_id);
155
156static void _ecn_tsk_eoj_set(ecnl_svc_task_t *svc, const EOBJINIB *fp_obj, ATR fa_eobjatr, bool_t fa_fromapp, bool_t fa_update,
157 ECN_FBS_ID fa_fbs_id, ECN_SRV_CODE fa_res_esv, ECN_SRV_CODE fa_sna_esv,
158 ECN_FBS_ID *fa_fbs_anno);
159static void _ecn_tsk_eoj_get(ecnl_svc_task_t *svc, const EOBJINIB *fp_obj, ATR fa_eobjatr, bool_t fa_forward, ATR fa_access,
160 ECN_FBS_ID fa_fbs_id, ECN_SRV_CODE fa_res_esv, ECN_SRV_CODE fa_sna_esv);
161static void _ecn_tsk_eoj_res(ecnl_svc_task_t *svc, ECN_FBS_ID fa_fbs_id, ECN_SRV_CODE fa_res_esv,
162 ECN_SRV_CODE fa_sna_esv);
163static void _ecn_tsk_eoj_set_get(ecnl_svc_task_t *svc, const EOBJINIB *fp_obj, ATR fa_eobjatr, bool_t fa_fromapp,
164 ECN_FBS_ID fa_fbs_id, ECN_SRV_CODE fa_res_esv, ECN_SRV_CODE fa_sna_esv,
165 ECN_FBS_ID *fa_fbs_anno);
166static void _ecn_tsk_eoj_set_get_res(ecnl_svc_task_t *svc, const EOBJINIB *fp_obj, ATR fa_eobjatr, bool_t fa_fromapp,
167 ECN_FBS_ID fa_fbs_id, ECN_FBS_ID *fa_fbs_anno);
168
169/*
170 * ECHONET Lite タスクの初期化(コンストラクタ相当)
171 */
172void echonet_task_init(ecnl_svc_task_t *svc, intptr_t exinf)
173{
174 _ecn_tsk_int_module_init(svc);
175}
176
177/*
178 * モジュール初期化
179 */
180static void _ecn_tsk_int_module_init(ecnl_svc_task_t *svc)
181{
182 if (!svc->eobjlist_need_init)
183 return;
184
185 ECN_CAP_PUT("[ECHONET MainTask] started");
186
187 svc->eobjlist_need_init = 0;
188
189#ifdef ECHONET_CONTROLLER_EXTENTION
190 ecn_agent_init(svc);
191#endif
192}
193
194/*
195 * ECHONET Lite タスク タイマー値取得
196 */
197TMO echonet_svctask_get_timer(ecnl_svc_task_t *svc)
198{
199 TMO a_timer;
200#ifdef ECHONET_CONTROLLER_EXTENTION
201 TMO a_timera;
202#endif
203
204 a_timer = ECHONET_TASK_GET_TIMER;
205#ifdef ECHONET_CONTROLLER_EXTENTION
206 a_timera = ecn_agent_get_timer(svc);
207 if(a_timer == TMO_FEVR){
208 a_timer =a_timera;
209 }
210 else if((a_timera != TMO_FEVR) && (a_timera < a_timer)){
211 a_timer = a_timera;
212 }
213#endif
214 return a_timer;
215}
216
217
218/*
219 * ECHONET Lite タスク 時間経過処理
220 */
221void echonet_svctask_progress(ecnl_svc_task_t *svc, TMO a_timer)
222{
223 ECHONET_TASK_PROGRESS(a_timer);
224#ifdef ECHONET_CONTROLLER_EXTENTION
225 ecn_agent_progress(svc, a_timer);
226#endif
227}
228
229/*
230 * ECHONET Lite タスク メッセージ受信処理
231 */
232void echonet_svctask_recv_msg(ecnl_svc_task_t *svc, T_ECN_FST_BLK *p_msg)
233{
234 ECN_FBS_ID fbs_id;
235 fbs_id.ptr = p_msg;
236
237 ECN_DBG_PUT_1("trcv_dtq() mbx recv (%d byte)", _ecn_fbs_get_datalen(fbs_id));
238 svc->release_esv = true;
239
240 switch (fbs_id.ptr->hdr.type) {
241 /* 内
242部使用メッセージ */
243 case ECN_MSG_INTERNAL:
244 _ecn_tsk_int_msg(svc, svc->exinf, fbs_id);
245 break;
246
247 /* ECHONET用メッセージ */
248 case ECN_MSG_ECHONET:
249 _ecn_tsk_ecn_msg(svc, svc->exinf, fbs_id);
250 break;
251
252 default:
253 ECN_DBG_PUT_1("echonet_task() a_fbs_id.ptr->k.hdr.k.t_edt.type:0x%02X undefined.", fbs_id.ptr->hdr.type);
254 }
255
256 /* 領域解放 */
257 if (svc->release_esv)
258 _ecn_fbs_del(svc->mrb, fbs_id);
259}
260
261/*
262 * ECHONET Lite タスク タイムアウト処理
263 */
264void echonet_svctask_timeout(ecnl_svc_task_t *svc)
265{
266 ECHONET_TASK_TIMEOUT;
267#ifdef ECHONET_CONTROLLER_EXTENTION
268 ecn_agent_timeout(svc);
269#endif
270}
271
272/*
273 * シーケンス番号生成
274 */
275static uint16_t _ecn_tsk_new_tid(ecnl_svc_task_t *svc)
276{
277 return svc->current_tid++;
278}
279
280/*
281 * 要求電文作成
282 * 引数
283 * ECN_FBS_ID *fp_fbs_id 取得したFBS_IDの格納å…
284ˆ
285 * ID fa_seoj 送信å…
286ƒã®ECHONETオブジェクトID
287 * ID fa_deoj 宛å…
288ˆã®ECHONETオブジェクトID
289 * uint8_t fa_epc プロパティコード
290 * uint8_t fa_pdc プロパティ値データサイズ
291 * const void *p_edt プロパティ値データ
292 * ECN_SRV_CODE fa_esv ECHONET Light サービスコード
293 */
294ER _ecn_tsk_mk_esv(ecnl_svc_task_t *svc, ECN_FBS_ID *fp_fbs_id, ID fa_seoj, ID fa_deoj,
295 uint8_t fa_epc, uint8_t fa_pdc, const void *p_edt, ECN_SRV_CODE fa_esv)
296{
297 mrb_state *mrb = svc->mrb;
298 ER a_ret;
299 int a_size, i;
300 ECN_FBS_ID a_fbs_id = { 0 }; /* 要求電文用メモリ */
301 T_ECN_EDT_HDR a_ecn_hdp; /* ecn_hdr+edata+ecn_prp 14byte */
302 ID a_enodid;
303 const EOBJINIB *a_eobj;
304 const EOBJINIB *a_enod;
305
306 if (!fp_fbs_id)
307 return E_PAR; /* 取得したFBS_IDの格納å…
308ˆãŒNULL */
309 if (ECHONET_MEMPOOL_BLOCK_SIZE <= fa_pdc)
310 return E_PAR; /* プロパティ値サイズが大きすぎる */
311 if (!p_edt && 0 < fa_pdc)
312 return E_PAR; /* プロパティ値サイズが1以上なのにデータポインタがNULL */
313
314 if (fa_seoj <= EOBJ_NULL || svc->tmax_eobjid < fa_seoj)
315 return E_NOEXS; /* ECHONETオブジェクトIDが未定義 */
316#ifndef ECHONET_CONTROLLER_EXTENTION
317 if (fa_deoj < EOBJ_NULL || svc->tmax_eobjid < fa_deoj)
318 return E_NOEXS; /* ECHONETオブジェクトIDが未定義 */
319#else
320 if (fa_deoj < EOBJ_NULL || (svc->tmax_eobjid + TNUM_AEOBJID) < fa_deoj)
321 return E_NOEXS; /* ECHONETオブジェクトIDが未定義 */
322#endif
323 if (fa_deoj == EOBJ_NULL && fa_esv == ESV_INFC)
324 return E_NOEXS; /* ECHONETオブジェクトIDが未定義 */
325
326 /* 要求最小サイズの取得 */
327 a_size = sizeof(T_ECN_HDR) + sizeof(T_ECN_EDATA_BODY) + sizeof(T_ECN_PRP);
328
329 /* 要求電文用メモリの取得 */
330 a_ret = _ecn_fbs_cre(mrb, a_size, &a_fbs_id);
331 if (a_ret != E_OK || !a_fbs_id.ptr) { /* 確保失敗 */
332 ECN_DBG_PUT_3("_ecn_fbs_cre(%d) result = %d:%s",
333 a_size,
334 a_ret, itron_strerror(a_ret));
335 return E_NOMEM;
336 }
337
338 /* 要求電文設定 */
339 memset(&a_ecn_hdp, 0, sizeof(a_ecn_hdp));
340 a_ecn_hdp.ecn_hdr.ehd1 = ECN_EDH1_ECHONET_LITE;
341 a_ecn_hdp.ecn_hdr.ehd2 = ECN_EDH2_FORMAT_1;
342 a_ecn_hdp.ecn_hdr.tid = _ecn_tsk_new_tid(svc);
343 memcpy(&a_ecn_hdp.edata.seoj, &echonet_svctask_get_eobjinib(svc, fa_seoj)->eojx1, sizeof(a_ecn_hdp.edata.seoj));
344 a_ecn_hdp.edata.esv = fa_esv;
345 a_ecn_hdp.edata.opc = 1; /* 処理プロパティ数 */
346 a_ecn_hdp.ecn_prp.epc = fa_epc; /* プロパティコード */
347 a_ecn_hdp.ecn_prp.pdc = fa_pdc; /* 付随データサイズ */
348
349 /* 要求電文用メモリにデータ追加 */
350 a_ret = _ecn_fbs_add_data_ex(mrb, a_fbs_id, &a_ecn_hdp, a_size);
351 if (a_ret) {
352 ECN_DBG_PUT_5("_ecn_fbs_add_data_ex(*, ecn_hdp{esv:0x%02X,epc:0x%02X}, %d) result = %d:%s",
353 a_ecn_hdp.edata.esv, a_ecn_hdp.ecn_prp.epc, a_size,
354 a_ret, itron_strerror(a_ret));
355 goto lb_except;
356 }
357 if (0 < fa_pdc) {
358 /* 付随データ追加 */
359 a_ret = _ecn_fbs_add_data_ex(mrb, a_fbs_id, p_edt, fa_pdc);
360 if (a_ret) {
361 ECN_DBG_PUT_5("_ecn_fbs_add_data_ex(*, ecn_hdp{esv:0x%02X,epc:0x%02X} edt, %d) result = %d:%s",
362 a_ecn_hdp.edata.esv, a_ecn_hdp.ecn_prp.epc, fa_pdc,
363 a_ret, itron_strerror(a_ret));
364 goto lb_except;
365 }
366 }
367 if (fa_deoj == 0) {
368 ECN_DBG_PUT("マルチキャスト");
369 /* fa_deoj == 0 : マルチキャスト */
370 ((T_EDATA *)a_fbs_id.ptr)->hdr.edata.deoj.eojx1 = EOJ_X1_PROFILE;
371 ((T_EDATA *)a_fbs_id.ptr)->hdr.edata.deoj.eojx2 = EOJ_X2_NODE_PROFILE;
372 ((T_EDATA *)a_fbs_id.ptr)->hdr.edata.deoj.eojx3 = 0x01;
373 a_fbs_id.ptr->hdr.target.id = ENOD_MULTICAST_ID;
374 }
375 else if (fa_deoj <= svc->tmax_eobjid) {
376 ECN_DBG_PUT_1("fa_deoj = %d", fa_deoj);
377 /* if (fa_deoj < 1 || svc->tmax_eobjid < fa_deoj) …の異常系は関数冒頭で除外済みとする */
378 a_eobj = echonet_svctask_get_eobjinib(svc, fa_deoj);
379 memcpy(&((T_EDATA *)a_fbs_id.ptr)->hdr.edata.deoj, &a_eobj->eojx1,
380 sizeof(((T_EDATA *)a_fbs_id.ptr)->hdr.edata.deoj));
381
382 /* テーブルから検索 */
383 a_fbs_id.ptr->hdr.target.id = ENOD_NOT_MATCH_ID;
384 a_enodid = (a_eobj->enodid == 0) ? fa_deoj : a_eobj->enodid;
385 a_enod = echonet_svctask_get_eobjinib(svc, a_enodid);
386 if ((a_enod->eobjatr == EOBJ_LOCAL_NODE)
387 || ((a_enod->eobjatr == EOBJ_ASYNC_REMOTE_NODE) && (fa_esv == ESV_GET))) {
388 a_fbs_id.ptr->hdr.target.id = ENOD_LOCAL_ID;
389 }
390 else{
391 for (i = 1; i < svc->tnum_enodid; i++) {
392 const EOBJCB *temp = &svc->eobjcb_table[i];
393 if (a_enod != temp->profile)
394 continue;
395
396 a_fbs_id.ptr->hdr.target.id = (ECN_ENOD_ID)(i + ENOD_REMOTE_ID - 1);
397 break;
398 }
399 }
400 if (a_fbs_id.ptr->hdr.target.id == ENOD_NOT_MATCH_ID) {
401 goto lb_except;
402 ECN_DBG_PUT_3("deoj = %02X %02X %02x : enod not match",
403 ((T_EDATA *)a_fbs_id.ptr)->hdr.edata.deoj.eojx1,
404 ((T_EDATA *)a_fbs_id.ptr)->hdr.edata.deoj.eojx2,
405 ((T_EDATA *)a_fbs_id.ptr)->hdr.edata.deoj.eojx3);
406 }
407#ifdef ECN_DBG_PUT_ENA
408 else {
409 ECN_DBG_PUT_4("deoj = %02X %02X %02x : %s",
410 ((T_EDATA *)a_fbs_id.ptr)->hdr.edata.deoj.eojx1,
411 ((T_EDATA *)a_fbs_id.ptr)->hdr.edata.deoj.eojx2,
412 ((T_EDATA *)a_fbs_id.ptr)->hdr.edata.deoj.eojx3,
413 _ecn_dbg_enod2str(a_fbs_id.ptr->hdr.target.id));
414 }
415#endif
416 }
417#ifdef ECHONET_CONTROLLER_EXTENTION
418 else{
419 T_ECN_EOJ eoj;
420 ECN_ENOD_ID enodid;
421 ECN_DBG_PUT_1("fa_deoj = %d", fa_deoj);
422 /* オブジェクトIDからEOJとノードIDを取得 */
423 if(ecn_agent_get_eoj_enodid(svc, fa_deoj, &eoj, &enodid)){
424 memcpy(&((T_EDATA *)a_fbs_id.ptr)->hdr.edata.deoj, &eoj,
425 sizeof(((T_EDATA *)a_fbs_id.ptr)->hdr.edata.deoj));
426 a_fbs_id.ptr->hdr.target.id = enodid;
427#ifdef ECN_DBG_PUT_ENA
428 ECN_DBG_PUT_4("deoj = %02X %02X %02x : %s",
429 ((T_EDATA *)a_fbs_id.ptr)->hdr.edata.deoj.eojx1,
430 ((T_EDATA *)a_fbs_id.ptr)->hdr.edata.deoj.eojx2,
431 ((T_EDATA *)a_fbs_id.ptr)->hdr.edata.deoj.eojx3,
432 _ecn_dbg_enod2str(a_fbs_id.ptr->hdr.target.id));
433#endif
434 }
435 else {
436 ECN_DBG_PUT_3("deoj = %02X %02X %02x : enod not match",
437 ((T_EDATA *)a_fbs_id.ptr)->hdr.edata.deoj.eojx1,
438 ((T_EDATA *)a_fbs_id.ptr)->hdr.edata.deoj.eojx2,
439 ((T_EDATA *)a_fbs_id.ptr)->hdr.edata.deoj.eojx3);
440 goto lb_except;
441 }
442 }
443#endif
444 a_fbs_id.ptr->hdr.type = ECN_MSG_ECHONET;
445 a_fbs_id.ptr->hdr.sender.id = ENOD_API_ID;
446 if (fa_esv == ESV_INFC)
447 a_fbs_id.ptr->hdr.reply.id = a_fbs_id.ptr->hdr.target.id;
448 else if (fa_esv == ESV_INF_REQ)
449 a_fbs_id.ptr->hdr.reply.id = ENOD_MULTICAST_ID;
450 else
451 a_fbs_id.ptr->hdr.reply.id = ENOD_API_ID;
452
453 ((T_EDATA *)a_fbs_id.ptr)->trn_pos = -1;
454 /* 正常終了 */
455 *fp_fbs_id = a_fbs_id;
456 return E_OK;
457
458lb_except:
459 /* データ作成失敗したら領域解放 */
460 if (a_fbs_id.ptr)
461 _ecn_fbs_del(mrb, a_fbs_id);
462
463 return a_ret;
464}
465
466/*
467 * 内
468部使用メッセージ
469 */
470static void _ecn_tsk_int_msg(ecnl_svc_task_t *svc, intptr_t fa_exinf, ECN_FBS_ID fa_fbs_id)
471{
472 T_ECN_INTERNAL_MSG a_im;
473 ECN_FBS_SSIZE_T a_len;
474 int a_ans;
475
476 a_im.command = 0;
477 a_len = 0;
478 a_ans = _ecn_fbs_get_data(svc->mrb, fa_fbs_id, &a_im.command, sizeof(a_im.command), &a_len);
479 if (a_ans || !a_len) {
480 return; /* NG */
481 }
482
483 switch (a_im.command) {
484 case ECN_INM_NOTIFY_INSTANCELIST:
485 ECN_DBG_PUT("do _ecn_tsk_int_startup()");
486 _ecn_tsk_int_startup(svc);
487 break;
488 default:
489#ifdef ECHONET_CONTROLLER_EXTENTION
490 if(ecn_agent_proc_int_msg(svc, fa_fbs_id, a_im.command))
491 break;
492#endif
493 ECN_DBG_PUT_1("recv: unefined internal-msg: %d", a_im.command);
494 break;
495 }
496}
497
498/*
499 * タスク初期化
500 */
501void _ecn_tsk_int_startup(ecnl_svc_task_t *svc)
502{
503 _ecn_tsk_int_module_init(svc);
504}
505
506/*
507 * インスタンスリスト通知の送信
508 * ECHONET-Lite_Ver.1.10_02.pdf p.43 図4-1-4
509 */
510ER _ecn_tsk_ntf_inl(ecnl_svc_task_t *svc)
511{
512 mrb_state *mrb = svc->mrb;
513 const T_ECN_EOJ a_seoj = /* 0x01 : 一般ノード、0x02:送信専用ノード */
514 { EOJ_X1_PROFILE, EOJ_X2_NODE_PROFILE, 0x01 };
515 const T_ECN_EOJ a_deoj =
516 { EOJ_X1_PROFILE, EOJ_X2_NODE_PROFILE, 0x01 };
517 T_ECN_EDT_HDR a_hdr;
518 ER a_ret = E_OK;
519 ECN_FBS_ID a_fbs = { 0 };
520 int a_eoj_ct = 0;
521 int i;
522 uint8_t a_count;
523 const EOBJCB *enod = &svc->eobjcb_table[0]; /* ローカルノード */
524 const EOBJINIB *eobj;
525
526 ECN_DBG_PUT("do _ecn_tsk_ntf_inl()");
527
528 memset(&a_hdr, 0, sizeof(a_hdr));
529 a_hdr.ecn_hdr.ehd1 = ECN_EDH1_ECHONET_LITE;
530 a_hdr.ecn_hdr.ehd2 = ECN_EDH2_FORMAT_1;
531 a_hdr.edata.seoj = a_seoj;
532 a_hdr.edata.deoj = a_deoj;
533 a_hdr.edata.esv = ESV_INF;
534 a_hdr.edata.opc = 1;
535 a_hdr.ecn_prp.epc = ECN_EPC_INL_BCS;
536
537 for (i = 0; i < enod->eobjcnt; i++) {
538 eobj = enod->eobjs[i];
539
540 if (!a_eoj_ct) {
541 /* メモリ確保・ヘッダ格納 */
542 a_hdr.ecn_hdr.tid = (uint8_t)_ecn_tsk_new_tid(svc); /* シーケンス番号生成 */
543 a_ret = _ecn_fbs_cre(mrb, sizeof(a_hdr), &a_fbs);
544 if (a_ret != E_OK) /* 確保失敗 */
545 goto lb_except;
546 a_ret = _ecn_fbs_add_data(mrb, a_fbs, &a_hdr, sizeof(a_hdr));
547 if (a_ret != E_OK) /* データ追加失敗 */
548 goto lb_except;
549
550 a_fbs.ptr->hdr.type = ECN_MSG_ECHONET;
551 a_fbs.ptr->hdr.sender.id = ENOD_LOCAL_ID;
552 a_fbs.ptr->hdr.target.id = ENOD_MULTICAST_ID;
553 a_fbs.ptr->hdr.reply.id = ENOD_LOCAL_ID;
554 ((T_EDATA *)a_fbs.ptr)->hdr.ecn_prp.pdc = 1; /* 件数 */
555 /* 件数を格納 */
556 a_count = (uint8_t)(enod->eobjcnt - i);
557 if (a_count >= ECN_IST_LST_EOJ_MAX_CT)
558 a_count = ECN_IST_LST_EOJ_MAX_CT;
559 a_ret = _ecn_fbs_add_data_ex(mrb, a_fbs, &a_count, sizeof(a_count));
560 if (a_ret != E_OK) /* データ追加失敗 */
561 goto lb_except;
562 }
563 /* ECHONETオブジェクトID(3byte)を格納 */
564 a_ret = _ecn_fbs_add_data_ex(mrb, a_fbs, &eobj->eojx1, sizeof(T_ECN_EOJ));
565 if (a_ret != E_OK) /* データ追加失敗 */
566 goto lb_except;
567
568 /* 件数・edtサイズ加算 */
569 ((T_EDATA *)a_fbs.ptr)->hdr.ecn_prp.pdc += sizeof(T_ECN_EOJ);
570 if (++a_eoj_ct < ECN_IST_LST_EOJ_MAX_CT)
571 continue;
572
573 /* 1アナウンスでの上限に達したら、一旦送信 */
574 a_ret = _ecn_tsk_snd_mbx(svc, a_fbs, false);
575 if (a_ret != E_OK) /* データ送信失敗 */
576 goto lb_except;
577 a_eoj_ct = 0;
578 a_fbs.ptr = 0;
579 }
580 if (a_eoj_ct) {
581 /* 未送信データがあったら、送信 */
582 a_ret = _ecn_tsk_snd_mbx(svc, a_fbs, false);
583 if (a_ret != E_OK) /* データ送信失敗 */
584 goto lb_except;
585 a_fbs.ptr = 0;
586 }
587 goto lb_finally;
588
589lb_except:
590 if (a_fbs.ptr)
591 _ecn_fbs_del(mrb, a_fbs);
592
593lb_finally:
594 return a_ret;
595}
596
597const EOBJCB *_ecn_eno_fnd(ecnl_svc_task_t *svc, ECN_ENOD_ID enodid)
598{
599 const EOBJCB *enod = NULL;
600 int i;
601
602 switch (enodid) {
603 case ENOD_MULTICAST_ID:
604 case ENOD_LOCAL_ID:
605 case ENOD_API_ID:
606 enod = &svc->eobjcb_table[0];
607 break;
608 default:
609 i = enodid - ENOD_REMOTE_ID + 1;
610 if ((i >= 1) && (i < svc->tnum_enodid))
611 enod = &svc->eobjcb_table[i];
612#ifdef ECHONET_CONTROLLER_EXTENTION
613 else{
614 ecn_node_t *p_tmp = ecn_agent_find_node(svc, enodid);
615 if (p_tmp == NULL)
616 return NULL;
617 return &p_tmp->eobj;
618 }
619#endif
620 break;
621 }
622
623 return enod;
624}
625
626/*
627 * 3byteのeobjidでé…
628åˆ—中を検索する
629 */
630const EOBJINIB *_ecn_eoj_fnd(const EOBJCB *fp_nod, const T_ECN_EOJ *fp_eoj)
631{
632 const EOBJINIB *p_obj;
633 int i, count = fp_nod->eobjcnt;
634
635#ifdef ECHONET_CONTROLLER_EXTENTION
636 if (fp_nod->eobjs == NULL) {
637 ecn_obj_t *p_tmp = ecn_agent_find_eobj(fp_nod, *fp_eoj);
638 if(p_tmp == NULL)
639 return NULL;
640 return &p_tmp->inib;
641 }
642#endif
643
644 for (i = 0; i < count; i++) {
645 p_obj = fp_nod->eobjs[i];
646
647 if (p_obj->eojx1 != fp_eoj->eojx1)
648 continue;
649 if (p_obj->eojx2 != fp_eoj->eojx2)
650 continue;
651 if (p_obj->eojx3 != fp_eoj->eojx3)
652 continue;
653
654 return p_obj;
655 }
656
657 return 0;
658}
659
660/*
661 * 電文の構成要素数とサイズのチェックを行う
662 */
663static bool_t _ecn_tsk_check_format(ecnl_svc_task_t *svc, T_EDATA *edata, int len)
664{
665 mrb_state *mrb = svc->mrb;
666 ER ret;
667 T_ENUM_EPC enm;
668 int opc;
669 uint8_t epc;
670 uint8_t pdc;
671
672 len -= sizeof(T_ECN_HDR) + sizeof(T_ECN_EDATA_BODY);
673
674 ret = ecn_itr_ini(&enm, edata);
675 if (ret != E_OK) {
676 return false;
677 }
678 opc = enm.count;
679 for (;;) {
680 ret = ecn_itr_nxt(mrb, &enm, &epc, &pdc, NULL);
681 if (enm.is_eof)
682 break;
683 if (ret == E_BOVR){
684 if (opc != 0)
685 return false;
686 opc = enm.count;
687 len -= 1;
688 continue;
689 }
690 if (ret != E_OK)
691 break;
692
693 opc--;
694 len -= sizeof(T_ECN_PRP) + pdc;
695 }
696
697 return (opc == 0) && (len == 0);
698}
699
700static int _ecn_tsk_ecn_msg_main(ecnl_svc_task_t *svc, ECN_FBS_ID fa_fbs_id, const EOBJINIB *p_obj, ATR eobjatr,
701 const EOBJINIB *p_sobj, ATR sobjatr);
702
703/*
704 * ECHONET用メッセージ
705 */
706static void _ecn_tsk_ecn_msg(ecnl_svc_task_t *svc, intptr_t fa_exinf, ECN_FBS_ID fa_fbs_id)
707{
708 mrb_state *mrb = svc->mrb;
709 const EOBJCB *p_nod, *p_snod;
710 const EOBJINIB *p_obj, *p_sobj = NULL;
711 ATR eobjatr, sobjatr = EPC_NONE;
712 T_ECN_EDT_HDR *p_esv;
713 ER a_ret;
714 int i, count;
715 T_ECN_EOJ *p_eoj;
716 bool_t a_prc;
717 bool_t a_fwd;
718
719#ifdef ECN_DBG_PUT_ENA
720 printf("mbx recv:");
721 _ecn_dbg_bindmp((void *)fa_fbs_id.ptr, sizeof(*fa_fbs_id.ptr));
722#endif
723
724 p_esv = &((T_EDATA *)fa_fbs_id.ptr)->hdr;
725
726 if (p_esv->ecn_hdr.ehd1 != ECN_EDH1_ECHONET_LITE
727 || p_esv->ecn_hdr.ehd2 != ECN_EDH2_FORMAT_1) {
728 ECN_DBG_PUT_2("_ecn_tsk_ecn_msg() format fault: 0x%02X,0x%02X", p_esv->ecn_hdr.ehd1, p_esv->ecn_hdr.ehd2);
729 return;
730 }
731
732 if (p_esv->edata.deoj.eojx3 > 0x7F) {
733 ECN_DBG_PUT_1("_ecn_tsk_ecn_msg() format fault: deoj %06X",
734 p_esv->edata.deoj.eojx1 << 16 | p_esv->edata.deoj.eojx2 << 8 | p_esv->edata.deoj.eojx3);
735 return;
736 }
737
738 if ((p_esv->edata.seoj.eojx3 > 0x7F) || (p_esv->edata.seoj.eojx3 == 0x00)) {
739 ECN_DBG_PUT_1("_ecn_tsk_ecn_msg() format fault: seoj %06X",
740 p_esv->edata.seoj.eojx1 << 16 | p_esv->edata.seoj.eojx2 << 8 | p_esv->edata.seoj.eojx3);
741 return;
742 }
743
744 if ((p_esv->edata.esv & 0xC0) != 0x40) {
745 ECN_DBG_PUT_1("_ecn_tsk_ecn_msg() format fault: esv 0x%02X", p_esv->edata.esv);
746 return;
747 }
748
749 if (p_esv->edata.opc == 0x00) {
750 ECN_DBG_PUT_1("_ecn_tsk_ecn_msg() format fault: opc 0x%02X", p_esv->edata.opc);
751 return;
752 }
753
754 /* 電文の構成要素数とサイズのチェックを行う */
755 if (!_ecn_tsk_check_format(svc, (T_EDATA *)fa_fbs_id.ptr, fa_fbs_id.ptr->hdr.length)) {
756 ECN_DBG_PUT("_ecn_tsk_ecn_msg() format fault");
757 return;
758 }
759
760 /* 送信宛からノードを検索 */
761 p_nod = _ecn_eno_fnd(svc, fa_fbs_id.ptr->hdr.target.id);
762 /* 送信å…
763ƒã‹ã‚‰ãƒŽãƒ¼ãƒ‰ã‚’検索 */
764 p_snod = _ecn_eno_fnd(svc, fa_fbs_id.ptr->hdr.sender.id);
765 if (p_snod != NULL) {
766 sobjatr = p_snod->profile->eobjatr;
767 /* ノードプロファイルの場合 */
768 if ((p_esv->edata.seoj.eojx1 == EOJ_X1_PROFILE)
769 && (p_esv->edata.seoj.eojx2 == EOJ_X2_NODE_PROFILE)) {
770 p_sobj = p_snod->profile;
771 }
772 /* 機器オブジェクトの場合 */
773 else {
774 p_sobj = _ecn_eoj_fnd(p_snod, &p_esv->edata.seoj);
775 }
776 }
777
778#ifdef ECHONET_CONTROLLER_EXTENTION
779 ecn_agent_proc_ecn_msg(svc, &p_snod, &p_sobj, (T_EDATA *)fa_fbs_id.ptr);
780#endif
781
782 /* ノード内
783の機器オブジェクトを検索 */
784 a_prc = false;
785 a_fwd = false;
786 svc->forward_esv = false;
787 if (p_nod != NULL) {
788 eobjatr = p_nod->profile->eobjatr;
789 p_eoj = &p_esv->edata.deoj;
790 /* ノードプロファイルの場合 */
791 if ((p_eoj->eojx1 == EOJ_X1_PROFILE)
792 && (p_eoj->eojx2 == EOJ_X2_NODE_PROFILE)) {
793 if ((p_eoj->eojx3 == p_nod->profile->eojx3)
794 || (p_eoj->eojx3 == 0)) {
795 /* 電文処理実行 */
796 if (_ecn_tsk_ecn_msg_main(svc, fa_fbs_id, p_nod->profile, eobjatr, p_sobj, sobjatr) == 1)
797 a_fwd = true;
798 a_prc = true;
799 }
800 /* 0x74 プロパティ値通知(応答要)の場合の場合は電文破棄 */
801 else if (p_esv->edata.esv == ESV_INFC) {
802 a_prc = true;
803 }
804 }
805 /* 機器オブジェクトの場合 */
806 else {
807 count = p_nod->eobjcnt;
808#ifdef ECHONET_CONTROLLER_EXTENTION
809 p_obj = NULL;
810#endif
811 for (i = 0; i < count; i++) {
812#ifdef ECHONET_CONTROLLER_EXTENTION
813 if(p_nod->eobjs == NULL)
814 p_obj = ecn_agent_next_eobj(p_nod, p_obj);
815 else
816 p_obj = p_nod->eobjs[i];
817#else
818 p_obj = p_nod->eobjs[i];
819#endif
820 if (p_obj->eojx1 != p_eoj->eojx1)
821 continue;
822 if (p_obj->eojx2 != p_eoj->eojx2)
823 continue;
824 /* インスタンスコードが0の場合、同じクラスのå…
825¨ã¦ã®ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹å®› */
826 if ((p_obj->eojx3 != p_eoj->eojx3) && (p_eoj->eojx3 != 0))
827 continue;
828
829 /* 電文処理実行 */
830 if (_ecn_tsk_ecn_msg_main(svc, fa_fbs_id, p_obj, eobjatr, p_sobj, sobjatr) == 1)
831 a_fwd = true;
832 a_prc = true;
833 }
834
835 /* 機器オブジェクトが見つからず、0x74 プロパティ値通知(応答要)の場合は電文破棄 */
836 if (!a_prc && (p_esv->edata.esv == ESV_INFC)) {
837 a_prc = true;
838 }
839 }
840 }
841 /* 機器オブジェクトが見つからない場合でも */
842 if (!a_prc) {
843 /* 電文処理実行(応答受信用) */
844 if (_ecn_tsk_ecn_msg_main(svc, fa_fbs_id, NULL, EPC_NONE, p_sobj, sobjatr) == 1)
845 a_fwd = true;
846 }
847
848 /* 応答の場合アプリケーションに転送する */
849 if (a_fwd && ((p_esv->ecn_hdr.tid == svc->api_tid)
850 || svc->forward_esv))
851 {
852 svc->release_esv = false;
853
854 ECN_CAP_PUT_1("redirect svc->svc_mbxid → svc->api_mbxid (esv:0x%02X)",
855 p_esv->edata.esv);
856 fa_fbs_id.ptr->hdr.target.id = ENOD_API_ID;
857 a_ret = ecn_fbs_enqueue(&svc->api_mbxid, fa_fbs_id.ptr);
858 if (a_ret != E_OK) {
859 ECN_DBG_PUT_2("_ecn_tsk_ecn_msg() : ecn_fbs_enqueue() result = %d:%s", a_ret, itron_strerror(a_ret));
860 _ecn_fbs_del(mrb, fa_fbs_id);
861 }
862 }
863#ifdef ECHONET_CONTROLLER_EXTENTION
864 ecn_agent_proc_ecn_msg_end(svc);
865#endif
866}
867
868static int _ecn_tsk_ecn_msg_main(ecnl_svc_task_t *svc, ECN_FBS_ID fa_fbs_id, const EOBJINIB *p_obj, ATR eobjatr,
869 const EOBJINIB *p_sobj, ATR sobjatr)
870{
871 mrb_state *mrb = svc->mrb;
872 int result;
873 T_ECN_EDT_HDR *p_esv;
874 ECN_FBS_ID a_fbs_anno = { NULL };
875 bool_t fromapp = sobjatr == EOBJ_LOCAL_NODE;
876
877 p_esv = &((T_EDATA *)fa_fbs_id.ptr)->hdr;
878
879 switch (p_esv->edata.esv) {
880 /* 0x60 プロパティ値書き込み要求(応答不要) */
881 case ESV_SET_I:
882 if (!p_obj) {
883 ECN_DBG_PUT_1("_ecn_tsk_ecn_msg_main() eoj %06X not found.",
884 p_esv->edata.deoj.eojx1 << 16 | p_esv->edata.deoj.eojx2 << 8 | p_esv->edata.deoj.eojx3);
885 result = -1;
886 break;
887 }
888 _ecn_tsk_eoj_set(svc, p_obj, eobjatr, fromapp, false, fa_fbs_id, ESV_NOP, ESV_SET_I_SNA, &a_fbs_anno); /* 0; 0x50 */
889 result = 0;
890 break;
891
892 /* 0x61 プロパティ値書き込み要求(応答要) */
893 case ESV_SET_C:
894 if (!p_obj) {
895 ECN_DBG_PUT_1("_ecn_tsk_ecn_msg_main() eoj %06X not found.",
896 p_esv->edata.deoj.eojx1 << 16 | p_esv->edata.deoj.eojx2 << 8 | p_esv->edata.deoj.eojx3);
897 result = -1;
898 break;
899 }
900 _ecn_tsk_eoj_set(svc, p_obj, eobjatr, fromapp, false, fa_fbs_id, ESV_SET_RES, ESV_SET_C_SNA, &a_fbs_anno); /* 0x71; 0x51 */
901 result = 0;
902 break;
903
904 /* 0x62 プロパティ値読み出し要求 */
905 case ESV_GET:
906 if (!p_obj) {
907 ECN_DBG_PUT_1("_ecn_tsk_ecn_msg_main() eoj %06X not found.",
908 p_esv->edata.deoj.eojx1 << 16 | p_esv->edata.deoj.eojx2 << 8 | p_esv->edata.deoj.eojx3);
909 result = -1;
910 break;
911 }
912 _ecn_tsk_eoj_get(svc, p_obj, eobjatr, false, EPC_RULE_GET, fa_fbs_id, ESV_GET_RES, ESV_GET_SNA); /* 0x72; 0x52 */
913 result = 0;
914 break;
915
916 /* 0x63 プロパティ値通知要求 */
917 case ESV_INF_REQ:
918 if (!p_obj) {
919 ECN_DBG_PUT_1("_ecn_tsk_ecn_msg_main() eoj %06X not found.",
920 p_esv->edata.deoj.eojx1 << 16 | p_esv->edata.deoj.eojx2 << 8 | p_esv->edata.deoj.eojx3);
921 result = -1;
922 break;
923 }
924 fa_fbs_id.ptr->hdr.reply.id = ENOD_MULTICAST_ID;
925 _ecn_tsk_eoj_get(svc, p_obj, eobjatr, false, (EPC_RULE_GET|EPC_RULE_ANNO), fa_fbs_id, ESV_INF, ESV_INF_SNA); /* 0x73; 0x53 */
926 result = 0;
927 break;
928
929 /* 0x6E プロパティ値書き込み・読み出し要求 */
930 case ESV_SET_GET:
931 if (!p_obj) {
932 ECN_DBG_PUT_1("_ecn_tsk_ecn_msg_main() eoj %06X not found.",
933 p_esv->edata.deoj.eojx1 << 16 | p_esv->edata.deoj.eojx2 << 8 | p_esv->edata.deoj.eojx3);
934 result = -1;
935 break;
936 }
937 _ecn_tsk_eoj_set_get(svc, p_obj, eobjatr, fromapp, fa_fbs_id, ESV_SET_GET_RES, ESV_SET_GET_SNA, &a_fbs_anno); /* 0x7E; 0x5E */
938 result = 0;
939 break;
940
941 /* 0x74 プロパティ値通知(応答要) */
942 case ESV_INFC:
943 if (!p_sobj)
944 /* 送信å…
945ƒãŒæœªçŸ¥ã®ä»–ノードであった場合、応答を返す */
946 _ecn_tsk_eoj_res(svc, fa_fbs_id, ESV_INFC_RES, ESV_INFC_RES); /* 0x7A; 0x7A */
947 else if (fromapp)
948 /* アプリケーションからの要求の場合、プロパティ値通知(応答要)を送信する */
949 _ecn_tsk_eoj_get(svc, p_sobj, sobjatr, true, (EPC_RULE_GET|EPC_RULE_ANNO), fa_fbs_id, ESV_INFC, ESV_NOP); /* 0x74; 0 */
950 else
951 /* 送信å…
952ƒãŒæ—¢çŸ¥ã®ä»–ノードであった場合、プロパティ値を更新し応答を返す */
953 _ecn_tsk_eoj_set(svc, p_sobj, sobjatr, fromapp, true, fa_fbs_id, ESV_INFC_RES, ESV_INFC_RES, &a_fbs_anno); /* 0x7A; 0x7A */
954 result = 0;
955 break;
956
957 /* 0x60 プロパティ値書き込み要求(応答不要) */
958 case ESV_SET_I_SNA: /* 0x50 プロパティ値書き込み要求不可応答 */
959 result = 1;
960 break;
961
962 /* 0x61 プロパティ値書き込み要求(応答要) */
963 case ESV_SET_RES: /* 0x71 プロパティ値書き込み応答 */
964 case ESV_SET_C_SNA: /* 0x51 プロパティ値書き込み要求不可応答 */
965 result = 1;
966 break;
967
968 /* 0x62 プロパティ値読み出し要求 */
969 case ESV_GET_RES: /* 0x72 プロパティ値読み出し応答 */
970 case ESV_GET_SNA: /* 0x52 プロパティ値読み出し不可応答 */
971 if (!p_sobj) {
972 ECN_DBG_PUT_1("_ecn_tsk_ecn_msg_main() eoj %06X not found.",
973 p_esv->edata.seoj.eojx1 << 16 | p_esv->edata.seoj.eojx2 << 8 | p_esv->edata.seoj.eojx3);
974 result = -1;
975 break;
976 }
977 _ecn_tsk_eoj_set(svc, p_sobj, sobjatr, fromapp, true, fa_fbs_id, ESV_NOP, ESV_NOP, &a_fbs_anno); /* 0; 0 */
978 result = 1;
979 break;
980
981 /* 0x63 プロパティ値通知要求 */
982 case ESV_INF: /* 0x73 プロパティ値通知 */
983 case ESV_INF_SNA: /* 0x53 プロパティ値通知不可応答 */
984 if (!p_sobj) {
985 ECN_DBG_PUT_1("_ecn_tsk_ecn_msg_main() eoj %06X not found.",
986 p_esv->edata.seoj.eojx1 << 16 | p_esv->edata.seoj.eojx2 << 8 | p_esv->edata.seoj.eojx3);
987 result = -1;
988 break;
989 }
990 _ecn_tsk_eoj_set(svc, p_sobj, sobjatr, fromapp, true, fa_fbs_id, ESV_NOP, ESV_NOP, &a_fbs_anno); /* 0; 0 */
991 result = 1;
992 break;
993
994 /* 0x6E プロパティ値書き込み・読み出し要求 */
995 case ESV_SET_GET_RES: /* 0x7E プロパティ値書き込み・読み出し応答 */
996 case ESV_SET_GET_SNA: /* 0x5E プロパティ値書き込み・読み出し不可応答 */
997 if (!p_sobj) {
998 ECN_DBG_PUT_1("_ecn_tsk_ecn_msg_main() eoj %06X not found.",
999 p_esv->edata.seoj.eojx1 << 16 | p_esv->edata.seoj.eojx2 << 8 | p_esv->edata.seoj.eojx3);
1000 result = -1;
1001 break;
1002 }
1003 _ecn_tsk_eoj_set_get_res(svc, p_sobj, sobjatr, fromapp, fa_fbs_id, &a_fbs_anno); /* 0x7A; 0 */
1004 result = 1;
1005 break;
1006
1007 /* 0x74 プロパティ値通知(応答要) */
1008 case ESV_INFC_RES: /* 0x7A プロパティ値通知応答 */
1009 result = 1;
1010 break;
1011
1012 default:
1013 ECN_DBG_PUT_1("_ecn_tsk_ecn_msg_main() esv 0x%02X undefined.", p_esv->edata.esv);
1014 result = -1;
1015 break;
1016 }
1017
1018 /* プロパティ通知要求を送信 */
1019 if (a_fbs_anno.ptr != NULL) {
1020 ER a_ret = _ecn_tsk_snd_mbx(svc, a_fbs_anno, true);
1021 if (a_ret != E_OK)
1022 _ecn_fbs_del(mrb, a_fbs_anno);
1023 }
1024
1025 return result;
1026}
1027
1028#ifdef ECN_DBG_PUT_ENA
1029static void f_put_fbs_eoj(const char *fp_fncnm, const char *fp_varnm,
1030 ECN_FBS_ID fa_fbs_id);
1031static void f_put_fbs_eoj(const char *fp_fncnm, const char *fp_varnm,
1032 ECN_FBS_ID fa_fbs_id)
1033{
1034 ECN_DBG_PUT_4("%s() %s eoj src:%06X dest:%06X",
1035 fp_fncnm, fp_varnm,
1036 ((T_EDATA *)fa_fbs_id.ptr)->hdr.edata.seoj.eojx1 << 16 | ((T_EDATA *)fa_fbs_id.ptr)->hdr.edata.seoj.eojx2 << 8 | ((T_EDATA *)fa_fbs_id.ptr)->hdr.edata.seoj.eojx3,
1037 ((T_EDATA *)fa_fbs_id.ptr)->hdr.edata.deoj.eojx1 << 16 | ((T_EDATA *)fa_fbs_id.ptr)->hdr.edata.deoj.eojx2 << 8 | ((T_EDATA *)fa_fbs_id.ptr)->hdr.edata.deoj.eojx3);
1038}
1039#else
1040#define f_put_fbs_eoj(f,v,r)
1041#endif /* #ifdef ECN_DBG_PUT_ENA */
1042
1043static const EPRPINIB *_ecn_tsk_eoj_get_property(const EOBJINIB *fp_obj, uint8_t fa_epc);
1044static const EPRPINIB *_ecn_tsk_eoj_get_property(const EOBJINIB *fp_obj, uint8_t fa_epc)
1045{
1046 const EPRPINIB **p = fp_obj->eprp;
1047 uint_t i;
1048#ifdef ECHONET_CONTROLLER_EXTENTION
1049 if (fp_obj->eprpcnt == 0) {
1050 return ecn_agent_get_property(fp_obj, fa_epc, *p);
1051 }
1052#endif
1053 for (i = 0; i < fp_obj->eprpcnt; i++, p++) {
1054 if ((*p)->eprpcd != fa_epc)
1055 continue;
1056
1057 return *p;
1058 }
1059 ECN_DBG_PUT_4("_ecn_tsk_eoj_get_property(0x%02X-0x%02X-0x%02X, epc:0x%02X) not found.",
1060 fp_obj->eojx1, fp_obj->eojx2, fp_obj->eojx3, fa_epc);
1061
1062 return NULL;
1063}
1064
1065static int _ecn_tsk_eoj_set_edt(ecnl_svc_task_t *svc, const EPRPINIB *fp_prp, void *fp_src, int fa_srcsz,
1066 bool_t *fa_anno);
1067static int _ecn_tsk_eoj_set_edt(ecnl_svc_task_t *svc, const EPRPINIB *fp_prp, void *fp_src, int fa_srcsz,
1068 bool_t *fa_anno)
1069{
1070 if (!fp_prp->eprpset)
1071 return -1;
1072
1073 ECN_DBG_PUT_1("_ecn_tsk_eoj_set_edt(epc:0x%02X) call eprpset()", fp_prp->eprpcd);
1074
1075 return fp_prp->eprpset(svc, fp_prp, fp_src, fa_srcsz, fa_anno);
1076}
1077
1078static int _ecn_tsk_eoj_get_edt(ecnl_svc_task_t *svc, const EPRPINIB *fp_prp, void *fp_dst, int fa_dstsz);
1079static int _ecn_tsk_eoj_get_edt(ecnl_svc_task_t *svc, const EPRPINIB *fp_prp, void *fp_dst, int fa_dstsz)
1080{
1081 if (fa_dstsz < fp_prp->eprpsz)
1082 return -1;
1083 if (!fp_prp->eprpget)
1084 return -1;
1085
1086 ECN_DBG_PUT_1("_ecn_tsk_eoj_get_edt(epc:0x%02X) call eprpget()", fp_prp->eprpcd);
1087
1088 return fp_prp->eprpget(svc, fp_prp, fp_dst, fp_prp->eprpsz);
1089}
1090
1091static T_ECN_SUB_BLK *_ecn_tsk_get_prp_pce(ecnl_svc_task_t *svc, ECN_FBS_ID fa_fbs_id, T_ECN_PRP *fp_prp,
1092 T_ECN_SUB_BLK *const fp_prev_blk);
1093
1094/*
1095 * ECN_FBS_IDからT_ECN_PRP1件とその付随データ(edt)を抽出し、edtのポインタを返す
1096 * 引数
1097 * ECN_FBS_ID fa_fbs_id 読み取るFBS
1098 * T_ECN_PRP *fp_prp epc+pdcの格納å…
1099ˆ
1100 * T_ECN_SUB_BLK * const fp_prev_blk 前回使ったメモリのポインタ(無ければ0)
1101 * 正常:ポインタ NG:0
1102 * ポインタは_ecn_fbs_mbx_rel()で解放する必
1103要がある
1104 */
1105static T_ECN_SUB_BLK *_ecn_tsk_get_prp_pce(ecnl_svc_task_t *svc, ECN_FBS_ID fa_fbs_id, T_ECN_PRP *fp_prp,
1106 T_ECN_SUB_BLK *const fp_prev_blk)
1107{
1108 mrb_state *mrb = svc->mrb;
1109 T_ECN_SUB_BLK *p_blk = 0;
1110 int a_size;
1111 ER a_ret;
1112
1113 /* プロパティ用メモリの取得 */
1114 if (fp_prev_blk) {
1115 p_blk = fp_prev_blk; /* 前回使ったメモリがあるなら、再利用する */
1116 }
1117 else {
1118 p_blk = (T_ECN_SUB_BLK *)_ecn_fbs_mbx_get(mrb, sizeof(*p_blk));
1119 if (!p_blk) {
1120 ECN_DBG_PUT("_ecn_fbs_mbx_get() fault.");
1121 return 0; /* メモリ不足 */
1122 }
1123 }
1124 memset(p_blk, 0, sizeof(*p_blk));
1125
1126 /* T_ECN_PRP部分(epc,pdc)を読み取る */
1127 a_size = 0;
1128 a_ret = _ecn_fbs_get_data(mrb, fa_fbs_id, fp_prp, sizeof(*fp_prp), &a_size);
1129 if (a_ret || a_size < (int)sizeof(*fp_prp)) {
1130 ECN_DBG_PUT_2("_ecn_fbs_get_data() result = %d:%s", a_ret, itron_strerror(a_ret));
1131 goto lb_except;
1132 }
1133
1134 if (0 < fp_prp->pdc) {
1135 /* 付随データ部分(edt)を読み取る */
1136 a_size = 0;
1137 a_ret = _ecn_fbs_get_data(mrb, fa_fbs_id, p_blk, fp_prp->pdc, &a_size);
1138 if (a_ret || a_size < (int)fp_prp->pdc) {
1139 ECN_DBG_PUT_2("_ecn_fbs_get_data() result = %d:%s", a_ret, itron_strerror(a_ret));
1140 goto lb_except;
1141 }
1142 }
1143
1144 return p_blk;
1145
1146lb_except:
1147 /* プロパティ用メモリ解放 */
1148 if (p_blk && !fp_prev_blk)
1149 _ecn_fbs_mbx_rel(mrb, p_blk);
1150
1151 return 0; /* 0:NG */
1152}
1153
1154static ER _ecn_tsk_eoj_set_main(ecnl_svc_task_t *svc, const EOBJINIB *fp_obj, ATR fa_eobjatr, bool_t fa_fromapp, bool_t fa_update,
1155 ECN_FBS_ID fa_fbs_id, ECN_FBS_ID a_fbs_res, ECN_FBS_ID *fa_fbs_anno, int a_count,
1156 int *p_sw_ok);
1157/* プロパティ値書き込み実行 */
1158static ER _ecn_tsk_eoj_set_main(ecnl_svc_task_t *svc, const EOBJINIB *fp_obj, ATR fa_eobjatr, bool_t fa_fromapp, bool_t fa_update,
1159 ECN_FBS_ID fa_fbs_id, ECN_FBS_ID a_fbs_res, ECN_FBS_ID *fa_fbs_anno, int a_count,
1160 int *p_sw_ok)
1161{
1162 mrb_state *mrb = svc->mrb;
1163 T_ECN_SUB_BLK *p_edt = 0;
1164 T_ECN_PRP a_prp; /* epc+pdc */
1165 const EPRPINIB *a_eprp;
1166 int i, a_ans;
1167 ER a_ret;
1168 uint8_t a_size;
1169 bool_t a_anno = false, a_update;
1170
1171 ((T_EDATA *)a_fbs_res.ptr)->hdr.edata.opc = 0;
1172
1173 for (i = 0; i < a_count; i++) {
1174 /* ECN_FBS_IDからT_ECN_PRP1件とその付随データを抽出し、そのポインタを返す */
1175 p_edt = _ecn_tsk_get_prp_pce(svc, fa_fbs_id, &a_prp, p_edt);
1176 if (!p_edt) {
1177 ECN_DBG_PUT("_ecn_tsk_eoj_set_main(): _ecn_tsk_get_prp_pce() fault.");
1178 goto lb_except;
1179 }
1180
1181 /* プロパティの設定 set_prp(obj, reqp, resp) */
1182 a_size = a_prp.pdc;
1183 /* obj,epcに対応するset関数を呼ぶ */
1184 a_eprp = _ecn_tsk_eoj_get_property(fp_obj, a_prp.epc);
1185 if ((a_eprp != NULL)
1186 && (fa_update || (((a_eprp->eprpatr & EPC_RULE_SET) != 0) || fa_fromapp))) {
1187 a_anno = (fa_eobjatr == EOBJ_LOCAL_NODE) && ((a_eprp->eprpatr & EPC_ANNOUNCE) != 0);
1188 a_update = a_anno;
1189 a_ans = _ecn_tsk_eoj_set_edt(svc, a_eprp, p_edt->payload, a_size, &a_update);
1190 if (a_anno && (a_ans > 0))
1191 a_anno = a_update;
1192 }
1193 else {
1194 a_ans = -1;
1195 }
1196 if (a_ans == a_size) {
1197 ECN_DBG_PUT_4("_ecn_tsk_eoj_set_edt(0x%06X, 0x%02x, 0x%02X..., %u) ok.",
1198 fp_obj->eojx1 << 16 | fp_obj->eojx2 << 8 | fp_obj->eojx3,
1199 a_prp.epc, p_edt->payload[0], a_size);
1200 a_prp.pdc = 0;
1201 } else {
1202 ECN_DBG_PUT_4("_ecn_tsk_eoj_set_edt(0x%06X, 0x%02x, 0x%02X..., %u) fault.",
1203 fp_obj->eojx1 << 16 | fp_obj->eojx2 << 8 | fp_obj->eojx3,
1204 a_prp.epc, p_edt->payload[0], a_size);
1205 *p_sw_ok = 0; /* プロパティ設定失敗 */
1206 /* 応答処理の場合EDTは設定しない */
1207 if (fa_update)
1208 a_prp.pdc = 0;
1209 }
1210
1211 /* 応答電文用メモリにデータ追加(epc,pdcの2byte) */
1212 a_ret = _ecn_fbs_add_data_ex(mrb, a_fbs_res, &a_prp, sizeof(a_prp));
1213 if (a_ret) {
1214 ECN_DBG_PUT_2("_ecn_fbs_add_data_ex() result = %d:%s", a_ret, itron_strerror(a_ret));
1215 goto lb_except;
1216 }
1217
1218 if (0 < a_prp.pdc) {
1219 /* 応答電文用メモリにデータ追加(edt n-byte) */
1220 a_ret = _ecn_fbs_add_data_ex(mrb, a_fbs_res, p_edt->payload, a_prp.pdc);
1221 if (a_ret) {
1222 ECN_DBG_PUT_2("_ecn_fbs_add_data_ex() result = %d:%s", a_ret, itron_strerror(a_ret));
1223 goto lb_except;
1224 }
1225 }
1226 ((T_EDATA *)a_fbs_res.ptr)->hdr.edata.opc ++;
1227
1228 /* プロパティ通知ありの場合 */
1229 if (a_anno && (a_ans == a_size)) {
1230 if (fa_fbs_anno->ptr == NULL) {
1231 _ecn_tsk_mk_esv(svc, fa_fbs_anno, (ID)1, echonet_svctask_get_eobjid(svc, fp_obj),
1232 a_prp.epc, 0, NULL, ESV_INF_REQ);
1233 }
1234 else{
1235 ecn_add_edt(mrb, (T_EDATA *)fa_fbs_anno->ptr, a_prp.epc, 0, 0);
1236 }
1237 }
1238 }
1239 a_ret = E_OK; /* ok */
1240 goto lb_finally;
1241
1242lb_except:
1243 a_ret = E_SYS;
1244
1245lb_finally:
1246 /* プロパティ用メモリ解放 */
1247 if (p_edt)
1248 _ecn_fbs_mbx_rel(mrb, p_edt);
1249
1250 return a_ret;
1251}
1252
1253static ER _ecn_tsk_eoj_get_main(ecnl_svc_task_t *svc, const EOBJINIB *fp_obj, ATR fa_eobjatr, bool_t fa_forward, ATR fa_access,
1254 ECN_FBS_ID fa_fbs_id, ECN_FBS_ID a_fbs_res, int a_count, int *p_sw_ok);
1255/* プロパティ値読み出し実行 */
1256static ER _ecn_tsk_eoj_get_main(ecnl_svc_task_t *svc, const EOBJINIB *fp_obj, ATR fa_eobjatr, bool_t fa_forward, ATR fa_access,
1257 ECN_FBS_ID fa_fbs_id, ECN_FBS_ID a_fbs_res, int a_count, int *p_sw_ok)
1258{
1259 mrb_state *mrb = svc->mrb;
1260 T_ECN_SUB_BLK *p_edt = 0;
1261 void *p_prp_buf = 0; /* 作業領域 */
1262 const EPRPINIB *a_eprp;
1263 ER a_ret = E_SYS;
1264 T_ECN_PRP a_prp; /* epc+pdc */
1265 int i, a_ans;
1266
1267 ((T_EDATA *)a_fbs_res.ptr)->hdr.edata.opc = 0;
1268
1269 /* 作業領域確保 */
1270 p_prp_buf = _ecn_fbs_mbx_get(mrb, ECHONET_MEMPOOL_BLOCK_SIZE);
1271 if (!p_prp_buf) {
1272 ECN_DBG_PUT_2("_ecn_fbs_mbx_get() result = %d:%s", a_ret, itron_strerror(a_ret));
1273 goto lb_except; /* メモリ不足 */
1274 }
1275
1276 for (i = 0; i < a_count; i++) {
1277 /* ECN_FBS_IDからT_ECN_PRP1件とその付随データを抽出 */
1278 p_edt = _ecn_tsk_get_prp_pce(svc, fa_fbs_id, &a_prp, p_edt);
1279 if (!p_edt) {
1280 ECN_DBG_PUT("_ecn_tsk_eoj_get_main(): _ecn_tsk_get_prp_pce() fault.");
1281 goto lb_except;
1282 }
1283
1284 /* プロパティの取得 get_eprp(obj, reqp, resp, size) */
1285 memset(p_prp_buf, 0, ECHONET_MEMPOOL_BLOCK_SIZE);
1286 /* obj,epcに対応するget関数を呼ぶ */
1287 a_eprp = _ecn_tsk_eoj_get_property(fp_obj, a_prp.epc);
1288 if ((a_eprp != NULL) && (((a_eprp->eprpatr & fa_access) != 0) && (fa_eobjatr == EOBJ_LOCAL_NODE) || fa_forward)) {
1289 a_ans = _ecn_tsk_eoj_get_edt(svc, a_eprp, p_prp_buf, ECHONET_MEMPOOL_BLOCK_SIZE - 1);
1290 }
1291 else {
1292 a_ans = -1;
1293 }
1294 if (0 < a_ans && a_ans <= (int)UINT8_MAX) {
1295 a_prp.pdc = (uint8_t)a_ans;
1296 } else {
1297 *p_sw_ok = 0; /* プロパティ取得失敗 */
1298 a_ans = 0;
1299 a_prp.pdc = 0;
1300 }
1301
1302 /* 応答電文用メモリにデータ追加(epc,pdcの2byte) */
1303 a_ret = _ecn_fbs_add_data_ex(mrb, a_fbs_res, &a_prp, sizeof(a_prp));
1304 if (a_ret) {
1305 ECN_DBG_PUT_2("_ecn_fbs_add_data_ex() result = %d:%s", a_ret, itron_strerror(a_ret));
1306 goto lb_except;
1307 }
1308 if (0 < a_ans) {
1309 /* 付随データ追加 */
1310 a_ret = _ecn_fbs_add_data_ex(mrb, a_fbs_res, p_prp_buf, a_ans);
1311 if (a_ret) {
1312 ECN_DBG_PUT_2("_ecn_fbs_add_data_ex() result = %d:%s", a_ret, itron_strerror(a_ret));
1313 goto lb_except;
1314 }
1315 }
1316 ((T_EDATA *)a_fbs_res.ptr)->hdr.edata.opc ++;
1317 }
1318 a_ret = E_OK; /* ok */
1319 goto lb_finally;
1320
1321lb_except:
1322 a_ret = E_SYS;
1323
1324lb_finally:
1325 /* 作業領域解放 */
1326 if (p_prp_buf)
1327 _ecn_fbs_mbx_rel(mrb, p_prp_buf);
1328
1329 /* プロパティ用メモリ解放 */
1330 if (p_edt)
1331 _ecn_fbs_mbx_rel(mrb, p_edt);
1332
1333 return a_ret;
1334}
1335
1336static ER _ecn_tsk_eoj_res_main(ecnl_svc_task_t *svc, ECN_FBS_ID fa_fbs_id, ECN_FBS_ID a_fbs_res, int a_count, int *p_sw_ok);
1337/* プロパティ値読み出し実行 */
1338static ER _ecn_tsk_eoj_res_main(ecnl_svc_task_t *svc, ECN_FBS_ID fa_fbs_id, ECN_FBS_ID a_fbs_res, int a_count, int *p_sw_ok)
1339{
1340 mrb_state *mrb = svc->mrb;
1341 T_ECN_SUB_BLK *p_edt = 0;
1342 void *p_prp_buf = 0; /* 作業領域 */
1343 ER a_ret = E_SYS;
1344 T_ECN_PRP a_prp; /* epc+pdc */
1345 int i;
1346
1347 ((T_EDATA *)a_fbs_res.ptr)->hdr.edata.opc = 0;
1348
1349 /* 作業領域確保 */
1350 p_prp_buf = _ecn_fbs_mbx_get(mrb, ECHONET_MEMPOOL_BLOCK_SIZE);
1351 if (!p_prp_buf) {
1352 ECN_DBG_PUT_2("_ecn_fbs_mbx_get() result = %d:%s", a_ret, itron_strerror(a_ret));
1353 goto lb_except; /* メモリ不足 */
1354 }
1355
1356 for (i = 0; i < a_count; i++) {
1357 /* ECN_FBS_IDからT_ECN_PRP1件とその付随データを抽出 */
1358 p_edt = _ecn_tsk_get_prp_pce(svc, fa_fbs_id, &a_prp, p_edt);
1359 if (!p_edt) {
1360 ECN_DBG_PUT("_ecn_tsk_eoj_get_main(): _ecn_tsk_get_prp_pce() fault.");
1361 goto lb_except;
1362 }
1363
1364 a_prp.pdc = 0;
1365
1366 /* 応答電文用メモリにデータ追加(epc,pdcの2byte) */
1367 a_ret = _ecn_fbs_add_data_ex(mrb, a_fbs_res, &a_prp, sizeof(a_prp));
1368 if (a_ret) {
1369 ECN_DBG_PUT_2("_ecn_fbs_add_data_ex() result = %d:%s", a_ret, itron_strerror(a_ret));
1370 goto lb_except;
1371 }
1372 ((T_EDATA *)a_fbs_res.ptr)->hdr.edata.opc++;
1373 }
1374 a_ret = E_OK; /* ok */
1375 goto lb_finally;
1376
1377lb_except:
1378 a_ret = E_SYS;
1379
1380lb_finally:
1381 /* 作業領域解放 */
1382 if (p_prp_buf)
1383 _ecn_fbs_mbx_rel(mrb, p_prp_buf);
1384
1385 /* プロパティ用メモリ解放 */
1386 if (p_edt)
1387 _ecn_fbs_mbx_rel(mrb, p_edt);
1388
1389 return a_ret;
1390}
1391
1392/* プロパティ値読み飛ばし実行 */
1393static ER _ecn_tsk_eoj_skip_main(ecnl_svc_task_t *svc, const EOBJINIB *fp_obj, ECN_FBS_ID fa_fbs_id,
1394 int a_count);
1395static ER _ecn_tsk_eoj_skip_main(ecnl_svc_task_t *svc, const EOBJINIB *fp_obj, ECN_FBS_ID fa_fbs_id,
1396 int a_count)
1397{
1398 mrb_state *mrb = svc->mrb;
1399 T_ECN_PRP a_prp; /* epc+pdc */
1400 int i, a_size;
1401 ER a_ret;
1402
1403 for (i = 0; i < a_count; i++) {
1404 /* T_ECN_PRP部分(epc,pdc)を読み取る */
1405 a_size = 0;
1406 a_ret = _ecn_fbs_get_data(mrb, fa_fbs_id, &a_prp, sizeof(a_prp), &a_size);
1407 if (a_ret || a_size < (int)sizeof(a_prp)) {
1408 ECN_DBG_PUT_2("_ecn_fbs_get_data() result = %d:%s", a_ret, itron_strerror(a_ret));
1409 goto lb_except;
1410 }
1411
1412 /* pdc分読み飛ばし */
1413 a_ret = _ecn_fbs_seek_rpos(fa_fbs_id, a_prp.pdc);
1414 if (a_ret) {
1415 ECN_DBG_PUT_2("_ecn_fbs_seek_rpos() result = %d:%s", a_ret, itron_strerror(a_ret));
1416 goto lb_except;
1417 }
1418 }
1419 a_ret = E_OK; /* ok */
1420 goto lb_finally;
1421
1422lb_except:
1423 a_ret = E_SYS;
1424
1425lb_finally:
1426 return a_ret;
1427}
1428
1429static void _ecn_tsk_mk_rsp_hdr(const EOBJINIB *fp_obj, T_ECN_EDT_HDR *fp_rsp_esv,
1430 T_ECN_EDT_HDR const *fp_req_esv);
1431/* 応答電文設定 */
1432static void _ecn_tsk_mk_rsp_hdr(const EOBJINIB *fp_obj, T_ECN_EDT_HDR *fp_rsp_esv,
1433 T_ECN_EDT_HDR const *fp_req_esv)
1434{
1435 fp_rsp_esv->ecn_hdr.ehd1 = ECN_EDH1_ECHONET_LITE;
1436 fp_rsp_esv->ecn_hdr.ehd2 = ECN_EDH2_FORMAT_1;
1437 fp_rsp_esv->ecn_hdr.tid = fp_req_esv->ecn_hdr.tid;
1438 fp_rsp_esv->edata.seoj.eojx1 = fp_obj->eojx1;
1439 fp_rsp_esv->edata.seoj.eojx2 = fp_obj->eojx2;
1440 fp_rsp_esv->edata.seoj.eojx3 = fp_obj->eojx3;
1441 fp_rsp_esv->edata.deoj = fp_req_esv->edata.seoj;
1442}
1443
1444static void _ecn_tsk_mk_rsp_hdr_res(T_ECN_EDT_HDR *fp_rsp_esv,
1445 T_ECN_EDT_HDR const *fp_req_esv);
1446static void _ecn_tsk_mk_rsp_hdr_res(T_ECN_EDT_HDR *fp_rsp_esv,
1447 T_ECN_EDT_HDR const *fp_req_esv)
1448{
1449 fp_rsp_esv->ecn_hdr.ehd1 = ECN_EDH1_ECHONET_LITE;
1450 fp_rsp_esv->ecn_hdr.ehd2 = ECN_EDH2_FORMAT_1;
1451 fp_rsp_esv->ecn_hdr.tid = fp_req_esv->ecn_hdr.tid;
1452 fp_rsp_esv->edata.seoj = fp_req_esv->edata.deoj;
1453 fp_rsp_esv->edata.deoj = fp_req_esv->edata.seoj;
1454}
1455
1456/* 応答電文用fbs設定 */
1457static void _ecn_tsk_set_rsp_fbs(ECN_FBS_ID fa_rsp_fbs, T_ECN_FST_BLK const *fp_req_ptr);
1458/* 応答電文用fbs設定(sender/targetの設定) */
1459static void _ecn_tsk_set_rsp_fbs(ECN_FBS_ID fa_rsp_fbs, T_ECN_FST_BLK const *fp_req_ptr)
1460{
1461 fa_rsp_fbs.ptr->hdr.type = ECN_MSG_ECHONET;
1462 fa_rsp_fbs.ptr->hdr.sender.id = ENOD_LOCAL_ID;
1463 fa_rsp_fbs.ptr->hdr.target.id = fp_req_ptr->hdr.reply.id;
1464 fa_rsp_fbs.ptr->hdr.reply.id = ENOD_LOCAL_ID;
1465}
1466
1467/* プロパティ値書き込み要求 */
1468static void _ecn_tsk_eoj_set(ecnl_svc_task_t *svc, const EOBJINIB *fp_obj, ATR fa_eobjatr, bool_t fa_fromapp, bool_t fa_update,
1469 ECN_FBS_ID fa_fbs_id, ECN_SRV_CODE fa_res_esv, ECN_SRV_CODE fa_sna_esv,
1470 ECN_FBS_ID *fa_fbs_anno)
1471{
1472 mrb_state *mrb = svc->mrb;
1473 T_ECN_EDT_HDR const *p_req_esv = &((T_EDATA *)fa_fbs_id.ptr)->hdr;
1474 T_ECN_EDT_HDR a_ecn_hdp;
1475 ECN_FBS_ID a_fbs_res = { 0 };
1476 ER a_ret;
1477 int a_size;
1478 int a_sw_ok = 1;
1479 T_ECN_EOJ eoj;
1480
1481 memset(&a_ecn_hdp, 0, sizeof(a_ecn_hdp));
1482
1483 /* 応答最大サイズの取得 */
1484 a_size = sizeof(T_ECN_HDR) + sizeof(T_ECN_EDATA_BODY) + sizeof(T_ECN_PRP);
1485
1486 /* 応答電文用メモリの取得 */
1487 a_ret = _ecn_fbs_cre(mrb, a_size, &a_fbs_res);
1488 if (a_ret != E_OK || !a_fbs_res.ptr) /* 確保失敗 */
1489 return;
1490
1491 /* 応答電文設定 */
1492 if(p_req_esv->edata.deoj.eojx3 != 0)
1493 _ecn_tsk_mk_rsp_hdr_res(&a_ecn_hdp, p_req_esv);
1494 else
1495 _ecn_tsk_mk_rsp_hdr(fp_obj, &a_ecn_hdp, p_req_esv);
1496
1497 /* 正常時の応答電文がプロパティ値通知応答の場合 */
1498 if (fa_res_esv == ESV_INFC_RES) {
1499 /* 送信å…
1500ƒã¨å®›å…
1501ˆã‚’å…
1502¥ã‚Œæ›¿ãˆ */
1503 eoj = a_ecn_hdp.edata.seoj;
1504 a_ecn_hdp.edata.seoj = a_ecn_hdp.edata.deoj;
1505 a_ecn_hdp.edata.deoj = eoj;
1506 }
1507
1508 f_put_fbs_eoj("_ecn_tsk_eoj_set", "fa_fbs_id", fa_fbs_id); /* s/deoj デバッグ出力 */
1509
1510 /* 応答電文用メモリにデータ追加 */
1511 a_ret = _ecn_fbs_add_data_ex(mrb, a_fbs_res, &a_ecn_hdp,
1512 sizeof(a_ecn_hdp.ecn_hdr) + sizeof(a_ecn_hdp.edata));
1513 if (a_ret)
1514 goto lb_except;
1515
1516 /* payloadå…
1517ˆé ­ã®T_ECN_HDR(ecn_hdr), T_ECN_EDATA_BODY(edata)を読み飛ばす */
1518 a_ret = _ecn_fbs_set_rpos(fa_fbs_id, offsetof(T_ECN_EDT_HDR, ecn_prp));
1519 if (a_ret)
1520 goto lb_except;
1521
1522 /* 応答電文用fbs設定 */
1523 _ecn_tsk_set_rsp_fbs(a_fbs_res, fa_fbs_id.ptr);
1524
1525 /* プロパティ値書き込み実行 */
1526 a_ret = _ecn_tsk_eoj_set_main(svc, fp_obj, fa_eobjatr, fa_fromapp, fa_update, fa_fbs_id, a_fbs_res,
1527 fa_fbs_anno, p_req_esv->edata.opc, &a_sw_ok);
1528 if (a_ret)
1529 goto lb_except;
1530
1531 /* 応答要の場合 */
1532 if (a_sw_ok) {
1533 if (!fa_res_esv) {
1534 /* 応答不要の場合 */
1535 _ecn_fbs_del(mrb, a_fbs_res);
1536 goto lb_finally;
1537 }
1538 /* 設定処理成功 */
1539 ((T_EDATA *)a_fbs_res.ptr)->hdr.edata.esv = fa_res_esv;
1540 } else {
1541 if (!fa_sna_esv) {
1542 /* 応答不要の場合 */
1543 _ecn_fbs_del(mrb, a_fbs_res);
1544 goto lb_finally;
1545 }
1546 /* 設定処理失敗 */
1547 ((T_EDATA *)a_fbs_res.ptr)->hdr.edata.esv = fa_sna_esv;
1548 }
1549 /* 応答送信 */
1550 a_ret = _ecn_tsk_snd_mbx(svc, a_fbs_res, false);
1551 if (a_ret == E_OK)
1552 goto lb_finally;
1553
1554lb_except:
1555 /* データ送信失敗したら領域解放 */
1556 if (a_fbs_res.ptr)
1557 _ecn_fbs_del(mrb, a_fbs_res);
1558
1559lb_finally:
1560 return;
1561}
1562
1563/* プロパティ値読み出し要求 */
1564static void _ecn_tsk_eoj_get(ecnl_svc_task_t *svc, const EOBJINIB *fp_obj, ATR fa_eobjatr, bool_t fa_forward, ATR fa_access,
1565 ECN_FBS_ID fa_fbs_id, ECN_SRV_CODE fa_res_esv, ECN_SRV_CODE fa_sna_esv)
1566{
1567 mrb_state *mrb = svc->mrb;
1568 T_ECN_EDT_HDR const *p_req_esv = &((T_EDATA *)fa_fbs_id.ptr)->hdr;
1569 T_ECN_EDT_HDR a_ecn_hdp;
1570 ECN_FBS_ID a_fbs_res = { 0 };
1571 ER a_ret;
1572 int a_size;
1573 int a_sw_ok = 1;
1574
1575 memset(&a_ecn_hdp, 0, sizeof(a_ecn_hdp));
1576
1577 /* 初期取得サイズ */
1578 a_size = sizeof(T_ECN_HDR) + sizeof(T_ECN_EDATA_BODY) + sizeof(T_ECN_PRP);
1579
1580 /* 応答電文用メモリの取得 */
1581 a_ret = _ecn_fbs_cre(mrb, a_size, &a_fbs_res);
1582 if (a_ret != E_OK || !a_fbs_res.ptr) { /* 確保失敗 */
1583 ECN_DBG_PUT_2("_ecn_fbs_cre() result = %d:%s", a_ret, itron_strerror(a_ret));
1584 goto lb_finally;
1585 }
1586
1587 /* 応答電文設定 */
1588 if(p_req_esv->edata.deoj.eojx3 != 0)
1589 _ecn_tsk_mk_rsp_hdr_res(&a_ecn_hdp, p_req_esv);
1590 else
1591 _ecn_tsk_mk_rsp_hdr(fp_obj, &a_ecn_hdp, p_req_esv);
1592
1593 f_put_fbs_eoj("_ecn_tsk_eoj_get", "fa_fbs_id", fa_fbs_id); /* s/deoj デバッグ出力 */
1594
1595 /* 応答電文用メモリにデータ追加 */
1596 a_ret = _ecn_fbs_add_data_ex(mrb, a_fbs_res, &a_ecn_hdp,
1597 sizeof(a_ecn_hdp.ecn_hdr) + sizeof(a_ecn_hdp.edata));
1598 if (a_ret) {
1599 ECN_DBG_PUT_2("_ecn_fbs_add_data_ex() result = %d:%s", a_ret, itron_strerror(a_ret));
1600 goto lb_except;
1601 }
1602
1603 /* payloadå…
1604ˆé ­ã®T_ECN_HDR(ecn_hdr), T_ECN_EDATA_BODY(edata)を読み飛ばす */
1605 a_ret = _ecn_fbs_set_rpos(fa_fbs_id, offsetof(T_ECN_EDT_HDR, ecn_prp));
1606 if (a_ret) {
1607 ECN_DBG_PUT_2("_ecn_fbs_set_rpos() result = %d:%s", a_ret, itron_strerror(a_ret));
1608 goto lb_except;
1609 }
1610
1611 /* 応答電文用fbs設定 */
1612 _ecn_tsk_set_rsp_fbs(a_fbs_res, fa_fbs_id.ptr);
1613
1614 /* プロパティ値読み込み実行 */
1615 a_ret = _ecn_tsk_eoj_get_main(svc, fp_obj, fa_eobjatr, fa_forward, fa_access, fa_fbs_id, a_fbs_res,
1616 ((T_EDATA *)fa_fbs_id.ptr)->hdr.edata.opc, &a_sw_ok);
1617 if (a_ret) {
1618 ECN_DBG_PUT_2("_ecn_tsk_eoj_get_main() result = %d:%s", a_ret, itron_strerror(a_ret));
1619 goto lb_except;
1620 }
1621
1622 if (a_sw_ok) {
1623 if (!fa_res_esv) {
1624 /* 応答不要の場合 */
1625 _ecn_fbs_del(mrb, a_fbs_res);
1626 goto lb_finally;
1627 }
1628 /* 設定処理成功 */
1629 ((T_EDATA *)a_fbs_res.ptr)->hdr.edata.esv = fa_res_esv;
1630 } else {
1631 if (!fa_sna_esv) {
1632 /* 応答不要の場合 */
1633 _ecn_fbs_del(mrb, a_fbs_res);
1634 goto lb_finally;
1635 }
1636 /* 設定処理失敗 */
1637 ((T_EDATA *)a_fbs_res.ptr)->hdr.edata.esv = fa_sna_esv;
1638
1639 /* 不可応答の場合は個別送信する */
1640 if (a_fbs_res.ptr->hdr.target.id == ENOD_MULTICAST_ID) {
1641 a_fbs_res.ptr->hdr.target.id = fa_fbs_id.ptr->hdr.sender.id;
1642 }
1643 }
1644 /* 応答送信 */
1645 a_ret = _ecn_tsk_snd_mbx(svc, a_fbs_res, false);
1646 if (a_ret != E_OK) {
1647 ECN_DBG_PUT_2("_ecn_tsk_snd_mbx() result = %d:%s", a_ret, itron_strerror(a_ret));
1648 goto lb_except;
1649 }
1650 goto lb_finally;
1651
1652lb_except:
1653 /* データ送信失敗したら領域解放 */
1654 if (a_fbs_res.ptr)
1655 _ecn_fbs_del(mrb, a_fbs_res);
1656
1657lb_finally:
1658 return;
1659}
1660
1661/* プロパティ値読み出し要求 */
1662static void _ecn_tsk_eoj_res(ecnl_svc_task_t *svc, ECN_FBS_ID fa_fbs_id, ECN_SRV_CODE fa_res_esv,
1663 ECN_SRV_CODE fa_sna_esv)
1664{
1665 mrb_state *mrb = svc->mrb;
1666 T_ECN_EDT_HDR const *p_req_esv = &((T_EDATA *)fa_fbs_id.ptr)->hdr;
1667 T_ECN_EDT_HDR a_ecn_hdp;
1668 ECN_FBS_ID a_fbs_res = { 0 };
1669 ER a_ret;
1670 int a_size;
1671 int a_sw_ok = 1;
1672
1673 memset(&a_ecn_hdp, 0, sizeof(a_ecn_hdp));
1674
1675 /* 初期取得サイズ */
1676 a_size = sizeof(T_ECN_HDR) + sizeof(T_ECN_EDATA_BODY) + sizeof(T_ECN_PRP);
1677
1678 /* 応答電文用メモリの取得 */
1679 a_ret = _ecn_fbs_cre(mrb, a_size, &a_fbs_res);
1680 if (a_ret != E_OK || !a_fbs_res.ptr) { /* 確保失敗 */
1681 ECN_DBG_PUT_2("_ecn_fbs_cre() result = %d:%s", a_ret, itron_strerror(a_ret));
1682 goto lb_finally;
1683 }
1684
1685 /* 応答電文設定 */
1686 _ecn_tsk_mk_rsp_hdr_res(&a_ecn_hdp, p_req_esv);
1687
1688 f_put_fbs_eoj("_ecn_tsk_eoj_res", "fa_fbs_id", fa_fbs_id); /* s/deoj デバッグ出力 */
1689
1690 /* 応答電文用メモリにデータ追加 */
1691 a_ret = _ecn_fbs_add_data_ex(mrb, a_fbs_res, &a_ecn_hdp,
1692 sizeof(a_ecn_hdp.ecn_hdr) + sizeof(a_ecn_hdp.edata));
1693 if (a_ret) {
1694 ECN_DBG_PUT_2("_ecn_fbs_add_data_ex() result = %d:%s", a_ret, itron_strerror(a_ret));
1695 goto lb_except;
1696 }
1697
1698 /* payloadå…
1699ˆé ­ã®T_ECN_HDR(ecn_hdr), T_ECN_EDATA_BODY(edata)を読み飛ばす */
1700 a_ret = _ecn_fbs_set_rpos(fa_fbs_id, offsetof(T_ECN_EDT_HDR, ecn_prp));
1701 if (a_ret) {
1702 ECN_DBG_PUT_2("_ecn_fbs_set_rpos() result = %d:%s", a_ret, itron_strerror(a_ret));
1703 goto lb_except;
1704 }
1705
1706 /* 応答電文用fbs設定 */
1707 _ecn_tsk_set_rsp_fbs(a_fbs_res, fa_fbs_id.ptr);
1708
1709 /* プロパティ値読み込み実行 */
1710 a_ret = _ecn_tsk_eoj_res_main(svc, fa_fbs_id, a_fbs_res,
1711 ((T_EDATA *)fa_fbs_id.ptr)->hdr.edata.opc, &a_sw_ok);
1712 if (a_ret) {
1713 ECN_DBG_PUT_2("_ecn_tsk_eoj_res_main() result = %d:%s", a_ret, itron_strerror(a_ret));
1714 goto lb_except;
1715 }
1716
1717 if (a_sw_ok) {
1718 if (!fa_res_esv) {
1719 /* 応答不要の場合 */
1720 _ecn_fbs_del(mrb, a_fbs_res);
1721 goto lb_finally;
1722 }
1723 /* 設定処理成功 */
1724 ((T_EDATA *)a_fbs_res.ptr)->hdr.edata.esv = fa_res_esv;
1725 } else {
1726 if (!fa_sna_esv) {
1727 /* 応答不要の場合 */
1728 _ecn_fbs_del(mrb, a_fbs_res);
1729 goto lb_finally;
1730 }
1731 /* 設定処理失敗 */
1732 ((T_EDATA *)a_fbs_res.ptr)->hdr.edata.esv = fa_sna_esv;
1733 }
1734 /* 応答送信 */
1735 a_ret = _ecn_tsk_snd_mbx(svc, a_fbs_res, false);
1736 if (a_ret != E_OK) {
1737 ECN_DBG_PUT_2("_ecn_tsk_snd_mbx() result = %d:%s", a_ret, itron_strerror(a_ret));
1738 goto lb_except;
1739 }
1740 goto lb_finally;
1741
1742lb_except:
1743 /* データ送信失敗したら領域解放 */
1744 if (a_fbs_res.ptr)
1745 _ecn_fbs_del(mrb, a_fbs_res);
1746
1747lb_finally:
1748 return;
1749}
1750
1751static void _ecn_tsk_eoj_set_get(ecnl_svc_task_t *svc, const EOBJINIB *fp_obj, ATR fa_eobjatr, bool_t fa_fromapp,
1752 ECN_FBS_ID fa_fbs_id, ECN_SRV_CODE fa_res_esv, ECN_SRV_CODE fa_sna_esv,
1753 ECN_FBS_ID *fa_fbs_anno)
1754{
1755 mrb_state *mrb = svc->mrb;
1756 T_ECN_EDT_HDR const *p_req_esv = &((T_EDATA *)fa_fbs_id.ptr)->hdr;
1757 T_ECN_EDT_HDR a_ecn_hdp;
1758 ECN_FBS_ID a_fbs_res = { 0 };
1759 int a_rdprp_wrpos; /* プロパティ読み込み件数書き込み時のヘッド位置 */
1760 ER a_ret;
1761 int i, a_size, a_rdlen;
1762 int a_sw_ok = 1;
1763 int a_count = ((T_EDATA *)fa_fbs_id.ptr)->hdr.edata.opc; /* 処理プロパティ数 */
1764
1765 memset(&a_ecn_hdp, 0, sizeof(a_ecn_hdp));
1766
1767 ECN_DBG_PUT_1("_ecn_tsk_eoj_set_get() eoj:%06X",
1768 fp_obj->eojx1 << 16 | fp_obj->eojx2 << 8 | fp_obj->eojx3);
1769
1770 /* 初期取得サイズ */
1771 a_size = sizeof(T_ECN_HDR) + sizeof(T_ECN_EDATA_BODY) + sizeof(T_ECN_PRP);
1772
1773 /* 応答電文用メモリの取得 */
1774 a_ret = _ecn_fbs_cre(mrb, a_size, &a_fbs_res);
1775 if (a_ret != E_OK || !a_fbs_res.ptr) /* 確保失敗 */
1776 goto lb_finally;
1777
1778 /* 応答電文設定 */
1779 if(p_req_esv->edata.deoj.eojx3 != 0)
1780 _ecn_tsk_mk_rsp_hdr_res(&a_ecn_hdp, p_req_esv);
1781 else
1782 _ecn_tsk_mk_rsp_hdr(fp_obj, &a_ecn_hdp, p_req_esv);
1783 a_size -= sizeof(T_ECN_HDR) + sizeof(T_ECN_EDATA_BODY);
1784
1785 f_put_fbs_eoj("_ecn_tsk_eoj_set_get", "fa_fbs_id", fa_fbs_id); /* s/deoj デバッグ出力 */
1786
1787 /* 応答電文用メモリにデータ追加 */
1788 a_ret = _ecn_fbs_add_data_ex(mrb, a_fbs_res, &a_ecn_hdp,
1789 sizeof(a_ecn_hdp.ecn_hdr) + sizeof(a_ecn_hdp.edata));
1790 if (a_ret)
1791 goto lb_except;
1792
1793 /* payloadå…
1794ˆé ­ã®T_ECN_HDR(ecn_hdr), T_ECN_EDATA_BODY(edata)を読み飛ばす */
1795 a_ret = _ecn_fbs_set_rpos(fa_fbs_id, offsetof(T_ECN_EDT_HDR, ecn_prp));
1796 if (a_ret)
1797 goto lb_except;
1798
1799 /* 応答電文用fbs設定 */
1800 _ecn_tsk_set_rsp_fbs(a_fbs_res, fa_fbs_id.ptr);
1801
1802 /* プロパティ値書き込み実行 */
1803 a_ret = _ecn_tsk_eoj_set_main(svc, fp_obj, fa_eobjatr, fa_fromapp, false, fa_fbs_id, a_fbs_res,
1804 fa_fbs_anno, a_count, &a_sw_ok);
1805 if (a_ret) {
1806 ECN_DBG_PUT_2("_ecn_tsk_eoj_set_get() eoj:%06X _ecn_tsk_eoj_set_main() fault. result = %d",
1807 fp_obj->eojx1 << 16 | fp_obj->eojx2 << 8 | fp_obj->eojx3,
1808 a_ret);
1809 goto lb_except;
1810 }
1811 ECN_DBG_PUT_2("_ecn_tsk_eoj_set_get() eoj:%06X _ecn_tsk_eoj_set_main() ok sw_ok:%s",
1812 fp_obj->eojx1 << 16 | fp_obj->eojx2 << 8 | fp_obj->eojx3,
1813 (a_sw_ok ? "true" : "false"));
1814
1815 /* 次の件数を読み取る(1byte) */
1816 /* → ECHONET-Lite_Ver.1.10_02.pdf p.40 [OPCGet] */
1817 a_rdlen = i = 0;
1818 a_ret = _ecn_fbs_get_data(mrb, fa_fbs_id, &i, 1, &a_rdlen);
1819 if (a_ret < 0 || a_rdlen < 1)
1820 goto lb_except; /* NG */
1821 a_count = *(uint8_t *)&i;
1822
1823 /* プロパティ読み込み件数書き込み時のヘッド情
1824報を記録 */
1825 a_rdprp_wrpos = _ecn_fbs_get_datalen(a_fbs_res);
1826
1827 /* 応答電文用メモリにデータ追加 (OPCGet 1byte) */
1828 a_ret = _ecn_fbs_add_data_ex(mrb, a_fbs_res, &i, 1);
1829 if (a_ret)
1830 goto lb_except;
1831
1832 /* この時点での応答電文中プロパティ件数を記録 */
1833 i = ((T_EDATA *)a_fbs_res.ptr)->hdr.edata.opc;
1834 ((T_EDATA *)a_fbs_res.ptr)->hdr.edata.opc = 0;
1835
1836 /* プロパティ値読み込み実行 */
1837 a_ret = _ecn_tsk_eoj_get_main(svc, fp_obj, fa_eobjatr, false, EPC_RULE_GET, fa_fbs_id, a_fbs_res,
1838 a_count, &a_sw_ok);
1839 if (a_ret) {
1840 ECN_DBG_PUT_2("_ecn_tsk_eoj_set_get() eoj:%06X _ecn_tsk_eoj_get_main() fault. result = %d",
1841 fp_obj->eojx1 << 16 | fp_obj->eojx2 << 8 | fp_obj->eojx3,
1842 a_ret);
1843 goto lb_except;
1844 }
1845 ECN_DBG_PUT_2("_ecn_tsk_eoj_set_get() eoj:%06X _ecn_tsk_eoj_get_main() ok sw_ok:%s",
1846 fp_obj->eojx1 << 16 | fp_obj->eojx2 << 8 | fp_obj->eojx3,
1847 (a_sw_ok ? "true" : "false"));
1848
1849 /* プロパティ読み込み件数書き込み時のヘッド情
1850報で、読み出し件数を記録 */
1851 _ecn_fbs_poke(mrb, a_fbs_res, a_rdprp_wrpos, ((T_EDATA *)a_fbs_res.ptr)->hdr.edata.opc);
1852
1853 /* 記録しておいたプロパティ件数(書き込み件数)を書き戻す */
1854 ((T_EDATA *)a_fbs_res.ptr)->hdr.edata.opc = (uint8_t)i;
1855
1856 /* 応答要の場合 */
1857 if (a_sw_ok) {
1858 /* 設定処理成功 */
1859 ((T_EDATA *)a_fbs_res.ptr)->hdr.edata.esv = fa_res_esv;
1860 } else {
1861 /* 設定処理失敗 */
1862 ((T_EDATA *)a_fbs_res.ptr)->hdr.edata.esv = fa_sna_esv;
1863 }
1864 /* 応答送信 */
1865 a_ret = _ecn_tsk_snd_mbx(svc, a_fbs_res, false);
1866 if (a_ret == E_OK)
1867 goto lb_finally;
1868
1869lb_except:
1870 /* データ送信失敗したら領域解放 */
1871 if (a_fbs_res.ptr)
1872 _ecn_fbs_del(mrb, a_fbs_res);
1873
1874lb_finally:
1875 return;
1876}
1877
1878static void _ecn_tsk_eoj_set_get_res(ecnl_svc_task_t *svc, const EOBJINIB *fp_obj, ATR fa_eobjatr,
1879 bool_t fa_fromapp, ECN_FBS_ID fa_fbs_id, ECN_FBS_ID *fa_fbs_anno)
1880{
1881 mrb_state *mrb = svc->mrb;
1882 T_ECN_EDT_HDR const *p_req_esv = &((T_EDATA *)fa_fbs_id.ptr)->hdr;
1883 T_ECN_EDT_HDR a_ecn_hdp;
1884 ECN_FBS_ID a_fbs_dmy = { 0 };
1885 ER a_ret;
1886 int i, a_size, a_rdlen;
1887 int a_sw_ok = 1;
1888 int a_count = ((T_EDATA *)fa_fbs_id.ptr)->hdr.edata.opc; /* 処理プロパティ数 */
1889
1890 memset(&a_ecn_hdp, 0, sizeof(a_ecn_hdp));
1891
1892 ECN_DBG_PUT_1("_ecn_tsk_eoj_set_get_res() eoj:%06X",
1893 fp_obj->eojx1 << 16 | fp_obj->eojx2 << 8 | fp_obj->eojx3);
1894
1895 /* 初期取得サイズ */
1896 a_size = sizeof(T_ECN_HDR) + sizeof(T_ECN_EDATA_BODY) + sizeof(T_ECN_PRP);
1897
1898 /* 応答電文用メモリ(ダミー)の取得 */
1899 a_ret = _ecn_fbs_cre(mrb, a_size, &a_fbs_dmy);
1900 if (a_ret != E_OK || !a_fbs_dmy.ptr) /* 確保失敗 */
1901 goto lb_finally;
1902
1903 /* 応答電文設定 */
1904 _ecn_tsk_mk_rsp_hdr_res(&a_ecn_hdp, p_req_esv);
1905 a_size -= sizeof(T_ECN_HDR) + sizeof(T_ECN_EDATA_BODY);
1906
1907 /* payloadå…
1908ˆé ­ã®T_ECN_HDR(ecn_hdr), T_ECN_EDATA_BODY(edata)を読み飛ばす */
1909 a_ret = _ecn_fbs_set_rpos(fa_fbs_id, offsetof(T_ECN_EDT_HDR, ecn_prp));
1910 if (a_ret)
1911 goto lb_except;
1912
1913 /* プロパティ値書き込み応答読み飛ばし実行 */
1914 a_ret = _ecn_tsk_eoj_skip_main(svc, fp_obj, fa_fbs_id, a_count);
1915 if (a_ret) {
1916 ECN_DBG_PUT_2("_ecn_tsk_eoj_set_get_res() eoj:%06X _ecn_tsk_eoj_set_main() fault. result = %d",
1917 fp_obj->eojx1 << 16 | fp_obj->eojx2 << 8 | fp_obj->eojx3,
1918 a_ret);
1919 goto lb_except;
1920 }
1921 ECN_DBG_PUT_2("_ecn_tsk_eoj_set_get_res() eoj:%06X _ecn_tsk_eoj_set_main() ok sw_ok:%s",
1922 fp_obj->eojx1 << 16 | fp_obj->eojx2 << 8 | fp_obj->eojx3,
1923 (a_sw_ok ? "true" : "false"));
1924
1925 /* 次の件数を読み取る(1byte) */
1926 /* → ECHONET-Lite_Ver.1.10_02.pdf p.40 [OPCGet] */
1927 a_rdlen = i = 0;
1928 a_ret = _ecn_fbs_get_data(mrb, fa_fbs_id, &i, 1, &a_rdlen);
1929 if (a_ret < 0 || a_rdlen < 1)
1930 goto lb_except; /* NG */
1931 a_count = *(uint8_t *)&i;
1932
1933 /* プロパティ値読み出し応答の書き込み実行 */
1934 a_ret = _ecn_tsk_eoj_set_main(svc, fp_obj, fa_eobjatr, fa_fromapp, true, fa_fbs_id, a_fbs_dmy,
1935 fa_fbs_anno, a_count, &a_sw_ok);
1936 if (a_ret) {
1937 ECN_DBG_PUT_2("_ecn_tsk_eoj_set_get_res() eoj:%06X _ecn_tsk_eoj_get_main() fault. result = %d",
1938 fp_obj->eojx1 << 16 | fp_obj->eojx2 << 8 | fp_obj->eojx3,
1939 a_ret);
1940 goto lb_except;
1941 }
1942 ECN_DBG_PUT_2("_ecn_tsk_eoj_set_get_res() eoj:%06X _ecn_tsk_eoj_get_main() ok sw_ok:%s",
1943 fp_obj->eojx1 << 16 | fp_obj->eojx2 << 8 | fp_obj->eojx3,
1944 (a_sw_ok ? "true" : "false"));
1945
1946 goto lb_finally;
1947
1948lb_except:
1949 /* データ送信失敗したら領域解放 */
1950 if (a_fbs_dmy.ptr)
1951 _ecn_fbs_del(mrb, a_fbs_dmy);
1952
1953lb_finally:
1954 return;
1955}
1956
1957/*
1958 * 応答電文待
1959ちの割り込み電文作成
1960 */
1961ER _ecn_mk_brk_wai(ecnl_svc_task_t *svc, ECN_FBS_ID *pk_fbs_id, const void *p_dat, size_t fa_size)
1962{
1963 mrb_state *mrb = svc->mrb;
1964 ER a_ret;
1965 ECN_FBS_ID a_fbs_id = { 0 }; /* 要求電文用メモリ */
1966
1967 if (!pk_fbs_id)
1968 return E_PAR;
1969 *pk_fbs_id = a_fbs_id;
1970 if (sizeof(a_fbs_id.ptr->payload) <= fa_size)
1971 return E_PAR; /* 付随データが大きすぎる */
1972 if (!p_dat && 0 < fa_size)
1973 return E_PAR; /* 付随データサイズが1以上なのにデータポインタがNULL */
1974
1975 /* 要求電文用メモリの取得 */
1976 a_ret = _ecn_fbs_cre(mrb, (0 < fa_size ? fa_size : 1), &a_fbs_id);
1977 if (a_ret != E_OK || !a_fbs_id.ptr) { /* 確保失敗 */
1978 ECN_DBG_PUT_3("_ecn_fbs_cre(%d) result = %d:%s", fa_size, a_ret, itron_strerror(a_ret));
1979 return a_ret;
1980 }
1981
1982 /* 要求電文設定 */
1983 a_fbs_id.ptr->hdr.type = ECN_MSG_USER_BREAK;
1984 a_fbs_id.ptr->hdr.sender.id = ENOD_API_ID;
1985 a_fbs_id.ptr->hdr.target.id = ENOD_API_ID;
1986 a_fbs_id.ptr->hdr.reply.id = ENOD_API_ID;
1987
1988 if (0 < fa_size && p_dat) {
1989 /* 付随データ追加 */
1990 a_ret = _ecn_fbs_add_data_ex(mrb, a_fbs_id, p_dat, fa_size);
1991 if (a_ret) {
1992 ECN_DBG_PUT_3("_ecn_fbs_add_data_ex(*, dat, %lu) result = %d:%s",
1993 fa_size,
1994 a_ret, itron_strerror(a_ret));
1995 goto lb_except;
1996 }
1997 }
1998
1999 *pk_fbs_id = a_fbs_id;
2000
2001 /* 正常終了 */
2002 return a_ret;
2003
2004lb_except:
2005 /* データ作成失敗したら領域解放 */
2006 if (a_fbs_id.ptr)
2007 _ecn_fbs_del(mrb, a_fbs_id);
2008
2009 return a_ret;
2010}
2011
2012/* 応答電文用fbs設定(sender/targetの設定) */
2013ER _ecn_tsk_cre_req_fbs(ecnl_svc_task_t *svc, T_ECN_FBS_QUEUE *sender, uint8_t cmd, ECN_FBS_ID *pk_req)
2014{
2015 mrb_state *mrb = svc->mrb;
2016 ER ret;
2017 ECN_FBS_ID req;
2018
2019 ret = _ecn_fbs_cre(mrb, 1, &req);
2020 if (ret != E_OK) {
2021 ECN_DBG_PUT_2("_ecn_tsk_cre_req_fbs() : _ecn_fbs_cre() result = %d:%s", ret, itron_strerror(ret));
2022 return ret;
2023 }
2024
2025 ret = _ecn_fbs_add_data(mrb, req, &cmd, sizeof(cmd));
2026 if (ret != E_OK) {
2027 _ecn_fbs_del(mrb, req);
2028 ECN_DBG_PUT_2("_ecn_tsk_cre_req_fbs() : _ecn_fbs_add_data() result = %d:%s", ret, itron_strerror(ret));
2029 return ret;
2030 }
2031
2032 req.ptr->hdr.type = ECN_MSG_INTERNAL;
2033 req.ptr->hdr.sender.mbxid = sender;
2034 req.ptr->hdr.target.mbxid = &svc->svc_mbxid;
2035 req.ptr->hdr.reply.mbxid = sender;
2036
2037 *pk_req = req;
2038
2039 return E_OK;
2040}
2041
2042/* 応答電文用fbs設定(sender/targetの設定) */
2043ER _ecn_tsk_cre_res_fbs(ecnl_svc_task_t *svc, ECN_FBS_ID req, uint8_t cmd, ECN_FBS_ID *pk_res)
2044{
2045 mrb_state *mrb = svc->mrb;
2046 ER ret;
2047 ECN_FBS_ID res;
2048
2049 ret = _ecn_fbs_cre(mrb, 1, &res);
2050 if (ret != E_OK) {
2051 ECN_DBG_PUT_2("_ecn_tsk_cre_res_fbs() : _ecn_fbs_cre() result = %d:%s", ret, itron_strerror(ret));
2052 return ret;
2053 }
2054
2055 ret = _ecn_fbs_add_data(mrb, res, &cmd, sizeof(cmd));
2056 if (ret != E_OK) {
2057 _ecn_fbs_del(mrb, res);
2058 ECN_DBG_PUT_2("_ecn_tsk_cre_res_fbs() : _ecn_fbs_add_data() result = %d:%s", ret, itron_strerror(ret));
2059 return ret;
2060 }
2061
2062 res.ptr->hdr.type = ECN_MSG_INTERNAL;
2063 res.ptr->hdr.sender.mbxid = &svc->svc_mbxid;
2064 res.ptr->hdr.target.mbxid = req.ptr->hdr.reply.mbxid;
2065 res.ptr->hdr.reply.mbxid = &svc->svc_mbxid;
2066
2067 *pk_res = res;
2068
2069 return E_OK;
2070}
Note: See TracBrowser for help on using the repository browser.