source: asp3_tinet_ecnl_rx/trunk/ntshell/echonet/echonet.c@ 400

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

ファイルヘッダーの更新

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 23.0 KB
Line 
1/*
2 * TOPPERS ECHONET Lite Communication Middleware
3 *
4 * Copyright (C) 2014-2019 Cores Co., Ltd. Japan
5 *
6 * 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
7 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
8 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
9 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
10 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
11 * スコード中に含まれていること.
12 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
13 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
14 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
15 * の無保証規定を掲載すること.
16 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
17 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
18 * と.
19 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
20 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
21 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
22 * 報告すること.
23 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
24 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
25 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
26 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
27 * 免責すること.
28 *
29 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
30 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
31 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
32 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
33 * の責任を負わない.
34 *
35 * @(#) $Id$
36 */
37
38#include <kernel.h>
39#include <stdio.h>
40#include <string.h>
41#include <t_stdlib.h>
42
43#include "echonet.h"
44#include "echonet_fbs.h"
45#include "echonet_task.h"
46#include "echonet_dbg.h"
47#include "echonet_agent.h"
48
49/*
50 * ECHONET Liteサービス処理開始
51 */
52ER ecn_sta_svc()
53{
54 return act_tsk(ecn_udp_taskid);
55}
56
57/*
58 * インスタンスリスト通知の送信
59 */
60ER ecn_ntf_inl()
61{
62 return _ecn_tsk_ntf_inl();
63}
64
65/*
66 * ECHONETオブジェクト参照
67 * 引数
68 * ID fa_eobjid ECHONETオブジェクトID
69 * T_REOBJ *fp_eobj ECHONETオブジェクトの設定内容コピー先
70 *
71 * eobjidで指定したECHONETオブジェクトの設定内容を参照する。
72 * 参照した設定内容はpk_eobjに指定したメモリに返される。
73 */
74ER ecn_ref_eobj(ID fa_eobjid, T_REOBJ *fp_eobj)
75{
76 const EOBJINIB *p_obj;
77
78 if (!fp_eobj)
79 return E_PAR; /* パラメータエラー */
80
81 if ((fa_eobjid <= 0) || (fa_eobjid > tmax_eobjid))
82 return E_OBJ; /* オブジェクト未登録 */
83
84 p_obj = &eobjinib_table[fa_eobjid - 1];
85
86 *fp_eobj = *p_obj;
87
88 return E_OK;
89}
90
91/*
92 * ECHONETプロパティ参照
93 * 引数
94 * ID fa_eobjid ECHONETオブジェクトID
95 * uint8_t fa_epc プロパティコード
96 * T_RPRP *fp_eprp ECHONETオブジェクトのプロパティ設定内容コピー先
97 *
98 * eobjidで指定したECHONETオブジェクトの、epcで指定したプロパティの設定内容を参照する。
99 * 参照した設定内容はpk_eprpに指定したメモリに返される。
100 */
101ER ecn_ref_eprp(ID fa_eobjid, uint8_t fa_epc, T_RPRP *fp_eprp)
102{
103 const EOBJINIB *p_obj;
104 const EPRPINIB *p;
105 uint_t i;
106
107 if (!fp_eprp)
108 return E_PAR; /* パラメータエラー */
109
110 if ((fa_eobjid <= 0) || (fa_eobjid > tmax_eobjid))
111 return E_OBJ; /* オブジェクト未登録 */
112
113 p_obj = &eobjinib_table[fa_eobjid - 1];
114
115 /* eojの持つプロパティ初期化定義配列から検索 */
116 p = p_obj->eprp;
117 for (i = 0; i < p_obj->eprpcnt; i++, p++) {
118 if (p->eprpcd != fa_epc)
119 continue;
120 *fp_eprp = *p;
121 return E_OK;
122 }
123
124 return E_PAR; /* パラメータエラー */
125}
126
127/*
128 * プロパティ値書き込み要求(応答不要)電文作成
129 * 引数
130 * T_EDATA **ppk_esv 取得した電文の格納先
131 * ID fa_deoj 宛先のECHONETオブジェクトID
132 * uint8_t fa_epc プロパティコード
133 * uint8_t fa_pdc プロパティ値データサイズ
134 * const void *p_edt プロパティ値データ
135 *
136 * プロパティ値書き込み要求(応答不要)電文を作成する。
137 * 電文はdeojで指定したECHONETオブジェクトを宛先とし、
138 * 電文の初めのプロパティ値として、epcとpdc、p_edtで指定された
139 * プロパティコード、データサイズ、データを電文に設定する。
140 * 作成した電文の先頭アドレスはポインタ経由で返される。
141 */
142ER ecn_esv_seti(T_EDATA **ppk_esv, ID fa_deoj, uint8_t fa_epc, uint8_t fa_pdc,
143 const void *p_edt)
144{
145 return _ecn_tsk_mk_esv((ECN_FBS_ID *)ppk_esv, (ID)1, fa_deoj, fa_epc, fa_pdc, p_edt, ESV_SET_I);
146}
147
148/*
149 * プロパティ値書き込み要求(応答要)電文作成
150 * 引数
151 * T_EDATA **ppk_esv 取得した電文の格納先
152 * ID fa_deoj 宛先のECHONETオブジェクトID
153 * uint8_t fa_epc プロパティコード
154 * uint8_t fa_pdc プロパティ値データサイズ
155 * const void *p_edt プロパティ値データ
156 *
157 * プロパティ値書き込み要求(応答要)電文を作成する。
158 * 電文はdeojで指定したECHONETオブジェクトを宛先とし、
159 * 電文の初めのプロパティ値として、epcとpdc、p_edtで指定された
160 * プロパティコード、データサイズ、データを電文に設定する。
161 * 作成した電文の先頭アドレスはポインタ経由で返される。
162 */
163ER ecn_esv_setc(T_EDATA **ppk_esv, ID fa_deoj, uint8_t fa_epc, uint8_t fa_pdc,
164 const void *p_edt)
165{
166 return _ecn_tsk_mk_esv((ECN_FBS_ID *)ppk_esv, (ID)1, fa_deoj, fa_epc, fa_pdc, p_edt, ESV_SET_C);
167}
168
169/*
170 * プロパティ値読み出し要求電文作成
171 * 引数
172 * T_EDATA **ppk_esv 取得した電文の格納先
173 * ID fa_deoj 宛先のECHONETオブジェクトID
174 * uint8_t fa_epc プロパティコード
175 *
176 * プロパティ値読み出し要求電文を作成する。
177 * 電文はdeojで指定したECHONETオブジェクトを宛先とし、
178 * 電文の初めのプロパティ値として、epcで指定された
179 * プロパティコードを電文に設定する。
180 * 作成した電文の先頭アドレスはポインタ経由で返される。
181 */
182ER ecn_esv_get(T_EDATA **ppk_esv, ID fa_deoj, uint8_t fa_epc)
183{
184 return _ecn_tsk_mk_esv((ECN_FBS_ID *)ppk_esv, (ID)1, fa_deoj, fa_epc, 0, NULL, ESV_GET);
185}
186
187/*
188 * プロパティ値通知要求電文作成
189 * 引数
190 * T_EDATA **ppk_esv 取得した電文の格納先
191 * ID fa_deoj 宛先のECHONETオブジェクトID
192 * uint8_t fa_epc プロパティコード
193 *
194 * プロパティ値通知要求電文を作成する。
195 * 電文はdeojで指定したECHONETオブジェクトを宛先とし、
196 * 電文の初めのプロパティ値として、epcで指定された
197 * プロパティコードを電文に設定する。
198 * 作成した電文の先頭アドレスはポインタ経由で返される。
199 */
200ER ecn_esv_inf_req(T_EDATA **ppk_esv, ID fa_deoj, uint8_t fa_epc)
201{
202 return _ecn_tsk_mk_esv((ECN_FBS_ID *)ppk_esv, (ID)1, fa_deoj, fa_epc, 0, NULL, ESV_INF_REQ);
203}
204
205/*
206 * プロパティ値書き込み・読み出し要求電文作成
207 * 引数
208 * T_EDATA **ppk_esv 取得した電文の格納先
209 * ID fa_deoj 宛先のECHONETオブジェクトID
210 * uint8_t fa_epc プロパティコード
211 * uint8_t fa_pdc プロパティ値データサイズ
212 * const void *p_edt プロパティ値データ
213 *
214 * プロパティ値書き込み・読み出し要求電文を作成する。
215 * 電文はdeojで指定したECHONETオブジェクトを宛先とし、
216 * 電文の初めのプロパティ値として、epcとpdc、p_edtで指定された
217 * プロパティコード、データサイズ、データを電文に設定する。
218 * 作成した電文の先頭アドレスはポインタ経由で返される。
219 */
220ER ecn_esv_set_get(T_EDATA **ppk_esv, ID fa_deoj, uint8_t fa_epc, uint8_t fa_pdc,
221 const void *p_edt)
222{
223 return _ecn_tsk_mk_esv((ECN_FBS_ID *)ppk_esv, (ID)1, fa_deoj, fa_epc, fa_pdc, p_edt, ESV_SET_GET);
224}
225
226/*
227 * プロパティ値書き込み・読み出し要求電文作成:折り返し指定
228 * プロパティ値書き込み・読み出し要求電文作成中の、書き込みプロパティ配列を終えて
229 * 読み出しプロパティ配列に移る時に用いる。
230 */
231ER ecn_trn_set_get(T_EDATA *ppk_esv, int *p_trn_pos)
232{
233 ER a_ret;
234
235 if (!ppk_esv)
236 return E_PAR;
237 if (!p_trn_pos)
238 return E_PAR;
239
240 /* プロパティ読み込み件数書き込み時のヘッド情報を記録 */
241 *p_trn_pos = _ecn_fbs_get_datalen(*(ECN_FBS_ID *)&ppk_esv);
242
243 /* 応答電文用メモリにデータ追加・この時点での応答電文中プロパティ件数を記録 */
244 a_ret = _ecn_fbs_add_data_ex(*(ECN_FBS_ID *)&ppk_esv, &ppk_esv->hdr.edata.opc, 1);
245 if (a_ret) {
246 ECN_DBG_PUT_2("ecn_trn_set_get(): _ecn_fbs_add_data_ex() result = %d:%s", a_ret, itron_strerror(a_ret));
247 return a_ret;
248 }
249
250 /* 応答電文中プロパティ件数を 0 に戻す(今後、終了指定するまでは読み出しプロパティ件数になる) */
251 ppk_esv->hdr.edata.opc = 0;
252
253 return E_OK;
254}
255
256/*
257 * プロパティ値書き込み・読み出し要求電文作成:終了指定
258 * プロパティ値書き込み・読み出し要求電文作成中の、読み出しプロパティ配列を終える時に用いる。
259 */
260ER ecn_end_set_get(T_EDATA *ppk_esv, int fa_trn_pos)
261{
262 ER a_ret;
263 int a_wr_opc;
264 uint8_t a_rd_opc;
265
266 if (!ppk_esv)
267 return E_PAR;
268
269 /* この時点での応答電文中プロパティ件数(読み出しプロパティ件数)を保持 */
270 a_rd_opc = ppk_esv->hdr.edata.opc;
271
272 /* 応答電文中プロパティ件数(書き込みプロパティ件数)を保存位置から読み取り */
273 a_wr_opc = _ecn_fbs_peek(*(ECN_FBS_ID *)&ppk_esv, fa_trn_pos);
274 if (a_wr_opc < 0) {
275 ECN_DBG_PUT_2("ecn_end_set_get(): _ecn_fbs_peek() result = %d:%s", a_wr_opc, itron_strerror(a_wr_opc));
276 return a_wr_opc;
277 }
278
279 /* 応答電文中プロパティ件数(書き込みプロパティ件数)を復元 */
280 ppk_esv->hdr.edata.opc = (uint8_t)a_wr_opc;
281
282 /* 応答電文中プロパティ件数(読み出しプロパティ件数)を保存位置に書き込み */
283 a_ret = _ecn_fbs_poke(*(ECN_FBS_ID *)&ppk_esv, fa_trn_pos, a_rd_opc);
284 if (a_ret) {
285 ECN_DBG_PUT_2("ecn_end_set_get(): _ecn_fbs_poke() result = %d:%s", a_ret, itron_strerror(a_ret));
286 return a_ret;
287 }
288
289 return E_OK;
290}
291
292/*
293 * プロパティ値通知(応答要)電文作成
294 * 引数
295 * T_EDATA **ppk_esv 取得した電文の格納先
296 * ID fa_deoj 宛先のECHONETオブジェクトID
297 * ID fa_seoj 送信元のECHONETオブジェクトID
298 * uint8_t fa_sepc 送信元のプロパティコード
299 */
300ER ecn_esv_infc(T_EDATA **ppk_esv, ID fa_deoj, ID fa_seoj, uint8_t fa_sepc)
301{
302 return _ecn_tsk_mk_esv((ECN_FBS_ID *)ppk_esv, fa_seoj, fa_deoj, fa_sepc, 0, NULL, ESV_INFC);
303}
304
305/*
306 * 要求電文へのプロパティ指定追加 (プロパティデータが付随しない場合に用いる)
307 */
308ER ecn_add_epc(T_EDATA *pk_esv, uint8_t epc)
309{
310 return ecn_add_edt(pk_esv, epc, 0, 0);
311}
312
313/*
314 * 要求電文へのプロパティデータ追加 (プロパティおよび付随データを追加する)
315 */
316ER ecn_add_edt(T_EDATA *pk_esv, uint8_t fa_epc, uint8_t fa_pdc, const void *p_edt)
317{
318 ECN_FBS_ID a_fbs_id;
319 ER a_ret;
320 T_ECN_PRP a_ecn_prp;
321
322 if (!pk_esv)
323 return E_PAR; /* 取得したFBS_IDの格納先がNULL */
324 if (ECHONET_MEMPOOL_BLOCK_SIZE <= fa_pdc)
325 return E_PAR; /* プロパティ値サイズが大きすぎる */
326 if (!p_edt && 0 < fa_pdc)
327 return E_PAR; /* プロパティ値サイズが1以上なのにデータポインタがNULL */
328
329 a_fbs_id.ptr = (T_ECN_FST_BLK *)pk_esv;
330 if (((T_EDATA *)a_fbs_id.ptr)->hdr.edata.opc == 0xFF)
331 return E_PAR; /* プロパティが多すぎる */
332
333 /* 要求電文用メモリにデータ追加 */
334 memset(&a_ecn_prp, 0, sizeof(a_ecn_prp));
335 a_ecn_prp.epc = fa_epc;
336 a_ecn_prp.pdc = fa_pdc;
337 a_ret = _ecn_fbs_add_data_ex(a_fbs_id, &a_ecn_prp, sizeof(a_ecn_prp));
338 if (a_ret) {
339 ECN_DBG_PUT_4("ecn_add_edt(): _ecn_fbs_add_data_ex(*, ecn_prp{epc:0x%02X}, %u) result = %d:%s",
340 a_ecn_prp.epc, sizeof(a_ecn_prp),
341 a_ret, itron_strerror(a_ret));
342 goto lb_except;
343 }
344 if (0 < fa_pdc) {
345 /* 付随データ追加 */
346 a_ret = _ecn_fbs_add_data_ex(a_fbs_id, p_edt, fa_pdc);
347 if (a_ret) {
348 ECN_DBG_PUT_4("ecn_add_edt(): _ecn_fbs_add_data_ex(*, ecn_prp{epc:0x%02X} edt, %u) result = %d:%s",
349 a_ecn_prp.epc, fa_pdc,
350 a_ret, itron_strerror(a_ret));
351 goto lb_except;
352 }
353 }
354 /* プロパティ数インクリメント */
355 ((T_EDATA *)a_fbs_id.ptr)->hdr.edata.opc++;
356
357lb_except:
358 return a_ret;
359}
360
361/*
362 * 要求電文の送信
363 * esvで指定された要求電文を送信する。
364 * 電文に指定された宛先からIPアドレスを特定し、UDPパケットとして送信する。
365 */
366ER ecn_snd_esv(T_EDATA *pk_esv)
367{
368 ECN_FBS_ID a_rsp_fbs;
369 a_rsp_fbs.ptr = (T_ECN_FST_BLK *)pk_esv;
370 return _ecn_tsk_snd_dtq(a_rsp_fbs, true);
371}
372
373/*
374 * 応答電文の受信永遠待ち
375 * 応答電文を受信するのを待つ。
376 * 受信した応答電文はppk_esvで指定したポインターに先頭アドレスが返される。
377 * 要求電文の宛先のECHONETオブジェクトがネットワークに存在しない場合、
378 * 応答電文は返送されないので、永遠に待つことになるのでタイムアウト付きの
379 * ecn_trcv_esvを使用することを推奨する。
380 */
381ER ecn_rcv_esv(T_EDATA **ppk_esv)
382{
383 return ecn_trcv_esv(ppk_esv, TMO_FEVR);
384}
385
386/*
387 * 応答電文の受信待ちタイムアウトあり
388 * 応答電文を受信するのを待つ。
389 * 受信した応答電文はppk_esvで指定したポインターに先頭アドレスが返される。
390 * tmoで指定されたタイムアウト時間が経過しても応答電文を受信しない場合、
391 * 待ちが解除され、戻り値がE_TMOで返される。
392 * tmoにTMO_FEVRを指定するとecn_rcv_esvと同じ振る舞いをする。
393 * tmoに0を指定するとecn_prcv_esvと同じ振る舞いをする。
394 */
395ER ecn_trcv_esv(T_EDATA **ppk_esv, int fa_tmout)
396{
397 T_MSG *p_msg = 0;
398 ER a_ret;
399
400 if (!ppk_esv)
401 return E_PAR;
402
403 a_ret = trcv_dtq(ecn_api_dataqueueid, (intptr_t *)&p_msg, fa_tmout);
404 if (a_ret != E_OK) {
405 *ppk_esv = NULL;
406 return a_ret;
407 }
408
409 *ppk_esv = (T_EDATA *)p_msg;
410 return (((T_ECN_FST_BLK *)p_msg)->hdr.type == ECN_MSG_ECHONET) ? E_OK : E_BRK;
411}
412
413/*
414 * 応答電文の受信ポーリング
415 * 応答電文を受信するのを待つ。
416 * 受信した応答電文はppk_esvで指定したポインターに先頭アドレスが返される。
417 * 応答電文の受信の有無にかかわらず、待たずに関数を抜ける。
418 */
419ER ecn_prcv_esv(T_EDATA **ppk_esv)
420{
421 return ecn_trcv_esv(ppk_esv, TMO_POL);
422}
423
424/*
425 * 応答電文の破棄
426 */
427ER ecn_rel_esv(T_EDATA *pk_esv)
428{
429 ECN_FBS_ID a_fbs;
430 ER a_ret;
431
432 a_fbs.ptr = (T_ECN_FST_BLK *)pk_esv;
433 a_ret = _ecn_fbs_del(a_fbs);
434 return a_ret;
435}
436
437/*
438 * 応答電文の送信元ノードを取得する
439 */
440ID ecn_get_enod(T_EDATA *pk_esv)
441{
442 const EOBJCB *p_snod;
443 const EOBJINIB *p_sobj = NULL;
444
445 p_snod = _ecn_eno_fnd(((T_ECN_FST_BLK *)pk_esv)->hdr.sender.id);
446 if (p_snod != NULL) {
447 p_sobj = p_snod->profile;
448 }
449
450 if (p_sobj == NULL)
451 return EOBJ_NULL;
452#ifdef ECHONET_CONTROLLER_EXTENTION
453 if (p_sobj->eprpcnt == 0)
454 return ecn_agent_get_eobj(p_sobj);
455#endif
456 return 1 + (((intptr_t)p_sobj - (intptr_t)eobjinib_table) / sizeof(EOBJINIB));
457}
458
459/*
460 * 応答電文の送信元機器オブジェクトを取得する
461 */
462ID ecn_get_eobj(T_EDATA *pk_esv)
463{
464 const EOBJCB *p_snod;
465 const EOBJINIB *p_sobj = NULL;
466 T_ECN_EDT_HDR *p_esv;
467
468 p_esv = &pk_esv->hdr;
469 p_snod = _ecn_eno_fnd(((T_ECN_FST_BLK *)pk_esv)->hdr.sender.id);
470 if (p_snod != NULL) {
471 /* ノードプロファイルの場合 */
472 if ((p_esv->edata.seoj.eojx1 == EOJ_X1_PROFILE)
473 && (p_esv->edata.seoj.eojx2 == EOJ_X2_NODE_PROFILE)) {
474 p_sobj = p_snod->profile;
475 }
476 /* 機器オブジェクトの場合 */
477 else {
478 p_sobj = _ecn_eoj_fnd(p_snod, &p_esv->edata.seoj);
479 }
480 }
481
482 if (p_sobj == NULL)
483 return EOBJ_NULL;
484#ifdef ECHONET_CONTROLLER_EXTENTION
485 if (p_sobj->eprpcnt == 0)
486 return ecn_agent_get_eobj(p_sobj);
487#endif
488 return 1 + (((intptr_t)p_sobj - (intptr_t)eobjinib_table) / sizeof(EOBJINIB));
489}
490
491/*
492 * 応答電文解析イテレーター初期化
493 */
494ER ecn_itr_ini(T_ENUM_EPC *pk_itr, T_EDATA *pk_esv)
495{
496 if (!pk_itr)
497 return E_PAR;
498 if (!pk_esv)
499 return E_PAR;
500
501 memset(pk_itr, 0, sizeof(*pk_itr));
502 pk_itr->pk_esv = pk_esv;
503 pk_itr->count = pk_esv->hdr.edata.opc;
504 /* 今のブロックでのプロパティ総数 */
505 pk_itr->got_ct = 0; /* 今のブロックで、読み取った数 */
506 pk_itr->next_blk_ct = 0; /* 後続ブロック数 */
507 pk_itr->is_eof = 0; /* 終端に達した時、非0 */
508 pk_itr->cur = offsetof(T_ECN_EDT_HDR, ecn_prp);
509
510 switch (pk_esv->hdr.edata.esv) {
511 case ESV_SET_GET: /* 0x6E プロパティ値書き込み・読み出し要求 */
512 case ESV_SET_GET_RES: /* 0x7E プロパティ値書き込み・読み出し応答 */
513 case ESV_SET_GET_SNA: /* 0x5E プロパティ値書き込み・読み出し不可応答 */
514 pk_itr->next_blk_ct ++;
515 default:
516 break;
517 }
518
519 return E_OK;
520}
521
522/*
523 * 応答電文解析イテレーターインクリメント
524 */
525ER ecn_itr_nxt(T_ENUM_EPC *pk_itr, uint8_t *p_epc, uint8_t *p_pdc, void *p_edt)
526{
527 ECN_FBS_ID a_fbs_id;
528 int a_rd_bak;
529 ER a_ret;
530 ECN_FBS_SSIZE_T a_rd_len;
531 T_ECN_PRP a_ecn_prp;
532
533 if (!pk_itr)
534 return E_PAR;
535 if (!p_epc)
536 return E_PAR;
537 if (!p_pdc)
538 return E_PAR;
539 if (!pk_itr->pk_esv)
540 return E_PAR;
541
542 if (pk_itr->is_eof)
543 return E_BOVR; /* データ終了 */
544 if (pk_itr->count <= pk_itr->got_ct && pk_itr->next_blk_ct < 1) {
545 pk_itr->is_eof = 1; /* 終端に達した時、非0 */
546 return E_BOVR; /* データ終了 */
547 }
548
549 a_fbs_id.ptr = (T_ECN_FST_BLK *)pk_itr->pk_esv;
550
551 /* 元のカーソル位置を保存し、イテレータのカーソル位置にする */
552 a_rd_bak = a_fbs_id.ptr->hdr.rd;
553 a_fbs_id.ptr->hdr.rd = pk_itr->cur;
554
555#ifdef ECN_ENA_ITR_NXT_CARP
556 ECN_CAP_PUT("ecn_itr_nxt() rd.cur=b%dp%d", pk_itr->cur.blk, pk_itr->cur.pos ECN_CAP_PUT(;
557#endif
558 if (pk_itr->count <= pk_itr->got_ct && 0 < pk_itr->next_blk_ct) {
559 /* 次ブロックに移動 */
560 pk_itr->next_blk_ct --;
561 pk_itr->count = 0; /* 今のブロックでのプロパティ総数 */
562 pk_itr->got_ct = 0; /* 今のブロックで、読み取った数 */
563
564 /* 次ブロックのプロパティ数を読み取る */
565 a_rd_len = 0;
566 a_ret = _ecn_fbs_get_data(a_fbs_id, &a_ecn_prp.pdc, 1, &a_rd_len);
567 if (a_ret != E_OK)
568 goto lb_except;
569 if (0 < a_rd_len) {
570 pk_itr->count = a_ecn_prp.pdc; /* 今のブロックでのプロパティ総数 */
571 }
572 a_ret = E_BOVR; /* データ終了 */
573 goto lb_finally;
574 }
575
576 /* プロパティコードとデータサイズを読み取る */
577 memset(&a_ecn_prp, 0, sizeof(a_ecn_prp));
578 a_rd_len = 0;
579 a_ret = _ecn_fbs_get_data(a_fbs_id, &a_ecn_prp, sizeof(a_ecn_prp), &a_rd_len);
580 if (a_ret != E_OK)
581 goto lb_except;
582 if (a_rd_len < sizeof(a_ecn_prp)) {
583 ECN_DBG_PUT_1("ecn_itr_nxt() ecn_prp read fault. rd.cur=%d", pk_itr->cur);
584 pk_itr->is_eof = 1; /* 終端に達した時、非0 */
585 a_ret = E_BOVR; /* データ終了 */
586 goto lb_finally;
587 }
588 *p_epc = a_ecn_prp.epc;
589 *p_pdc = a_ecn_prp.pdc;
590
591 if (0 < a_ecn_prp.pdc) {
592 if (p_edt == NULL) {
593 a_ret = _ecn_fbs_seek_rpos(a_fbs_id, a_ecn_prp.pdc);
594 if (a_ret != E_OK)
595 goto lb_except;
596 }
597 else {
598 /* 付随データを読み取る */
599 a_rd_len = 0;
600 a_ret = _ecn_fbs_get_data(a_fbs_id, p_edt, a_ecn_prp.pdc, &a_rd_len);
601 if (a_ret != E_OK)
602 goto lb_except;
603 if (a_rd_len < (ECN_FBS_SSIZE_T)a_ecn_prp.pdc) {
604 ECN_DBG_PUT_3("ecn_itr_nxt() edt read fault. rd.cur=%d,epc=0x%02X,pdc=%u",
605 pk_itr->cur, a_ecn_prp.epc , a_ecn_prp.pdc);
606 pk_itr->is_eof = 1; /* 終端に達した時、非0 */
607 a_ret = E_BOVR; /* データ終了 */
608 goto lb_finally;
609 }
610 }
611 }
612 pk_itr->got_ct++;
613
614#ifdef ECN_ENA_ITR_NXT_CARP
615 ECN_CAP_PUT("ecn_itr_nxt() read: ct=%d/%d", pk_itr->got_ct, pk_itr->count ECN_CAP_PUT(;
616#endif
617
618lb_finally:
619 /* イテレータのカーソル位置を更新 */
620 pk_itr->cur = a_fbs_id.ptr->hdr.rd;
621
622lb_except:
623 /* 元のカーソル位置に戻す */
624 a_fbs_id.ptr->hdr.rd = a_rd_bak;
625 return a_ret;
626}
627
628/*
629 * 応答電文待ちの割り込み送信
630 */
631ER ecn_brk_wai(const void *p_dat, int fa_datsz)
632{
633 ER a_ret;
634 ECN_FBS_ID a_fbs_id = { 0 }; /* 要求電文用メモリ */
635
636 /* 応答電文待ちの割り込み電文作成 */
637 a_ret = _ecn_mk_brk_wai(&a_fbs_id, p_dat, fa_datsz);
638 if (a_ret)
639 return a_ret;
640
641 /* 割り込み送信 */
642 a_ret = _ecn_tsk_snd_dtq(a_fbs_id, true);
643 if (a_ret) {
644 ECN_DBG_PUT_2("_ecn_tsk_snd_dtq() result = %d:%s", a_ret, itron_strerror(a_ret));
645 goto lb_except;
646 }
647
648 /* 正常終了 */
649 return a_ret;
650
651lb_except:
652 /* データ作成失敗したら領域解放 */
653 if (a_fbs_id.ptr)
654 _ecn_fbs_del(a_fbs_id);
655
656 return a_ret;
657}
658
659/*
660 * 割り込みデータの取得
661 */
662ER ecn_get_brk_dat(T_EDATA *pk_esv, void *p_buf, int fa_bufsz, int *p_datsz)
663{
664 ECN_FBS_ID a_fbs;
665 ER a_ret;
666 ECN_FBS_SSIZE_T a_len;
667
668 if (p_datsz)
669 *p_datsz = 0;
670 if (!pk_esv)
671 return E_PAR;
672
673 a_fbs.ptr = (T_ECN_FST_BLK *)pk_esv;
674 if (a_fbs.ptr->hdr.type != ECN_MSG_USER_BREAK) {
675 ECN_DBG_PUT_1("ecn_get_brk_dat: fbs-type:%d != ECN_MSG_USER_BREAK",
676 a_fbs.ptr->hdr.type);
677 return E_PAR;
678 }
679
680 /* 読み取り位置を先頭に戻す */
681 a_ret = _ecn_fbs_set_rpos(a_fbs, 0);
682 if (a_ret) {
683 ECN_DBG_PUT_2("_ecn_fbs_set_rpos(*, 0) result = %d:%s",
684 a_ret, itron_strerror(a_ret));
685 return a_ret;
686 }
687
688 /* 付随データを読み込む */
689 if (p_buf && 0 < fa_bufsz) {
690 a_len = 0;
691 a_ret = _ecn_fbs_get_data(a_fbs, p_buf, fa_bufsz, &a_len);
692 if (a_ret || !a_len) {
693 ECN_DBG_PUT_2("_ecn_fbs_get_data(*, p_buf, fa_bufsz) result = %d:%s",
694 a_ret, itron_strerror(a_ret));
695 return E_PAR;
696 }
697 *p_datsz = a_len;
698 }
699
700 return E_OK;
701}
702
703#ifndef ECN_USER_DATA_PROP_SET
704/*
705 * データ設定関数
706 */
707int ecn_data_prop_set(const EPRPINIB *item, const void *src, int size, bool_t *anno)
708{
709 if (size > item->eprpsz)
710 size = item->eprpsz;
711
712 if (*anno)
713 *anno = memcmp((uint8_t *)item->exinf, src, size) != 0;
714
715 memcpy((uint8_t *)item->exinf, src, size);
716
717 return size;
718}
719#endif
720
721#ifndef ECN_USER_DATA_PROP_GET
722/*
723 * データ取得関数
724 */
725int ecn_data_prop_get(const EPRPINIB *item, void *dst, int size)
726{
727 if (size > item->eprpsz)
728 size = item->eprpsz;
729
730 memcpy(dst, (uint8_t *)item->exinf, size);
731
732 return size;
733}
734#endif
Note: See TracBrowser for help on using the repository browser.