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

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

Azure IoT Hub Device C SDK を使ったサンプルの追加

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