source: asp3_tinet_ecnl_arm/trunk/ntshell/echonet/echonet.c@ 352

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

arm向けASP3版ECNLを追加

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