source: uKadecot/trunk/ecnl_ssp/echonet_task.c@ 108

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

MIMEプロパティの変更

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