source: EcnlProtoTool/trunk/mrbgems/mruby-ecnl/src/echonet.c@ 321

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

文字コードを設定

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