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

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

文字コードを設定

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