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

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

・デジタルPinとアナログPinのWAMPトピックを追加し、PubSubできるように機能追加。

デジタルPINのトピックは、

「com.sonycsl.kadecot.arduino.topic.pinXX」(XXは0から13)

アナログPINのトピックは、

「com.sonycsl.kadecot.arduino.topic.pinXX.thrYYY」(XXは14から19、YYYは閾値十進)

・デバッグ用の使用していない文字列が、ROM領域に残ってしまうのを修正
・WebSocket接続時のHTTPヘッダーを1行ずつNAK応答を待って送信しているのを、一括で送るよう変更

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