source: UsbWattMeter/trunk/ecnl_lwip/echonet.c@ 167

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

MIMEにSJISを設定

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc; charset=SHIFT_JIS
File size: 19.0 KB
Line 
1/*
2 * TOPPERS ECHONET Lite Communication Middleware
3 *
4 * Copyright (C) 2014-2016 Cores Co., Ltd. Japan
5 *
6 * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
7 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
8 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
9 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
10 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
11 * スコード中に含まれていること.
12 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
13 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
14 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
15 * の無保証規定を掲載すること.
16 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
17 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
18 * と.
19 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
20 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
21 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
22 * 報告すること.
23 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
24 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
25 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
26 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
27 * 免責すること.
28 *
29 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
30 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
31 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
32 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
33 * の責任を負わない.
34 *
35 * @(#) $Id: echonet.c 167 2016-03-08 11:37:45Z coas-nagasima $
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( "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( "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( "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( "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( "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_mbx(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, TMO 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_mbx(ecn_api_mailboxid, &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_WBLK;
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 (!p_edt)
510 return E_PAR;
511 if (!pk_itr->pk_esv)
512 return E_PAR;
513
514 if (pk_itr->is_eof)
515 return E_BOVR; /* データ終了 */
516 if ( pk_itr->count <= pk_itr->got_ct
517 && pk_itr->next_blk_ct < 1) {
518 pk_itr->is_eof = 1; /* 終端に達した時、非0 */
519 return E_BOVR; /* データ終了 */
520 }
521
522 a_fbs_id.ptr = (T_ECN_FST_BLK *)pk_itr->pk_esv;
523
524 /* 元のカーソル位置を保存し、イテレータのカーソル位置にする */
525 a_rd_bak = a_fbs_id.ptr->hdr.rd;
526 a_fbs_id.ptr->hdr.rd = pk_itr->cur;
527
528#ifdef ECN_ENA_ITR_NXT_CARP
529 ECN_CAP_PUT( "ecn_itr_nxt() rd.cur=b%dp%d", pk_itr->cur.blk, pk_itr->cur.pos ECN_CAP_PUT(;
530#endif
531 if (pk_itr->count <= pk_itr->got_ct && 0 < pk_itr->next_blk_ct) {
532 /* 次ブロックに移動 */
533 pk_itr->next_blk_ct --;
534 pk_itr->count = 0; /* 今のブロックでのプロパティ総数 */
535 pk_itr->got_ct = 0; /* 今のブロックで、読み取った数 */
536
537 /* 次ブロックのプロパティ数を読み取る */
538 a_rd_len = 0;
539 a_ret = _ecn_fbs_get_data(a_fbs_id, &a_ecn_prp.pdc, 1, &a_rd_len);
540 if (a_ret != E_OK)
541 goto lb_except;
542 if (0 < a_rd_len) {
543 pk_itr->count = a_ecn_prp.pdc; /* 今のブロックでのプロパティ総数 */
544 }
545 a_ret = E_BOVR; /* データ終了 */
546 goto lb_finally;
547 }
548
549 /* プロパティコードとデータサイズを読み取る */
550 memset(&a_ecn_prp, 0, sizeof(a_ecn_prp));
551 a_rd_len = 0;
552 a_ret = _ecn_fbs_get_data(a_fbs_id, &a_ecn_prp, sizeof(a_ecn_prp), &a_rd_len);
553 if (a_ret != E_OK)
554 goto lb_except;
555 if (a_rd_len < sizeof(a_ecn_prp)) {
556 ECN_DBG_PUT( "ecn_itr_nxt() ecn_prp read fault."
557 " rd.cur=%d", pk_itr->cur );
558 pk_itr->is_eof = 1; /* 終端に達した時、非0 */
559 a_ret = E_BOVR; /* データ終了 */
560 goto lb_finally;
561 }
562 *p_epc = a_ecn_prp.epc;
563 *p_pdc = a_ecn_prp.pdc;
564
565 if (0 < a_ecn_prp.pdc) {
566 /* 付随データを読み取る */
567 a_rd_len = 0;
568 a_ret = _ecn_fbs_get_data(a_fbs_id, p_edt, a_ecn_prp.pdc, &a_rd_len);
569 if (a_ret != E_OK)
570 goto lb_except;
571 if (a_rd_len < (ECN_FBS_SSIZE_T)a_ecn_prp.pdc) {
572 ECN_DBG_PUT( "ecn_itr_nxt() edt read fault."
573 " rd.cur=%d,epc=0x%02X,pdc=%u", pk_itr->cur, a_ecn_prp.epc , a_ecn_prp.pdc );
574 pk_itr->is_eof = 1; /* 終端に達した時、非0 */
575 a_ret = E_BOVR; /* データ終了 */
576 goto lb_finally;
577 }
578 }
579 pk_itr->got_ct++;
580
581#ifdef ECN_ENA_ITR_NXT_CARP
582 ECN_CAP_PUT( "ecn_itr_nxt() read: ct=%d/%d", pk_itr->got_ct, pk_itr->count ECN_CAP_PUT(;
583#endif
584
585lb_finally:
586 /* イテレータのカーソル位置を更新 */
587 pk_itr->cur = a_fbs_id.ptr->hdr.rd;
588
589lb_except:
590 /* 元のカーソル位置に戻す */
591 a_fbs_id.ptr->hdr.rd = a_rd_bak;
592 return a_ret;
593}
594
595/*
596 * 応答電文待ちの割り込み送信
597 */
598ER ecn_brk_wai(const void *p_dat, int fa_datsz)
599{
600 ER a_ret;
601 ECN_FBS_ID a_fbs_id = { 0 }; /* 要求電文用メモリ */
602
603 /* 応答電文待ちの割り込み電文作成 */
604 a_ret = _ecn_mk_brk_wai(&a_fbs_id, p_dat, fa_datsz);
605 if (a_ret)
606 return a_ret;
607
608 /* 割り込み送信 */
609 a_ret = _ecn_tsk_snd_mbx(a_fbs_id, true);
610 if (a_ret) {
611 ECN_DBG_PUT( "_ecn_tsk_snd_mbx() result = %d:%s",
612 a_ret, itron_strerror(a_ret) );
613 goto lb_except;
614 }
615
616 /* 正常終了 */
617 return a_ret;
618
619lb_except:
620 /* データ作成失敗したら領域解放 */
621 if (a_fbs_id.ptr)
622 _ecn_fbs_del(a_fbs_id);
623
624 return a_ret;
625}
626
627/*
628 * 割り込みデータの取得
629 */
630ER ecn_get_brk_dat(T_EDATA *pk_esv, void *p_buf, int fa_bufsz, int *p_datsz)
631{
632 ECN_FBS_ID a_fbs;
633 ER a_ret;
634 ECN_FBS_SSIZE_T a_len;
635
636 if (p_datsz)
637 *p_datsz = 0;
638 if (!pk_esv)
639 return E_PAR;
640
641 a_fbs.ptr = (T_ECN_FST_BLK *)pk_esv;
642 if (a_fbs.ptr->hdr.type != ECN_MSG_USER_BREAK) {
643 ECN_DBG_PUT( "ecn_get_brk_dat: fbs-type:%d != ECN_MSG_USER_BREAK",
644 a_fbs.ptr->hdr.type );
645 return E_PAR;
646 }
647
648 /* 読み取り位置を先頭に戻す */
649 a_ret = _ecn_fbs_set_rpos(a_fbs, 0);
650 if (a_ret) {
651 ECN_DBG_PUT( "_ecn_fbs_set_rpos(*, 0) result = %d:%s",
652 a_ret, itron_strerror(a_ret) );
653 return a_ret;
654 }
655
656 /* 付随データを読み込む */
657 if (p_buf && 0 < fa_bufsz) {
658 a_len = 0;
659 a_ret = _ecn_fbs_get_data(a_fbs, p_buf, fa_bufsz, &a_len);
660 if (a_ret || !a_len) {
661 ECN_DBG_PUT( "_ecn_fbs_get_data(*, p_buf, fa_bufsz) result = %d:%s",
662 a_ret, itron_strerror(a_ret) );
663 return E_PAR;
664 }
665 *p_datsz = a_len;
666 }
667
668 return E_OK;
669}
670
671#ifndef ECN_USER_DATA_PROP_SET
672/*
673 * データ設定関数
674 */
675int ecn_data_prop_set(const EPRPINIB *item, const void *src, int size, bool_t *anno)
676{
677 if (size > item->eprpsz)
678 size = item->eprpsz;
679
680 if (*anno)
681 *anno = memcmp((uint8_t *)item->exinf, src, size) != 0;
682
683 memcpy((uint8_t *)item->exinf, src, size);
684
685 return size;
686}
687#endif
688
689#ifndef ECN_USER_DATA_PROP_GET
690/*
691 * データ取得関数
692 */
693int ecn_data_prop_get(const EPRPINIB *item, void *dst, int size)
694{
695 if (size > item->eprpsz)
696 size = item->eprpsz;
697
698 memcpy(dst, (uint8_t *)item->exinf, size);
699
700 return size;
701}
702#endif
Note: See TracBrowser for help on using the repository browser.