source: azure_iot_hub/trunk/ntshell/echonet/echonet_task.c@ 400

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

ファイルヘッダーの更新

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