source: asp3_tinet_ecnl_rx/trunk/ntshell/echonet/echonet_task.c@ 337

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

ASP3版ECNLを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 62.4 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$
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_dtq(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 dtqid = 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 dtqid = 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 dtqid = ecn_udp_mailboxid;
101 break;
102 case ENOD_LOCAL_ID:
103 if (from_app)
104 dtqid = ecn_svc_mailboxid;
105 else
106 dtqid = ecn_api_mailboxid;
107 break;
108 case ENOD_API_ID:
109 dtqid = 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 dtqid = ecn_udp_mailboxid;
124 break;
125 case EOBJ_ASYNC_REMOTE_NODE:
126 dtqid = ecn_svc_mailboxid;
127 break;
128 default:
129 return E_SYS;
130 }
131 }
132 else {
133 dtqid = ecn_udp_mailboxid;
134 }
135 break;
136 }
137 }
138#ifdef ECN_DBG_PUT_ENA
139 ECN_DBG_PUT("snd_dtq(%d, 0x%08X-0x%08X)", dtqid, (intptr_t)msg, a_fbs_sub1);
140 _ecn_dbg_bindmp((const uint8_t *)msg, 256);
141#endif
142 a_ret = snd_dtq(dtqid, (intptr_t)msg);
143#ifdef ECN_DBG_PUT_ENA
144 ECN_DBG_PUT("snd_dtq(%d, 0x%08X-0x%08X) result = %d:%s", dtqid, (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 int a_timer;
217#ifdef ECHONET_CONTROLLER_EXTENTION
218 int 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_2("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_dtq(ecn_svc_mailboxid, (intptr_t *)&a_mdt.p_msg, a_timer);
245 if ((a_ret != E_OK) && (a_ret != E_TMOUT)) {
246 ECN_DBG_PUT_2("trcv_dtq() 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_2("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_1("trcv_dtq() dtq 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_3("_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_5("_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_5("_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("マルチキャスト");
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_1("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_3("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));
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_1("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_3("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_4("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_1("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_dtq(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_dtq(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
683/*
684 * 電文の構成要素数とサイズのチェックを行う
685 */
686static bool_t _ecn_tsk_check_format(T_EDATA *edata, int len)
687{
688 ER ret;
689 T_ENUM_EPC enm;
690 int opc;
691 uint8_t epc;
692 uint8_t pdc;
693
694 len -= sizeof(T_ECN_HDR) + sizeof(T_ECN_EDATA_BODY);
695
696 ret = ecn_itr_ini(&enm, edata);
697 if (ret != E_OK) {
698 return false;
699 }
700 opc = enm.count;
701 for (;;) {
702 ret = ecn_itr_nxt(&enm, &epc, &pdc, NULL);
703 if (enm.is_eof)
704 break;
705 if (ret == E_BOVR){
706 if (opc != 0)
707 return false;
708 opc = enm.count;
709 len -= 1;
710 continue;
711 }
712 if (ret != E_OK)
713 break;
714
715 opc--;
716 len -= sizeof(T_ECN_PRP) + pdc;
717 }
718
719 return (opc == 0) && (len == 0);
720}
721
722static int _ecn_tsk_ecn_msg_main(ECN_FBS_ID fa_fbs_id, const EOBJINIB *p_obj, ATR eobjatr,
723 const EOBJINIB *p_sobj, ATR sobjatr);
724
725/*
726 * ECHONET用メッセージ
727 */
728static void _ecn_tsk_ecn_msg(intptr_t fa_exinf, ECN_FBS_ID fa_fbs_id)
729{
730 const EOBJCB *p_nod, *p_snod;
731 const EOBJINIB *p_obj, *p_sobj = NULL;
732 ATR eobjatr, sobjatr = EPC_NONE;
733 T_ECN_EDT_HDR *p_esv;
734 ER a_ret;
735 int i, count;
736 T_ECN_EOJ *p_eoj;
737 bool_t a_prc;
738 bool_t a_fwd;
739
740#ifdef ECN_DBG_PUT_ENA
741 syslog(LOG_NOTICE, "dtq recv:");
742 _ecn_dbg_bindmp(fa_fbs_id.ptr->bin, sizeof(fa_fbs_id.ptr->bin));
743#endif
744
745 p_esv = &((T_EDATA *)fa_fbs_id.ptr)->hdr;
746
747 if (p_esv->ecn_hdr.ehd1 != ECN_EDH1_ECHONET_LITE
748 || p_esv->ecn_hdr.ehd2 != ECN_EDH2_FORMAT_1) {
749 ECN_DBG_PUT_2("_ecn_tsk_ecn_msg() format fault: 0x%02X,0x%02X", p_esv->ecn_hdr.ehd1, p_esv->ecn_hdr.ehd2);
750 return;
751 }
752
753 if (p_esv->edata.deoj.eojx3 > 0x7F) {
754 ECN_DBG_PUT_1("_ecn_tsk_ecn_msg() format fault: deoj %06X",
755 p_esv->edata.deoj.eojx1 << 16 | p_esv->edata.deoj.eojx2 << 8 | p_esv->edata.deoj.eojx3);
756 return;
757 }
758
759 if ((p_esv->edata.seoj.eojx3 > 0x7F) || (p_esv->edata.seoj.eojx3 == 0x00)) {
760 ECN_DBG_PUT_1("_ecn_tsk_ecn_msg() format fault: seoj %06X",
761 p_esv->edata.seoj.eojx1 << 16 | p_esv->edata.seoj.eojx2 << 8 | p_esv->edata.seoj.eojx3);
762 return;
763 }
764
765 if ((p_esv->edata.esv & 0xC0) != 0x40) {
766 ECN_DBG_PUT_1("_ecn_tsk_ecn_msg() format fault: esv 0x%02X", p_esv->edata.esv);
767 return;
768 }
769
770 if (p_esv->edata.opc == 0x00) {
771 ECN_DBG_PUT_1("_ecn_tsk_ecn_msg() format fault: opc 0x%02X", p_esv->edata.opc);
772 return;
773 }
774
775 /* 電文の構成要素数とサイズのチェックを行う */
776 if (!_ecn_tsk_check_format((T_EDATA *)fa_fbs_id.ptr, fa_fbs_id.ptr->hdr.length)) {
777 ECN_DBG_PUT("_ecn_tsk_ecn_msg() format fault");
778 return;
779 }
780
781 /* 送信宛からノードを検索 */
782 p_nod = _ecn_eno_fnd(fa_fbs_id.ptr->hdr.target.id);
783 /* 送信元からノードを検索 */
784 p_snod = _ecn_eno_fnd(fa_fbs_id.ptr->hdr.sender.id);
785 if (p_snod != NULL) {
786 sobjatr = p_snod->profile->eobjatr;
787 /* ノードプロファイルの場合 */
788 if ((p_esv->edata.seoj.eojx1 == EOJ_X1_PROFILE)
789 && (p_esv->edata.seoj.eojx2 == EOJ_X2_NODE_PROFILE)) {
790 p_sobj = p_snod->profile;
791 }
792 /* 機器オブジェクトの場合 */
793 else {
794 p_sobj = _ecn_eoj_fnd(p_snod, &p_esv->edata.seoj);
795 }
796 }
797
798#ifdef ECHONET_CONTROLLER_EXTENTION
799 ecn_agent_proc_ecn_msg(&p_snod, &p_sobj, (T_EDATA *)fa_fbs_id.ptr);
800#endif
801
802 /* ノード内の機器オブジェクトを検索 */
803 a_prc = false;
804 a_fwd = false;
805 if (p_nod != NULL) {
806 eobjatr = p_nod->profile->eobjatr;
807 p_eoj = &p_esv->edata.deoj;
808 /* ノードプロファイルの場合 */
809 if ((p_eoj->eojx1 == EOJ_X1_PROFILE)
810 && (p_eoj->eojx2 == EOJ_X2_NODE_PROFILE)) {
811 if ((p_eoj->eojx3 == p_nod->profile->eojx3)
812 || (p_eoj->eojx3 == 0)) {
813 /* 電文処理実行 */
814 if (_ecn_tsk_ecn_msg_main(fa_fbs_id, p_nod->profile, eobjatr, p_sobj, sobjatr) == 1)
815 a_fwd = true;
816 a_prc = true;
817 }
818 /* 0x74 プロパティ値通知(応答要)の場合の場合は電文破棄 */
819 else if (p_esv->edata.esv == ESV_INFC) {
820 a_prc = true;
821 }
822 }
823 /* 機器オブジェクトの場合 */
824 else {
825 count = p_nod->eobjcnt;
826#ifdef ECHONET_CONTROLLER_EXTENTION
827 p_obj = NULL;
828#endif
829 for (i = 0; i < count; i++) {
830#ifdef ECHONET_CONTROLLER_EXTENTION
831 if(p_nod->eobjs == NULL)
832 p_obj = ecn_agent_next_eobj(p_nod, p_obj);
833 else
834 p_obj = p_nod->eobjs[i];
835#else
836 p_obj = p_nod->eobjs[i];
837#endif
838 if (p_obj->eojx1 != p_eoj->eojx1)
839 continue;
840 if (p_obj->eojx2 != p_eoj->eojx2)
841 continue;
842 /* インスタンスコードが0の場合、同じクラスの全てのインスタンス宛 */
843 if ((p_obj->eojx3 != p_eoj->eojx3) && (p_eoj->eojx3 != 0))
844 continue;
845
846 /* 電文処理実行 */
847 if (_ecn_tsk_ecn_msg_main(fa_fbs_id, p_obj, eobjatr, p_sobj, sobjatr) == 1)
848 a_fwd = true;
849 a_prc = true;
850 }
851
852 /* 機器オブジェクトが見つからず、0x74 プロパティ値通知(応答要)の場合は電文破棄 */
853 if (!a_prc && (p_esv->edata.esv == ESV_INFC)) {
854 a_prc = true;
855 }
856 }
857 }
858 /* 機器オブジェクトが見つからない場合でも */
859 if (!a_prc) {
860 /* 電文処理実行(応答受信用) */
861 if (_ecn_tsk_ecn_msg_main(fa_fbs_id, NULL, EPC_NONE, p_sobj, sobjatr) == 1)
862 a_fwd = true;
863 }
864
865 /* 応答の場合アプリケーションに転送する */
866 if (a_fwd && (p_esv->ecn_hdr.tid == g_api_tid)) {
867 g_release_esv = false;
868
869 ECN_CAP_PUT_1("redirect ecn_svc_mailboxid → ecn_api_mailboxid (esv:0x%02X)",
870 p_esv->edata.esv);
871 fa_fbs_id.ptr->hdr.target.id = ENOD_API_ID;
872 a_ret = snd_dtq(ecn_api_mailboxid, (intptr_t)fa_fbs_id.ptr);
873 if (a_ret != E_OK) {
874 syslog(LOG_WARNING, "_ecn_tsk_ecn_msg() : snd_dtq() result = %d:%s", a_ret, itron_strerror(a_ret));
875 _ecn_fbs_del(fa_fbs_id);
876 }
877 }
878#ifdef ECHONET_CONTROLLER_EXTENTION
879 ecn_agent_proc_ecn_msg_end();
880#endif
881}
882
883static int _ecn_tsk_ecn_msg_main(ECN_FBS_ID fa_fbs_id, const EOBJINIB *p_obj, ATR eobjatr,
884 const EOBJINIB *p_sobj, ATR sobjatr)
885{
886 int result;
887 T_ECN_EDT_HDR *p_esv;
888 ECN_FBS_ID a_fbs_anno = { NULL };
889 bool_t fromapp = sobjatr == EOBJ_LOCAL_NODE;
890
891 p_esv = &((T_EDATA *)fa_fbs_id.ptr)->hdr;
892
893 switch (p_esv->edata.esv) {
894 /* 0x60 プロパティ値書き込み要求(応答不要) */
895 case ESV_SET_I:
896 if (!p_obj) {
897 ECN_DBG_PUT_1("_ecn_tsk_ecn_msg_main() eoj %06X not found.",
898 p_esv->edata.deoj.eojx1 << 16 | p_esv->edata.deoj.eojx2 << 8 | p_esv->edata.deoj.eojx3);
899 result = -1;
900 break;
901 }
902 _ecn_tsk_eoj_set(p_obj, eobjatr, fromapp, false, fa_fbs_id, ESV_NOP, ESV_SET_I_SNA, &a_fbs_anno); /* 0; 0x50 */
903 result = 0;
904 break;
905
906 /* 0x61 プロパティ値書き込み要求(応答要) */
907 case ESV_SET_C:
908 if (!p_obj) {
909 ECN_DBG_PUT_1("_ecn_tsk_ecn_msg_main() eoj %06X not found.",
910 p_esv->edata.deoj.eojx1 << 16 | p_esv->edata.deoj.eojx2 << 8 | p_esv->edata.deoj.eojx3);
911 result = -1;
912 break;
913 }
914 _ecn_tsk_eoj_set(p_obj, eobjatr, fromapp, false, fa_fbs_id, ESV_SET_RES, ESV_SET_C_SNA, &a_fbs_anno); /* 0x71; 0x51 */
915 result = 0;
916 break;
917
918 /* 0x62 プロパティ値読み出し要求 */
919 case ESV_GET:
920 if (!p_obj) {
921 ECN_DBG_PUT_1("_ecn_tsk_ecn_msg_main() eoj %06X not found.",
922 p_esv->edata.deoj.eojx1 << 16 | p_esv->edata.deoj.eojx2 << 8 | p_esv->edata.deoj.eojx3);
923 result = -1;
924 break;
925 }
926 _ecn_tsk_eoj_get(p_obj, eobjatr, false, EPC_RULE_GET, fa_fbs_id, ESV_GET_RES, ESV_GET_SNA); /* 0x72; 0x52 */
927 result = 0;
928 break;
929
930 /* 0x63 プロパティ値通知要求 */
931 case ESV_INF_REQ:
932 if (!p_obj) {
933 ECN_DBG_PUT_1("_ecn_tsk_ecn_msg_main() eoj %06X not found.",
934 p_esv->edata.deoj.eojx1 << 16 | p_esv->edata.deoj.eojx2 << 8 | p_esv->edata.deoj.eojx3);
935 result = -1;
936 break;
937 }
938 fa_fbs_id.ptr->hdr.reply.id = ENOD_MULTICAST_ID;
939 _ecn_tsk_eoj_get(p_obj, eobjatr, false, (EPC_RULE_GET|EPC_RULE_ANNO), fa_fbs_id, ESV_INF, ESV_INF_SNA); /* 0x73; 0x53 */
940 result = 0;
941 break;
942
943 /* 0x6E プロパティ値書き込み・読み出し要求 */
944 case ESV_SET_GET:
945 if (!p_obj) {
946 ECN_DBG_PUT_1("_ecn_tsk_ecn_msg_main() eoj %06X not found.",
947 p_esv->edata.deoj.eojx1 << 16 | p_esv->edata.deoj.eojx2 << 8 | p_esv->edata.deoj.eojx3);
948 result = -1;
949 break;
950 }
951 _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 */
952 result = 0;
953 break;
954
955 /* 0x74 プロパティ値通知(応答要) */
956 case ESV_INFC:
957 if (!p_sobj)
958 /* 送信元が未知の他ノードであった場合、応答を返す */
959 _ecn_tsk_eoj_res(fa_fbs_id, ESV_INFC_RES, ESV_INFC_RES); /* 0x7A; 0x7A */
960 else if (fromapp)
961 /* アプリケーションからの要求の場合、プロパティ値通知(応答要)を送信する */
962 _ecn_tsk_eoj_get(p_sobj, sobjatr, true, (EPC_RULE_GET|EPC_RULE_ANNO), fa_fbs_id, ESV_INFC, ESV_NOP); /* 0x74; 0 */
963 else
964 /* 送信元が既知の他ノードであった場合、プロパティ値を更新し応答を返す */
965 _ecn_tsk_eoj_set(p_sobj, sobjatr, fromapp, true, fa_fbs_id, ESV_INFC_RES, ESV_INFC_RES, &a_fbs_anno); /* 0x7A; 0x7A */
966 result = 0;
967 break;
968
969 /* 0x60 プロパティ値書き込み要求(応答不要) */
970 case ESV_SET_I_SNA: /* 0x50 プロパティ値書き込み要求不可応答 */
971 result = 1;
972 break;
973
974 /* 0x61 プロパティ値書き込み要求(応答要) */
975 case ESV_SET_RES: /* 0x71 プロパティ値書き込み応答 */
976 case ESV_SET_C_SNA: /* 0x51 プロパティ値書き込み要求不可応答 */
977 result = 1;
978 break;
979
980 /* 0x62 プロパティ値読み出し要求 */
981 case ESV_GET_RES: /* 0x72 プロパティ値読み出し応答 */
982 case ESV_GET_SNA: /* 0x52 プロパティ値読み出し不可応答 */
983 if (!p_sobj) {
984 ECN_DBG_PUT_1("_ecn_tsk_ecn_msg_main() eoj %06X not found.",
985 p_esv->edata.seoj.eojx1 << 16 | p_esv->edata.seoj.eojx2 << 8 | p_esv->edata.seoj.eojx3);
986 result = -1;
987 break;
988 }
989 _ecn_tsk_eoj_set(p_sobj, sobjatr, fromapp, true, fa_fbs_id, ESV_NOP, ESV_NOP, &a_fbs_anno); /* 0; 0 */
990 result = 1;
991 break;
992
993 /* 0x63 プロパティ値通知要求 */
994 case ESV_INF: /* 0x73 プロパティ値通知 */
995 case ESV_INF_SNA: /* 0x53 プロパティ値通知不可応答 */
996 if (!p_sobj) {
997 ECN_DBG_PUT_1("_ecn_tsk_ecn_msg_main() eoj %06X not found.",
998 p_esv->edata.seoj.eojx1 << 16 | p_esv->edata.seoj.eojx2 << 8 | p_esv->edata.seoj.eojx3);
999 result = -1;
1000 break;
1001 }
1002 _ecn_tsk_eoj_set(p_sobj, sobjatr, fromapp, true, fa_fbs_id, ESV_NOP, ESV_NOP, &a_fbs_anno); /* 0; 0 */
1003 result = 1;
1004 break;
1005
1006 /* 0x6E プロパティ値書き込み・読み出し要求 */
1007 case ESV_SET_GET_RES: /* 0x7E プロパティ値書き込み・読み出し応答 */
1008 case ESV_SET_GET_SNA: /* 0x5E プロパティ値書き込み・読み出し不可応答 */
1009 if (!p_sobj) {
1010 ECN_DBG_PUT_1("_ecn_tsk_ecn_msg_main() eoj %06X not found.",
1011 p_esv->edata.seoj.eojx1 << 16 | p_esv->edata.seoj.eojx2 << 8 | p_esv->edata.seoj.eojx3);
1012 result = -1;
1013 break;
1014 }
1015 _ecn_tsk_eoj_set_get_res(p_sobj, sobjatr, fromapp, fa_fbs_id, &a_fbs_anno); /* 0x7A; 0 */
1016 result = 1;
1017 break;
1018
1019 /* 0x74 プロパティ値通知(応答要) */
1020 case ESV_INFC_RES: /* 0x7A プロパティ値通知応答 */
1021 result = 1;
1022 break;
1023
1024 default:
1025 syslog(LOG_WARNING, "_ecn_tsk_ecn_msg_main() esv 0x%02X undefined.", p_esv->edata.esv);
1026 result = -1;
1027 break;
1028 }
1029
1030 /* プロパティ通知要求を送信 */
1031 if (a_fbs_anno.ptr != NULL) {
1032 ER a_ret = _ecn_tsk_snd_dtq(a_fbs_anno, true);
1033 if (a_ret != E_OK)
1034 _ecn_fbs_del(a_fbs_anno);
1035 }
1036
1037 return result;
1038}
1039
1040#ifdef ECN_DBG_PUT_ENA
1041static void f_put_fbs_eoj(const char *fp_fncnm, const char *fp_varnm,
1042 ECN_FBS_ID fa_fbs_id);
1043static void f_put_fbs_eoj(const char *fp_fncnm, const char *fp_varnm,
1044 ECN_FBS_ID fa_fbs_id)
1045{
1046 ECN_DBG_PUT("%s() %s eoj src:%06X dest:%06X",
1047 fp_fncnm, fp_varnm,
1048 ((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,
1049 ((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);
1050}
1051#else
1052#define f_put_fbs_eoj(f,v,r)
1053#endif /* #ifdef ECN_DBG_PUT_ENA */
1054
1055static const EPRPINIB *_ecn_tsk_eoj_get_property(const EOBJINIB *fp_obj, uint8_t fa_epc);
1056static const EPRPINIB *_ecn_tsk_eoj_get_property(const EOBJINIB *fp_obj, uint8_t fa_epc)
1057{
1058 const EPRPINIB *p = fp_obj->eprp;
1059 uint_t i;
1060#ifdef ECHONET_CONTROLLER_EXTENTION
1061 if (fp_obj->eprpcnt == 0) {
1062 return ecn_agent_get_property(fp_obj, fa_epc, p);
1063 }
1064#endif
1065 for (i = 0; i < fp_obj->eprpcnt; i++, p++) {
1066 if (p->eprpcd != fa_epc)
1067 continue;
1068
1069 return p;
1070 }
1071 ECN_DBG_PUT_4("_ecn_tsk_eoj_get_property(0x%02X-0x%02X-0x%02X, epc:0x%02X) not found.",
1072 fp_obj->eojx1, fp_obj->eojx2, fp_obj->eojx3,
1073 fa_epc);
1074
1075 return NULL;
1076}
1077
1078static int _ecn_tsk_eoj_set_edt(const EPRPINIB *fp_prp, void *fp_src, int fa_srcsz,
1079 bool_t *fa_anno);
1080static int _ecn_tsk_eoj_set_edt(const EPRPINIB *fp_prp, void *fp_src, int fa_srcsz,
1081 bool_t *fa_anno)
1082{
1083 if (!fp_prp->eprpset)
1084 return -1;
1085
1086 ECN_DBG_PUT_1("_ecn_tsk_eoj_set_edt(epc:0x%02X) call eprpset()",
1087 fp_prp->eprpcd);
1088
1089 return fp_prp->eprpset(fp_prp, fp_src, fa_srcsz, fa_anno);
1090}
1091
1092static int _ecn_tsk_eoj_get_edt(const EPRPINIB *fp_prp, void *fp_dst, int fa_dstsz);
1093static int _ecn_tsk_eoj_get_edt(const EPRPINIB *fp_prp, void *fp_dst, int fa_dstsz)
1094{
1095 if (fa_dstsz < fp_prp->eprpsz)
1096 return -1;
1097 if (!fp_prp->eprpget)
1098 return -1;
1099
1100 ECN_DBG_PUT_1("_ecn_tsk_eoj_get_edt(epc:0x%02X) call eprpget()",
1101 fp_prp->eprpcd);
1102
1103 return fp_prp->eprpget(fp_prp, fp_dst, fp_prp->eprpsz);
1104}
1105
1106static T_ECN_SUB_BLK *_ecn_tsk_get_prp_pce(ECN_FBS_ID fa_fbs_id, T_ECN_PRP *fp_prp,
1107 T_ECN_SUB_BLK *const fp_prev_blk);
1108
1109/*
1110 * ECN_FBS_IDからT_ECN_PRP1件とその付随データ(edt)を抽出し、edtのポインタを返す
1111 * 引数
1112 * ECN_FBS_ID fa_fbs_id 読み取るFBS
1113 * T_ECN_PRP *fp_prp epc+pdcの格納先
1114 * T_ECN_SUB_BLK * const fp_prev_blk 前回使ったメモリのポインタ(無ければ0)
1115 * 正常:ポインタ NG:0
1116 * ポインタは_ecn_fbs_dtq_rel()で解放する必要がある
1117 */
1118static T_ECN_SUB_BLK *_ecn_tsk_get_prp_pce(ECN_FBS_ID fa_fbs_id, T_ECN_PRP *fp_prp,
1119 T_ECN_SUB_BLK *const fp_prev_blk)
1120{
1121 T_ECN_SUB_BLK *p_blk = 0;
1122 int a_size;
1123 ER a_ret;
1124
1125 /* プロパティ用メモリの取得 */
1126 if (fp_prev_blk) {
1127 p_blk = fp_prev_blk; /* 前回使ったメモリがあるなら、再利用する */
1128 }
1129 else {
1130 p_blk = (T_ECN_SUB_BLK *)_ecn_fbs_dtq_get(sizeof(*p_blk));
1131 if (!p_blk) {
1132 ECN_DBG_PUT("_ecn_fbs_dtq_get() fault.");
1133 return 0; /* メモリ不足 */
1134 }
1135 }
1136 memset(p_blk, 0, sizeof(*p_blk));
1137
1138 /* T_ECN_PRP部分(epc,pdc)を読み取る */
1139 a_size = 0;
1140 a_ret = _ecn_fbs_get_data(fa_fbs_id, fp_prp, sizeof(*fp_prp), &a_size);
1141 if (a_ret || a_size < (int)sizeof(*fp_prp)) {
1142 ECN_DBG_PUT_2("_ecn_fbs_get_data() result = %d:%s", a_ret, itron_strerror(a_ret));
1143 goto lb_except;
1144 }
1145
1146 if (0 < fp_prp->pdc) {
1147 /* 付随データ部分(edt)を読み取る */
1148 a_size = 0;
1149 a_ret = _ecn_fbs_get_data(fa_fbs_id, p_blk, fp_prp->pdc, &a_size);
1150 if (a_ret || a_size < (int)fp_prp->pdc) {
1151 ECN_DBG_PUT_2("_ecn_fbs_get_data() result = %d:%s", a_ret, itron_strerror(a_ret));
1152 goto lb_except;
1153 }
1154 }
1155
1156 return p_blk;
1157
1158lb_except:
1159 /* プロパティ用メモリ解放 */
1160 if (p_blk && !fp_prev_blk)
1161 _ecn_fbs_dtq_rel(p_blk);
1162
1163 return 0; /* 0:NG */
1164}
1165
1166static ER _ecn_tsk_eoj_set_main(const EOBJINIB *fp_obj, ATR fa_eobjatr, bool_t fa_fromapp, bool_t fa_update,
1167 ECN_FBS_ID fa_fbs_id, ECN_FBS_ID a_fbs_res, ECN_FBS_ID *fa_fbs_anno, int a_count,
1168 int *p_sw_ok);
1169/* プロパティ値書き込み実行 */
1170static ER _ecn_tsk_eoj_set_main(const EOBJINIB *fp_obj, ATR fa_eobjatr, bool_t fa_fromapp, bool_t fa_update,
1171 ECN_FBS_ID fa_fbs_id, ECN_FBS_ID a_fbs_res, ECN_FBS_ID *fa_fbs_anno, int a_count,
1172 int *p_sw_ok)
1173{
1174 T_ECN_SUB_BLK *p_edt = 0;
1175 T_ECN_PRP a_prp; /* epc+pdc */
1176 const EPRPINIB *a_eprp;
1177 int i, a_ans;
1178 ER a_ret;
1179 uint8_t a_size;
1180 bool_t a_anno = false, a_update;
1181
1182 ((T_EDATA *)a_fbs_res.ptr)->hdr.edata.opc = 0;
1183
1184 for (i = 0; i < a_count; i++) {
1185 /* ECN_FBS_IDからT_ECN_PRP1件とその付随データを抽出し、そのポインタを返す */
1186 p_edt = _ecn_tsk_get_prp_pce(fa_fbs_id, &a_prp, p_edt);
1187 if (!p_edt) {
1188 ECN_DBG_PUT("_ecn_tsk_eoj_set_main(): _ecn_tsk_get_prp_pce() fault.");
1189 goto lb_except;
1190 }
1191
1192 /* プロパティの設定 set_prp(obj, reqp, resp) */
1193 a_size = a_prp.pdc;
1194 /* obj,epcに対応するset関数を呼ぶ */
1195 a_eprp = _ecn_tsk_eoj_get_property(fp_obj, a_prp.epc);
1196 if ((a_eprp != NULL)
1197 && (fa_update || (((a_eprp->eprpatr & EPC_RULE_SET) != 0) || fa_fromapp))) {
1198 a_anno = (fa_eobjatr == EOBJ_LOCAL_NODE) && ((a_eprp->eprpatr & EPC_ANNOUNCE) != 0);
1199 a_update = a_anno;
1200 a_ans = _ecn_tsk_eoj_set_edt(a_eprp, p_edt->payload, a_size, &a_update);
1201 if (a_anno && (a_ans > 0))
1202 a_anno = a_update;
1203 }
1204 else {
1205 a_ans = -1;
1206 }
1207 if (a_ans == a_size) {
1208 ECN_DBG_PUT_4("_ecn_tsk_eoj_set_edt(0x%06X, 0x%02x, 0x%02X..., %u) ok.",
1209 fp_obj->eojx1 << 16 | fp_obj->eojx2 << 8 | fp_obj->eojx3,
1210 a_prp.epc, p_edt->payload[0], a_size);
1211 a_prp.pdc = 0;
1212 } else {
1213 ECN_DBG_PUT_4("_ecn_tsk_eoj_set_edt(0x%06X, 0x%02x, 0x%02X..., %u) fault.",
1214 fp_obj->eojx1 << 16 | fp_obj->eojx2 << 8 | fp_obj->eojx3,
1215 a_prp.epc, p_edt->payload[0], a_size);
1216 *p_sw_ok = 0; /* プロパティ設定失敗 */
1217 /* 応答処理の場合EDTは設定しない */
1218 if (fa_update)
1219 a_prp.pdc = 0;
1220 }
1221
1222 /* 応答電文用メモリにデータ追加(epc,pdcの2byte) */
1223 a_ret = _ecn_fbs_add_data_ex(a_fbs_res, &a_prp, sizeof(a_prp));
1224 if (a_ret) {
1225 ECN_DBG_PUT_2("_ecn_fbs_add_data_ex() result = %d:%s", a_ret, itron_strerror(a_ret));
1226 goto lb_except;
1227 }
1228
1229 if (0 < a_prp.pdc) {
1230 /* 応答電文用メモリにデータ追加(edt n-byte) */
1231 a_ret = _ecn_fbs_add_data_ex(a_fbs_res, p_edt->payload, a_prp.pdc);
1232 if (a_ret) {
1233 ECN_DBG_PUT_2("_ecn_fbs_add_data_ex() result = %d:%s", a_ret, itron_strerror(a_ret));
1234 goto lb_except;
1235 }
1236 }
1237 ((T_EDATA *)a_fbs_res.ptr)->hdr.edata.opc ++;
1238
1239 /* プロパティ通知ありの場合 */
1240 if (a_anno && (a_ans == a_size)) {
1241 if (fa_fbs_anno->ptr == NULL) {
1242 _ecn_tsk_mk_esv(fa_fbs_anno, (ID)1, (((intptr_t)fp_obj - (intptr_t)eobjinib_table) / sizeof(EPRPINIB)) + 1,
1243 a_prp.epc, 0, NULL, ESV_INF_REQ);
1244 }
1245 else{
1246 ecn_add_edt((T_EDATA *)fa_fbs_anno->ptr, a_prp.epc, 0, 0);
1247 }
1248 }
1249 }
1250 a_ret = E_OK; /* ok */
1251 goto lb_finally;
1252
1253lb_except:
1254 a_ret = E_SYS;
1255
1256lb_finally:
1257 /* プロパティ用メモリ解放 */
1258 if (p_edt)
1259 _ecn_fbs_dtq_rel(p_edt);
1260
1261 return a_ret;
1262}
1263
1264static ER _ecn_tsk_eoj_get_main(const EOBJINIB *fp_obj, ATR fa_eobjatr, bool_t fa_forward, ATR fa_access,
1265 ECN_FBS_ID fa_fbs_id, ECN_FBS_ID a_fbs_res, int a_count, int *p_sw_ok);
1266/* プロパティ値読み出し実行 */
1267static ER _ecn_tsk_eoj_get_main(const EOBJINIB *fp_obj, ATR fa_eobjatr, bool_t fa_forward, ATR fa_access,
1268 ECN_FBS_ID fa_fbs_id, ECN_FBS_ID a_fbs_res, int a_count, int *p_sw_ok)
1269{
1270 T_ECN_SUB_BLK *p_edt = 0;
1271 void *p_prp_buf = 0; /* 作業領域 */
1272 const EPRPINIB *a_eprp;
1273 ER a_ret = E_SYS;
1274 T_ECN_PRP a_prp; /* epc+pdc */
1275 int i, a_ans;
1276
1277 ((T_EDATA *)a_fbs_res.ptr)->hdr.edata.opc = 0;
1278
1279 /* 作業領域確保 */
1280 p_prp_buf = _ecn_fbs_dtq_get(ECHONET_MEMPOOL_BLOCK_SIZE);
1281 if (!p_prp_buf) {
1282 ECN_DBG_PUT_2("_ecn_fbs_dtq_get() result = %d:%s", a_ret, itron_strerror(a_ret));
1283 goto lb_except; /* メモリ不足 */
1284 }
1285
1286 for (i = 0; i < a_count; i++) {
1287 /* ECN_FBS_IDからT_ECN_PRP1件とその付随データを抽出 */
1288 p_edt = _ecn_tsk_get_prp_pce(fa_fbs_id, &a_prp, p_edt);
1289 if (!p_edt) {
1290 ECN_DBG_PUT("_ecn_tsk_eoj_get_main(): _ecn_tsk_get_prp_pce() fault.");
1291 goto lb_except;
1292 }
1293
1294 /* プロパティの取得 get_eprp(obj, reqp, resp, size) */
1295 memset(p_prp_buf, 0, ECHONET_MEMPOOL_BLOCK_SIZE);
1296 /* obj,epcに対応するget関数を呼ぶ */
1297 a_eprp = _ecn_tsk_eoj_get_property(fp_obj, a_prp.epc);
1298 if ((a_eprp != NULL) && (((a_eprp->eprpatr & fa_access) != 0) && ((fa_eobjatr == EOBJ_LOCAL_NODE) || fa_forward))) {
1299 a_ans = _ecn_tsk_eoj_get_edt(a_eprp, p_prp_buf, ECHONET_MEMPOOL_BLOCK_SIZE - 1);
1300 }
1301 else {
1302 a_ans = -1;
1303 }
1304 if (0 < a_ans && a_ans <= (int)UINT8_MAX) {
1305 a_prp.pdc = (uint8_t)a_ans;
1306 } else {
1307 *p_sw_ok = 0; /* プロパティ取得失敗 */
1308 a_ans = 0;
1309 a_prp.pdc = 0;
1310 }
1311
1312 /* 応答電文用メモリにデータ追加(epc,pdcの2byte) */
1313 a_ret = _ecn_fbs_add_data_ex(a_fbs_res, &a_prp, sizeof(a_prp));
1314 if (a_ret) {
1315 ECN_DBG_PUT_2("_ecn_fbs_add_data_ex() result = %d:%s", a_ret, itron_strerror(a_ret));
1316 goto lb_except;
1317 }
1318 if (0 < a_ans) {
1319 /* 付随データ追加 */
1320 a_ret = _ecn_fbs_add_data_ex(a_fbs_res, p_prp_buf, a_ans);
1321 if (a_ret) {
1322 ECN_DBG_PUT_2("_ecn_fbs_add_data_ex() result = %d:%s", a_ret, itron_strerror(a_ret));
1323 goto lb_except;
1324 }
1325 }
1326 ((T_EDATA *)a_fbs_res.ptr)->hdr.edata.opc ++;
1327 }
1328 a_ret = E_OK; /* ok */
1329 goto lb_finally;
1330
1331lb_except:
1332 a_ret = E_SYS;
1333
1334lb_finally:
1335 /* 作業領域解放 */
1336 if (p_prp_buf)
1337 _ecn_fbs_dtq_rel(p_prp_buf);
1338
1339 /* プロパティ用メモリ解放 */
1340 if (p_edt)
1341 _ecn_fbs_dtq_rel(p_edt);
1342
1343 return a_ret;
1344}
1345
1346static 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);
1347/* プロパティ値読み出し実行 */
1348static 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)
1349{
1350 T_ECN_SUB_BLK *p_edt = 0;
1351 void *p_prp_buf = 0; /* 作業領域 */
1352 ER a_ret = E_SYS;
1353 T_ECN_PRP a_prp; /* epc+pdc */
1354 int i;
1355
1356 ((T_EDATA *)a_fbs_res.ptr)->hdr.edata.opc = 0;
1357
1358 /* 作業領域確保 */
1359 p_prp_buf = _ecn_fbs_dtq_get(ECHONET_MEMPOOL_BLOCK_SIZE);
1360 if (!p_prp_buf) {
1361 ECN_DBG_PUT_2("_ecn_fbs_dtq_get() result = %d:%s", a_ret, itron_strerror(a_ret));
1362 goto lb_except; /* メモリ不足 */
1363 }
1364
1365 for (i = 0; i < a_count; i++) {
1366 /* ECN_FBS_IDからT_ECN_PRP1件とその付随データを抽出 */
1367 p_edt = _ecn_tsk_get_prp_pce(fa_fbs_id, &a_prp, p_edt);
1368 if (!p_edt) {
1369 ECN_DBG_PUT("_ecn_tsk_eoj_get_main(): _ecn_tsk_get_prp_pce() fault.");
1370 goto lb_except;
1371 }
1372
1373 a_prp.pdc = 0;
1374
1375 /* 応答電文用メモリにデータ追加(epc,pdcの2byte) */
1376 a_ret = _ecn_fbs_add_data_ex(a_fbs_res, &a_prp, sizeof(a_prp));
1377 if (a_ret) {
1378 ECN_DBG_PUT_2("_ecn_fbs_add_data_ex() result = %d:%s", a_ret, itron_strerror(a_ret));
1379 goto lb_except;
1380 }
1381 ((T_EDATA *)a_fbs_res.ptr)->hdr.edata.opc++;
1382 }
1383 a_ret = E_OK; /* ok */
1384 goto lb_finally;
1385
1386lb_except:
1387 a_ret = E_SYS;
1388
1389lb_finally:
1390 /* 作業領域解放 */
1391 if (p_prp_buf)
1392 _ecn_fbs_dtq_rel(p_prp_buf);
1393
1394 /* プロパティ用メモリ解放 */
1395 if (p_edt)
1396 _ecn_fbs_dtq_rel(p_edt);
1397
1398 return a_ret;
1399}
1400
1401/* プロパティ値読み飛ばし実行 */
1402static ER _ecn_tsk_eoj_skip_main(const EOBJINIB *fp_obj, ECN_FBS_ID fa_fbs_id,
1403 int a_count);
1404static ER _ecn_tsk_eoj_skip_main(const EOBJINIB *fp_obj, ECN_FBS_ID fa_fbs_id,
1405 int a_count)
1406{
1407 T_ECN_PRP a_prp; /* epc+pdc */
1408 int i, a_size;
1409 ER a_ret;
1410
1411 for (i = 0; i < a_count; i++) {
1412 /* T_ECN_PRP部分(epc,pdc)を読み取る */
1413 a_size = 0;
1414 a_ret = _ecn_fbs_get_data(fa_fbs_id, &a_prp, sizeof(a_prp), &a_size);
1415 if (a_ret || a_size < (int)sizeof(a_prp)) {
1416 ECN_DBG_PUT_2("_ecn_fbs_get_data() result = %d:%s", a_ret, itron_strerror(a_ret));
1417 goto lb_except;
1418 }
1419
1420 /* pdc分読み飛ばし */
1421 a_ret = _ecn_fbs_seek_rpos(fa_fbs_id, a_prp.pdc);
1422 if (a_ret) {
1423 ECN_DBG_PUT_2("_ecn_fbs_seek_rpos() result = %d:%s", a_ret, itron_strerror(a_ret));
1424 goto lb_except;
1425 }
1426 }
1427 a_ret = E_OK; /* ok */
1428 goto lb_finally;
1429
1430lb_except:
1431 a_ret = E_SYS;
1432
1433lb_finally:
1434 return a_ret;
1435}
1436
1437static void _ecn_tsk_mk_rsp_hdr(const EOBJINIB *fp_obj, T_ECN_EDT_HDR *fp_rsp_esv,
1438 T_ECN_EDT_HDR const *fp_req_esv);
1439/* 応答電文設定 */
1440static void _ecn_tsk_mk_rsp_hdr(const EOBJINIB *fp_obj, T_ECN_EDT_HDR *fp_rsp_esv,
1441 T_ECN_EDT_HDR const *fp_req_esv)
1442{
1443 fp_rsp_esv->ecn_hdr.ehd1 = ECN_EDH1_ECHONET_LITE;
1444 fp_rsp_esv->ecn_hdr.ehd2 = ECN_EDH2_FORMAT_1;
1445 fp_rsp_esv->ecn_hdr.tid = fp_req_esv->ecn_hdr.tid;
1446 fp_rsp_esv->edata.seoj.eojx1 = fp_obj->eojx1;
1447 fp_rsp_esv->edata.seoj.eojx2 = fp_obj->eojx2;
1448 fp_rsp_esv->edata.seoj.eojx3 = fp_obj->eojx3;
1449 fp_rsp_esv->edata.deoj = fp_req_esv->edata.seoj;
1450}
1451
1452static void _ecn_tsk_mk_rsp_hdr_res(T_ECN_EDT_HDR *fp_rsp_esv,
1453 T_ECN_EDT_HDR const *fp_req_esv);
1454static void _ecn_tsk_mk_rsp_hdr_res(T_ECN_EDT_HDR *fp_rsp_esv,
1455 T_ECN_EDT_HDR const *fp_req_esv)
1456{
1457 fp_rsp_esv->ecn_hdr.ehd1 = ECN_EDH1_ECHONET_LITE;
1458 fp_rsp_esv->ecn_hdr.ehd2 = ECN_EDH2_FORMAT_1;
1459 fp_rsp_esv->ecn_hdr.tid = fp_req_esv->ecn_hdr.tid;
1460 fp_rsp_esv->edata.seoj = fp_req_esv->edata.deoj;
1461 fp_rsp_esv->edata.deoj = fp_req_esv->edata.seoj;
1462}
1463
1464/* 応答電文用fbs設定 */
1465static void _ecn_tsk_set_rsp_fbs(ECN_FBS_ID fa_rsp_fbs, T_ECN_FST_BLK const *fp_req_ptr);
1466/* 応答電文用fbs設定(sender/targetの設定) */
1467static void _ecn_tsk_set_rsp_fbs(ECN_FBS_ID fa_rsp_fbs, T_ECN_FST_BLK const *fp_req_ptr)
1468{
1469 fa_rsp_fbs.ptr->hdr.type = ECN_MSG_ECHONET;
1470 fa_rsp_fbs.ptr->hdr.sender.id = ENOD_LOCAL_ID;
1471 fa_rsp_fbs.ptr->hdr.target.id = fp_req_ptr->hdr.reply.id;
1472 fa_rsp_fbs.ptr->hdr.reply.id = ENOD_LOCAL_ID;
1473}
1474
1475/* プロパティ値書き込み要求 */
1476static void _ecn_tsk_eoj_set(const EOBJINIB *fp_obj, ATR fa_eobjatr, bool_t fa_fromapp, bool_t fa_update,
1477 ECN_FBS_ID fa_fbs_id, ECN_SRV_CODE fa_res_esv, ECN_SRV_CODE fa_sna_esv,
1478 ECN_FBS_ID *fa_fbs_anno)
1479{
1480 T_ECN_EDT_HDR const *p_req_esv = &((T_EDATA *)fa_fbs_id.ptr)->hdr;
1481 T_ECN_EDT_HDR a_ecn_hdp;
1482 ECN_FBS_ID a_fbs_res = { 0 };
1483 ER a_ret;
1484 int a_size;
1485 int a_sw_ok = 1;
1486 T_ECN_EOJ eoj;
1487
1488 memset(&a_ecn_hdp, 0, sizeof(a_ecn_hdp));
1489
1490 /* 応答最大サイズの取得 */
1491 a_size = sizeof(T_ECN_HDR) + sizeof(T_ECN_EDATA_BODY) + sizeof(T_ECN_PRP);
1492
1493 /* 応答電文用メモリの取得 */
1494 a_ret = _ecn_fbs_cre(a_size, &a_fbs_res);
1495 if (a_ret != E_OK || !a_fbs_res.ptr) /* 確保失敗 */
1496 return;
1497
1498 /* 応答電文設定 */
1499 if(p_req_esv->edata.deoj.eojx3 != 0)
1500 _ecn_tsk_mk_rsp_hdr_res(&a_ecn_hdp, p_req_esv);
1501 else
1502 _ecn_tsk_mk_rsp_hdr(fp_obj, &a_ecn_hdp, p_req_esv);
1503
1504 /* 正常時の応答電文がプロパティ値通知応答の場合 */
1505 if (fa_res_esv == ESV_INFC_RES) {
1506 /* 送信元と宛先を入れ替え */
1507 eoj = a_ecn_hdp.edata.seoj;
1508 a_ecn_hdp.edata.seoj = a_ecn_hdp.edata.deoj;
1509 a_ecn_hdp.edata.deoj = eoj;
1510 }
1511
1512 f_put_fbs_eoj("_ecn_tsk_eoj_set", "fa_fbs_id", fa_fbs_id); /* s/deoj デバッグ出力 */
1513
1514 /* 応答電文用メモリにデータ追加 */
1515 a_ret = _ecn_fbs_add_data_ex(a_fbs_res, &a_ecn_hdp,
1516 sizeof(a_ecn_hdp.ecn_hdr) + sizeof(a_ecn_hdp.edata));
1517 if (a_ret)
1518 goto lb_except;
1519
1520 /* payload先頭のT_ECN_HDR(ecn_hdr), T_ECN_EDATA_BODY(edata)を読み飛ばす */
1521 a_ret = _ecn_fbs_set_rpos(fa_fbs_id, offsetof(T_ECN_EDT_HDR, ecn_prp));
1522 if (a_ret)
1523 goto lb_except;
1524
1525 /* 応答電文用fbs設定 */
1526 _ecn_tsk_set_rsp_fbs(a_fbs_res, fa_fbs_id.ptr);
1527
1528 /* プロパティ値書き込み実行 */
1529 a_ret = _ecn_tsk_eoj_set_main(fp_obj, fa_eobjatr, fa_fromapp, fa_update, fa_fbs_id, a_fbs_res,
1530 fa_fbs_anno, p_req_esv->edata.opc, &a_sw_ok);
1531 if (a_ret)
1532 goto lb_except;
1533
1534 /* 応答要の場合 */
1535 if (a_sw_ok) {
1536 if (!fa_res_esv) {
1537 /* 応答不要の場合 */
1538 _ecn_fbs_del(a_fbs_res);
1539 goto lb_finally;
1540 }
1541 /* 設定処理成功 */
1542 ((T_EDATA *)a_fbs_res.ptr)->hdr.edata.esv = fa_res_esv;
1543 } else {
1544 if (!fa_sna_esv) {
1545 /* 応答不要の場合 */
1546 _ecn_fbs_del(a_fbs_res);
1547 goto lb_finally;
1548 }
1549 /* 設定処理失敗 */
1550 ((T_EDATA *)a_fbs_res.ptr)->hdr.edata.esv = fa_sna_esv;
1551 }
1552 /* 応答送信 */
1553 a_ret = _ecn_tsk_snd_dtq(a_fbs_res, false);
1554 if (a_ret == E_OK)
1555 goto lb_finally;
1556
1557lb_except:
1558 /* データ送信失敗したら領域解放 */
1559 if (a_fbs_res.ptr)
1560 _ecn_fbs_del(a_fbs_res);
1561
1562lb_finally:
1563 return;
1564}
1565
1566/* プロパティ値読み出し要求 */
1567static void _ecn_tsk_eoj_get(const EOBJINIB *fp_obj, ATR fa_eobjatr, bool_t fa_forward, ATR fa_access,
1568 ECN_FBS_ID fa_fbs_id, ECN_SRV_CODE fa_res_esv, ECN_SRV_CODE fa_sna_esv)
1569{
1570 T_ECN_EDT_HDR const *p_req_esv = &((T_EDATA *)fa_fbs_id.ptr)->hdr;
1571 T_ECN_EDT_HDR a_ecn_hdp;
1572 ECN_FBS_ID a_fbs_res = { 0 };
1573 ER a_ret;
1574 int a_size;
1575 int a_sw_ok = 1;
1576
1577 memset(&a_ecn_hdp, 0, sizeof(a_ecn_hdp));
1578
1579 /* 初期取得サイズ */
1580 a_size = sizeof(T_ECN_HDR) + sizeof(T_ECN_EDATA_BODY) + sizeof(T_ECN_PRP);
1581
1582 /* 応答電文用メモリの取得 */
1583 a_ret = _ecn_fbs_cre(a_size, &a_fbs_res);
1584 if (a_ret != E_OK || !a_fbs_res.ptr) { /* 確保失敗 */
1585 ECN_DBG_PUT_2("_ecn_fbs_cre() result = %d:%s", a_ret, itron_strerror(a_ret));
1586 goto lb_finally;
1587 }
1588
1589 /* 応答電文設定 */
1590 if(p_req_esv->edata.deoj.eojx3 != 0)
1591 _ecn_tsk_mk_rsp_hdr_res(&a_ecn_hdp, p_req_esv);
1592 else
1593 _ecn_tsk_mk_rsp_hdr(fp_obj, &a_ecn_hdp, p_req_esv);
1594
1595 f_put_fbs_eoj("_ecn_tsk_eoj_get", "fa_fbs_id", fa_fbs_id); /* s/deoj デバッグ出力 */
1596
1597 /* 応答電文用メモリにデータ追加 */
1598 a_ret = _ecn_fbs_add_data_ex(a_fbs_res, &a_ecn_hdp,
1599 sizeof(a_ecn_hdp.ecn_hdr) + sizeof(a_ecn_hdp.edata));
1600 if (a_ret) {
1601 ECN_DBG_PUT_2("_ecn_fbs_add_data_ex() result = %d:%s", a_ret, itron_strerror(a_ret));
1602 goto lb_except;
1603 }
1604
1605 /* payload先頭のT_ECN_HDR(ecn_hdr), T_ECN_EDATA_BODY(edata)を読み飛ばす */
1606 a_ret = _ecn_fbs_set_rpos(fa_fbs_id, offsetof(T_ECN_EDT_HDR, ecn_prp));
1607 if (a_ret) {
1608 ECN_DBG_PUT_2("_ecn_fbs_set_rpos() result = %d:%s", a_ret, itron_strerror(a_ret));
1609 goto lb_except;
1610 }
1611
1612 /* 応答電文用fbs設定 */
1613 _ecn_tsk_set_rsp_fbs(a_fbs_res, fa_fbs_id.ptr);
1614
1615 /* プロパティ値読み込み実行 */
1616 a_ret = _ecn_tsk_eoj_get_main(fp_obj, fa_eobjatr, fa_forward, fa_access, fa_fbs_id, a_fbs_res,
1617 ((T_EDATA *)fa_fbs_id.ptr)->hdr.edata.opc, &a_sw_ok);
1618 if (a_ret) {
1619 ECN_DBG_PUT_2("_ecn_tsk_eoj_get_main() result = %d:%s", a_ret, itron_strerror(a_ret));
1620 goto lb_except;
1621 }
1622
1623 if (a_sw_ok) {
1624 if (!fa_res_esv) {
1625 /* 応答不要の場合 */
1626 _ecn_fbs_del(a_fbs_res);
1627 goto lb_finally;
1628 }
1629 /* 設定処理成功 */
1630 ((T_EDATA *)a_fbs_res.ptr)->hdr.edata.esv = fa_res_esv;
1631 } else {
1632 if (!fa_sna_esv) {
1633 /* 応答不要の場合 */
1634 _ecn_fbs_del(a_fbs_res);
1635 goto lb_finally;
1636 }
1637 /* 設定処理失敗 */
1638 ((T_EDATA *)a_fbs_res.ptr)->hdr.edata.esv = fa_sna_esv;
1639
1640 /* 不可応答の場合は個別送信する */
1641 if (a_fbs_res.ptr->hdr.target.id == ENOD_MULTICAST_ID) {
1642 a_fbs_res.ptr->hdr.target.id = fa_fbs_id.ptr->hdr.sender.id;
1643 }
1644 }
1645 /* 応答送信 */
1646 a_ret = _ecn_tsk_snd_dtq(a_fbs_res, false);
1647 if (a_ret != E_OK) {
1648 ECN_DBG_PUT_2("_ecn_tsk_snd_dtq() result = %d:%s", a_ret, itron_strerror(a_ret));
1649 goto lb_except;
1650 }
1651 goto lb_finally;
1652
1653lb_except:
1654 /* データ送信失敗したら領域解放 */
1655 if (a_fbs_res.ptr)
1656 _ecn_fbs_del(a_fbs_res);
1657
1658lb_finally:
1659 return;
1660}
1661
1662/* プロパティ値読み出し要求 */
1663static void _ecn_tsk_eoj_res(ECN_FBS_ID fa_fbs_id, ECN_SRV_CODE fa_res_esv,
1664 ECN_SRV_CODE fa_sna_esv)
1665{
1666 T_ECN_EDT_HDR const *p_req_esv = &((T_EDATA *)fa_fbs_id.ptr)->hdr;
1667 T_ECN_EDT_HDR a_ecn_hdp;
1668 ECN_FBS_ID a_fbs_res = { 0 };
1669 ER a_ret;
1670 int a_size;
1671 int a_sw_ok = 1;
1672
1673 memset(&a_ecn_hdp, 0, sizeof(a_ecn_hdp));
1674
1675 /* 初期取得サイズ */
1676 a_size = sizeof(T_ECN_HDR) + sizeof(T_ECN_EDATA_BODY) + sizeof(T_ECN_PRP);
1677
1678 /* 応答電文用メモリの取得 */
1679 a_ret = _ecn_fbs_cre(a_size, &a_fbs_res);
1680 if (a_ret != E_OK || !a_fbs_res.ptr) { /* 確保失敗 */
1681 ECN_DBG_PUT_2("_ecn_fbs_cre() result = %d:%s", a_ret, itron_strerror(a_ret));
1682 goto lb_finally;
1683 }
1684
1685 /* 応答電文設定 */
1686 _ecn_tsk_mk_rsp_hdr_res(&a_ecn_hdp, p_req_esv);
1687
1688 f_put_fbs_eoj("_ecn_tsk_eoj_res", "fa_fbs_id", fa_fbs_id); /* s/deoj デバッグ出力 */
1689
1690 /* 応答電文用メモリにデータ追加 */
1691 a_ret = _ecn_fbs_add_data_ex(a_fbs_res, &a_ecn_hdp,
1692 sizeof(a_ecn_hdp.ecn_hdr) + sizeof(a_ecn_hdp.edata));
1693 if (a_ret) {
1694 ECN_DBG_PUT_2("_ecn_fbs_add_data_ex() result = %d:%s", a_ret, itron_strerror(a_ret));
1695 goto lb_except;
1696 }
1697
1698 /* payload先頭のT_ECN_HDR(ecn_hdr), T_ECN_EDATA_BODY(edata)を読み飛ばす */
1699 a_ret = _ecn_fbs_set_rpos(fa_fbs_id, offsetof(T_ECN_EDT_HDR, ecn_prp));
1700 if (a_ret) {
1701 ECN_DBG_PUT_2("_ecn_fbs_set_rpos() result = %d:%s", a_ret, itron_strerror(a_ret));
1702 goto lb_except;
1703 }
1704
1705 /* 応答電文用fbs設定 */
1706 _ecn_tsk_set_rsp_fbs(a_fbs_res, fa_fbs_id.ptr);
1707
1708 /* プロパティ値読み込み実行 */
1709 a_ret = _ecn_tsk_eoj_res_main(fa_fbs_id, a_fbs_res,
1710 ((T_EDATA *)fa_fbs_id.ptr)->hdr.edata.opc, &a_sw_ok);
1711 if (a_ret) {
1712 ECN_DBG_PUT_2("_ecn_tsk_eoj_res_main() result = %d:%s", a_ret, itron_strerror(a_ret));
1713 goto lb_except;
1714 }
1715
1716 if (a_sw_ok) {
1717 if (!fa_res_esv) {
1718 /* 応答不要の場合 */
1719 _ecn_fbs_del(a_fbs_res);
1720 goto lb_finally;
1721 }
1722 /* 設定処理成功 */
1723 ((T_EDATA *)a_fbs_res.ptr)->hdr.edata.esv = fa_res_esv;
1724 } else {
1725 if (!fa_sna_esv) {
1726 /* 応答不要の場合 */
1727 _ecn_fbs_del(a_fbs_res);
1728 goto lb_finally;
1729 }
1730 /* 設定処理失敗 */
1731 ((T_EDATA *)a_fbs_res.ptr)->hdr.edata.esv = fa_sna_esv;
1732 }
1733 /* 応答送信 */
1734 a_ret = _ecn_tsk_snd_dtq(a_fbs_res, false);
1735 if (a_ret != E_OK) {
1736 ECN_DBG_PUT_2("_ecn_tsk_snd_dtq() result = %d:%s", a_ret, itron_strerror(a_ret));
1737 goto lb_except;
1738 }
1739 goto lb_finally;
1740
1741lb_except:
1742 /* データ送信失敗したら領域解放 */
1743 if (a_fbs_res.ptr)
1744 _ecn_fbs_del(a_fbs_res);
1745
1746lb_finally:
1747 return;
1748}
1749
1750static void _ecn_tsk_eoj_set_get(const EOBJINIB *fp_obj, ATR fa_eobjatr, bool_t fa_fromapp,
1751 ECN_FBS_ID fa_fbs_id, ECN_SRV_CODE fa_res_esv, ECN_SRV_CODE fa_sna_esv,
1752 ECN_FBS_ID *fa_fbs_anno)
1753{
1754 T_ECN_EDT_HDR const *p_req_esv = &((T_EDATA *)fa_fbs_id.ptr)->hdr;
1755 T_ECN_EDT_HDR a_ecn_hdp;
1756 ECN_FBS_ID a_fbs_res = { 0 };
1757 int a_rdprp_wrpos; /* プロパティ読み込み件数書き込み時のヘッド位置 */
1758 ER a_ret;
1759 int i, a_size, a_rdlen;
1760 int a_sw_ok = 1;
1761 int a_count = ((T_EDATA *)fa_fbs_id.ptr)->hdr.edata.opc; /* 処理プロパティ数 */
1762
1763 memset(&a_ecn_hdp, 0, sizeof(a_ecn_hdp));
1764
1765 ECN_DBG_PUT_1("_ecn_tsk_eoj_set_get() eoj:%06X",
1766 fp_obj->eojx1 << 16 | fp_obj->eojx2 << 8 | fp_obj->eojx3);
1767
1768 /* 初期取得サイズ */
1769 a_size = sizeof(T_ECN_HDR) + sizeof(T_ECN_EDATA_BODY) + sizeof(T_ECN_PRP);
1770
1771 /* 応答電文用メモリの取得 */
1772 a_ret = _ecn_fbs_cre(a_size, &a_fbs_res);
1773 if (a_ret != E_OK || !a_fbs_res.ptr) /* 確保失敗 */
1774 goto lb_finally;
1775
1776 /* 応答電文設定 */
1777 if(p_req_esv->edata.deoj.eojx3 != 0)
1778 _ecn_tsk_mk_rsp_hdr_res(&a_ecn_hdp, p_req_esv);
1779 else
1780 _ecn_tsk_mk_rsp_hdr(fp_obj, &a_ecn_hdp, p_req_esv);
1781 a_size -= sizeof(T_ECN_HDR) + sizeof(T_ECN_EDATA_BODY);
1782
1783 f_put_fbs_eoj("_ecn_tsk_eoj_set_get", "fa_fbs_id", fa_fbs_id); /* s/deoj デバッグ出力 */
1784
1785 /* 応答電文用メモリにデータ追加 */
1786 a_ret = _ecn_fbs_add_data_ex(a_fbs_res, &a_ecn_hdp,
1787 sizeof(a_ecn_hdp.ecn_hdr) + sizeof(a_ecn_hdp.edata));
1788 if (a_ret)
1789 goto lb_except;
1790
1791 /* payload先頭のT_ECN_HDR(ecn_hdr), T_ECN_EDATA_BODY(edata)を読み飛ばす */
1792 a_ret = _ecn_fbs_set_rpos(fa_fbs_id, offsetof(T_ECN_EDT_HDR, ecn_prp));
1793 if (a_ret)
1794 goto lb_except;
1795
1796 /* 応答電文用fbs設定 */
1797 _ecn_tsk_set_rsp_fbs(a_fbs_res, fa_fbs_id.ptr);
1798
1799 /* プロパティ値書き込み実行 */
1800 a_ret = _ecn_tsk_eoj_set_main(fp_obj, fa_eobjatr, fa_fromapp, false, fa_fbs_id, a_fbs_res,
1801 fa_fbs_anno, a_count, &a_sw_ok);
1802 if (a_ret) {
1803 syslog(LOG_WARNING, "_ecn_tsk_eoj_set_get() eoj:%06X _ecn_tsk_eoj_set_main() fault. result = %d",
1804 fp_obj->eojx1 << 16 | fp_obj->eojx2 << 8 | fp_obj->eojx3,
1805 a_ret);
1806 goto lb_except;
1807 }
1808 ECN_DBG_PUT_2("_ecn_tsk_eoj_set_get() eoj:%06X _ecn_tsk_eoj_set_main() ok sw_ok:%s",
1809 fp_obj->eojx1 << 16 | fp_obj->eojx2 << 8 | fp_obj->eojx3,
1810 (a_sw_ok ? "true" : "false"));
1811
1812 /* 次の件数を読み取る(1byte) */
1813 /* → ECHONET-Lite_Ver.1.10_02.pdf p.40 [OPCGet] */
1814 a_rdlen = i = 0;
1815 a_ret = _ecn_fbs_get_data(fa_fbs_id, &i, 1, &a_rdlen);
1816 if (a_ret < 0 || a_rdlen < 1)
1817 goto lb_except; /* NG */
1818 a_count = *(uint8_t *)&i;
1819
1820 /* プロパティ読み込み件数書き込み時のヘッド情報を記録 */
1821 a_rdprp_wrpos = _ecn_fbs_get_datalen(a_fbs_res);
1822
1823 /* 応答電文用メモリにデータ追加 (OPCGet 1byte) */
1824 a_ret = _ecn_fbs_add_data_ex(a_fbs_res, &i, 1);
1825 if (a_ret)
1826 goto lb_except;
1827
1828 /* この時点での応答電文中プロパティ件数を記録 */
1829 i = ((T_EDATA *)a_fbs_res.ptr)->hdr.edata.opc;
1830 ((T_EDATA *)a_fbs_res.ptr)->hdr.edata.opc = 0;
1831
1832 /* プロパティ値読み込み実行 */
1833 a_ret = _ecn_tsk_eoj_get_main(fp_obj, fa_eobjatr, false, EPC_RULE_GET, fa_fbs_id, a_fbs_res,
1834 a_count, &a_sw_ok);
1835 if (a_ret) {
1836 syslog(LOG_WARNING, "%s _ecn_tsk_eoj_set_get() eoj:%06X _ecn_tsk_eoj_get_main() fault. result = %d",
1837 ECN_SRC_LOC,
1838 fp_obj->eojx1 << 16 | fp_obj->eojx2 << 8 | fp_obj->eojx3,
1839 a_ret);
1840 goto lb_except;
1841 }
1842 ECN_DBG_PUT_2("_ecn_tsk_eoj_set_get() eoj:%06X _ecn_tsk_eoj_get_main() ok sw_ok:%s",
1843 fp_obj->eojx1 << 16 | fp_obj->eojx2 << 8 | fp_obj->eojx3,
1844 (a_sw_ok ? "true" : "false"));
1845
1846 /* プロパティ読み込み件数書き込み時のヘッド情報で、読み出し件数を記録 */
1847 _ecn_fbs_poke(a_fbs_res, a_rdprp_wrpos, ((T_EDATA *)a_fbs_res.ptr)->hdr.edata.opc);
1848
1849 /* 記録しておいたプロパティ件数(書き込み件数)を書き戻す */
1850 ((T_EDATA *)a_fbs_res.ptr)->hdr.edata.opc = (uint8_t)i;
1851
1852 /* 応答要の場合 */
1853 if (a_sw_ok) {
1854 /* 設定処理成功 */
1855 ((T_EDATA *)a_fbs_res.ptr)->hdr.edata.esv = fa_res_esv;
1856 } else {
1857 /* 設定処理失敗 */
1858 ((T_EDATA *)a_fbs_res.ptr)->hdr.edata.esv = fa_sna_esv;
1859 }
1860 /* 応答送信 */
1861 a_ret = _ecn_tsk_snd_dtq(a_fbs_res, false);
1862 if (a_ret == E_OK)
1863 goto lb_finally;
1864
1865lb_except:
1866 /* データ送信失敗したら領域解放 */
1867 if (a_fbs_res.ptr)
1868 _ecn_fbs_del(a_fbs_res);
1869
1870lb_finally:
1871 return;
1872}
1873
1874static void _ecn_tsk_eoj_set_get_res(const EOBJINIB *fp_obj, ATR fa_eobjatr,
1875 bool_t fa_fromapp, ECN_FBS_ID fa_fbs_id, ECN_FBS_ID *fa_fbs_anno)
1876{
1877 T_ECN_EDT_HDR const *p_req_esv = &((T_EDATA *)fa_fbs_id.ptr)->hdr;
1878 T_ECN_EDT_HDR a_ecn_hdp;
1879 ECN_FBS_ID a_fbs_dmy = { 0 };
1880 ER a_ret;
1881 int i, a_size, a_rdlen;
1882 int a_sw_ok = 1;
1883 int a_count = ((T_EDATA *)fa_fbs_id.ptr)->hdr.edata.opc; /* 処理プロパティ数 */
1884
1885 memset(&a_ecn_hdp, 0, sizeof(a_ecn_hdp));
1886
1887 ECN_DBG_PUT_1("_ecn_tsk_eoj_set_get_res() eoj:%06X",
1888 fp_obj->eojx1 << 16 | fp_obj->eojx2 << 8 | fp_obj->eojx3);
1889
1890 /* 初期取得サイズ */
1891 a_size = sizeof(T_ECN_HDR) + sizeof(T_ECN_EDATA_BODY) + sizeof(T_ECN_PRP);
1892
1893 /* 応答電文用メモリ(ダミー)の取得 */
1894 a_ret = _ecn_fbs_cre(a_size, &a_fbs_dmy);
1895 if (a_ret != E_OK || !a_fbs_dmy.ptr) /* 確保失敗 */
1896 goto lb_finally;
1897
1898 /* 応答電文設定 */
1899 _ecn_tsk_mk_rsp_hdr_res(&a_ecn_hdp, p_req_esv);
1900 a_size -= sizeof(T_ECN_HDR) + sizeof(T_ECN_EDATA_BODY);
1901
1902 /* payload先頭のT_ECN_HDR(ecn_hdr), T_ECN_EDATA_BODY(edata)を読み飛ばす */
1903 a_ret = _ecn_fbs_set_rpos(fa_fbs_id, offsetof(T_ECN_EDT_HDR, ecn_prp));
1904 if (a_ret)
1905 goto lb_except;
1906
1907 /* プロパティ値書き込み応答読み飛ばし実行 */
1908 a_ret = _ecn_tsk_eoj_skip_main(fp_obj, fa_fbs_id, a_count);
1909 if (a_ret) {
1910 syslog(LOG_WARNING, "_ecn_tsk_eoj_set_get_res() eoj:%06X _ecn_tsk_eoj_set_main() fault. result = %d",
1911 fp_obj->eojx1 << 16 | fp_obj->eojx2 << 8 | fp_obj->eojx3,
1912 a_ret);
1913 goto lb_except;
1914 }
1915 ECN_DBG_PUT_2("_ecn_tsk_eoj_set_get_res() eoj:%06X _ecn_tsk_eoj_set_main() ok sw_ok:%s",
1916 fp_obj->eojx1 << 16 | fp_obj->eojx2 << 8 | fp_obj->eojx3,
1917 (a_sw_ok ? "true" : "false"));
1918
1919 /* 次の件数を読み取る(1byte) */
1920 /* → ECHONET-Lite_Ver.1.10_02.pdf p.40 [OPCGet] */
1921 a_rdlen = i = 0;
1922 a_ret = _ecn_fbs_get_data(fa_fbs_id, &i, 1, &a_rdlen);
1923 if (a_ret < 0 || a_rdlen < 1)
1924 goto lb_except; /* NG */
1925 a_count = *(uint8_t *)&i;
1926
1927 /* プロパティ値読み出し応答の書き込み実行 */
1928 a_ret = _ecn_tsk_eoj_set_main(fp_obj, fa_eobjatr, fa_fromapp, true, fa_fbs_id, a_fbs_dmy,
1929 fa_fbs_anno, a_count, &a_sw_ok);
1930 if (a_ret) {
1931 syslog(LOG_WARNING, "%s _ecn_tsk_eoj_set_get_res() eoj:%06X _ecn_tsk_eoj_get_main() fault. result = %d",
1932 ECN_SRC_LOC,
1933 fp_obj->eojx1 << 16 | fp_obj->eojx2 << 8 | fp_obj->eojx3,
1934 a_ret);
1935 goto lb_except;
1936 }
1937 ECN_DBG_PUT_2("_ecn_tsk_eoj_set_get_res() eoj:%06X _ecn_tsk_eoj_get_main() ok sw_ok:%s",
1938 fp_obj->eojx1 << 16 | fp_obj->eojx2 << 8 | fp_obj->eojx3,
1939 (a_sw_ok ? "true" : "false"));
1940
1941 goto lb_finally;
1942
1943lb_except:
1944 /* データ送信失敗したら領域解放 */
1945 if (a_fbs_dmy.ptr)
1946 _ecn_fbs_del(a_fbs_dmy);
1947
1948lb_finally:
1949 return;
1950}
1951
1952/*
1953 * 応答電文待ちの割り込み電文作成
1954 */
1955ER _ecn_mk_brk_wai(ECN_FBS_ID *pk_fbs_id, const void *p_dat, size_t fa_size)
1956{
1957 ER a_ret;
1958 ECN_FBS_ID a_fbs_id = { 0 }; /* 要求電文用メモリ */
1959
1960 if (!pk_fbs_id)
1961 return E_PAR;
1962 *pk_fbs_id = a_fbs_id;
1963 if (sizeof(a_fbs_id.ptr->payload) <= fa_size)
1964 return E_PAR; /* 付随データが大きすぎる */
1965 if (!p_dat && 0 < fa_size)
1966 return E_PAR; /* 付随データサイズが1以上なのにデータポインタがNULL */
1967
1968 /* 要求電文用メモリの取得 */
1969 a_ret = _ecn_fbs_cre((0 < fa_size ? fa_size : 1), &a_fbs_id);
1970 if (a_ret != E_OK || !a_fbs_id.ptr) { /* 確保失敗 */
1971 syslog(LOG_WARNING, "_ecn_fbs_cre(%d) result = %d:%s", fa_size, a_ret, itron_strerror(a_ret));
1972 return a_ret;
1973 }
1974
1975 /* 要求電文設定 */
1976 a_fbs_id.ptr->hdr.type = ECN_MSG_USER_BREAK;
1977 a_fbs_id.ptr->hdr.sender.id = ENOD_API_ID;
1978 a_fbs_id.ptr->hdr.target.id = ENOD_API_ID;
1979 a_fbs_id.ptr->hdr.reply.id = ENOD_API_ID;
1980
1981 if (0 < fa_size && p_dat) {
1982 /* 付随データ追加 */
1983 a_ret = _ecn_fbs_add_data_ex(a_fbs_id, p_dat, fa_size);
1984 if (a_ret) {
1985 syslog(LOG_WARNING, "_ecn_fbs_add_data_ex(*, dat, %lu) result = %d:%s",
1986 fa_size,
1987 a_ret, itron_strerror(a_ret));
1988 goto lb_except;
1989 }
1990 }
1991
1992 *pk_fbs_id = a_fbs_id;
1993
1994 /* 正常終了 */
1995 return a_ret;
1996
1997lb_except:
1998 /* データ作成失敗したら領域解放 */
1999 if (a_fbs_id.ptr)
2000 _ecn_fbs_del(a_fbs_id);
2001
2002 return a_ret;
2003}
2004
2005/* 応答電文用fbs設定(sender/targetの設定) */
2006ER _ecn_tsk_cre_req_fbs(ID sender, uint8_t cmd, ECN_FBS_ID *pk_req)
2007{
2008 ER ret;
2009 ECN_FBS_ID req;
2010
2011 ret = _ecn_fbs_cre(1, &req);
2012 if (ret != E_OK) {
2013 ECN_DBG_PUT_2("_ecn_tsk_cre_req_fbs() : _ecn_fbs_cre() result = %d:%s", ret, itron_strerror(ret));
2014 return ret;
2015 }
2016
2017 ret = _ecn_fbs_add_data(req, &cmd, sizeof(cmd));
2018 if (ret != E_OK) {
2019 _ecn_fbs_del(req);
2020 ECN_DBG_PUT_2("_ecn_tsk_cre_req_fbs() : _ecn_fbs_add_data() result = %d:%s", ret, itron_strerror(ret));
2021 return ret;
2022 }
2023
2024 req.ptr->hdr.type = ECN_MSG_INTERNAL;
2025 req.ptr->hdr.sender.dtqid = sender;
2026 req.ptr->hdr.target.dtqid = ecn_svc_mailboxid;
2027 req.ptr->hdr.reply.dtqid = sender;
2028
2029 *pk_req = req;
2030
2031 return E_OK;
2032}
2033
2034/* 応答電文用fbs設定(sender/targetの設定) */
2035ER _ecn_tsk_cre_res_fbs(ECN_FBS_ID req, uint8_t cmd, ECN_FBS_ID *pk_res)
2036{
2037 ER ret;
2038 ECN_FBS_ID res;
2039
2040 ret = _ecn_fbs_cre(1, &res);
2041 if (ret != E_OK) {
2042 ECN_DBG_PUT_2("_ecn_tsk_cre_res_fbs() : _ecn_fbs_cre() result = %d:%s", ret, itron_strerror(ret));
2043 return ret;
2044 }
2045
2046 ret = _ecn_fbs_add_data(res, &cmd, sizeof(cmd));
2047 if (ret != E_OK) {
2048 _ecn_fbs_del(res);
2049 ECN_DBG_PUT_2("_ecn_tsk_cre_res_fbs() : _ecn_fbs_add_data() result = %d:%s", ret, itron_strerror(ret));
2050 return ret;
2051 }
2052
2053 res.ptr->hdr.type = ECN_MSG_INTERNAL;
2054 res.ptr->hdr.sender.dtqid = ecn_svc_mailboxid;
2055 res.ptr->hdr.target.dtqid = req.ptr->hdr.reply.dtqid;
2056 res.ptr->hdr.reply.dtqid = ecn_svc_mailboxid;
2057
2058 *pk_res = res;
2059
2060 return E_OK;
2061}
Note: See TracBrowser for help on using the repository browser.