source: uKadecot/trunk/ecnl_ssp/echonet.c@ 108

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

MIMEプロパティの変更

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