source: UsbWattMeter/trunk/ecnl_lwip/echonet_task.c@ 473

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

MIMEにSJISを設定

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