source: EcnlProtoTool/trunk/mrbgems/mruby-ecnl/src/echonet_lcl_task.c@ 270

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

mruby版ECNLプロトタイピング・ツールを追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc
File size: 18.2 KB
Line 
1/*
2 * TOPPERS ECHONET Lite Communication Middleware
3 *
4 * Copyright (C) 2014-2016 Cores Co., Ltd. Japan
5 *
6 * 上記著作権者
7は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
8 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
9 * 変・再é…
10å¸ƒï¼ˆä»¥ä¸‹ï¼Œåˆ©ç”¨ã¨å‘¼ã¶ï¼‰ã™ã‚‹ã“とを無償で許諾する.
11 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
12 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
13 * スコード中に含まれていること.
14 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
15 * 用できる形で再é…
16å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
17å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
18 * 者
19マニュアルなど)に,上記の著作権表示,この利用条件および下記
20 * の無保証規定を掲載すること.
21 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
22 * 用できない形で再é…
23å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®ã„ずれかの条件を満たすこ
24 * と.
25 * (a) 再é…
26å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
27マニュアルなど)に,上記の著
28 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
29 * (b) 再é…
30å¸ƒã®å½¢æ…
31‹ã‚’,別に定める方法によって,TOPPERSプロジェクトに
32 * 報告すること.
33 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
34 * 害からも,上記著作権者
35およびTOPPERSプロジェクトをå…
36è²¬ã™ã‚‹ã“と.
37 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
38 * 由に基づく請求からも,上記著作権者
39およびTOPPERSプロジェクトを
40 * å…
41è²¬ã™ã‚‹ã“と.
42 *
43 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者
44お
45 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
46 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
47 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
48 * の責任を負わない.
49 *
50 */
51
52/*
53 * ECHONET Lite LCL通信処理タスク
54 */
55
56#include <mruby.h>
57#include <mruby/data.h>
58#include <mruby/string.h>
59#include <string.h>
60#include <stdio.h>
61#include <stdlib.h>
62
63#include "echonet.h"
64
65#include "echonet_task.h"
66#include "echonet_lcl_task.h"
67#include "echonet_dbg.h"
68#include "mrb_ecnl.h"
69
70#ifndef ECHONET_LCL_TASK_GET_TIMER
71#define ECHONET_LCL_TASK_GET_TIMER TMO_FEVR
72#endif /* ECHONET_LCL_TASK_GET_TIMER */
73
74#ifndef ECHONET_LCL_TASK_PROGRESS
75#define ECHONET_LCL_TASK_PROGRESS(timer)
76#endif /* ECHONET_LCL_TASK_PROGRESS */
77
78#ifndef ECHONET_LCL_TASK_TIMEOUT
79#define ECHONET_LCL_TASK_TIMEOUT
80#endif /* ECHONET_LCL_TASK_TIMEOUT */
81
82#ifndef ECHONET_LCL_SEND_TO_MBX
83#define ECHONET_LCL_SEND_TO_MBX
84#endif /* ECHONET_LCL_SEND_TO_MBX */
85
86static ECN_ENOD_ID lcl_get_id(ecnl_svc_task_t *svc, T_EDATA *edata, const mrb_value ep);
87static mrb_value lcl_get_addr(ecnl_svc_task_t *svc, ECN_ENOD_ID fa_enodid);
88void _ecn_int_msg(ecnl_svc_task_t *svc, ECN_FBS_ID fbs_id, ECN_FBS_SSIZE_T a_snd_len);
89void _ecn_esv_msg(ecnl_svc_task_t *svc, ECN_FBS_ID fbs_id);
90
91/*
92 * 受信したLCLデータをMAILBOXに送る
93 */
94ER _ecn_lcl2mbx(ecnl_svc_task_t *svc, const uint8_t *buffer, size_t fa_len, const mrb_value dst);
95ER _ecn_lcl2mbx(ecnl_svc_task_t *svc, const uint8_t *buffer, size_t fa_len, const mrb_value dst)
96{
97 mrb_state *mrb = svc->mrb;
98 ECN_FBS_ID a_fbs_id = { 0 };
99 ER a_ret = E_OK;
100 ECN_ENOD_ID a_enod_id;
101 union
102 {
103 const uint8_t *buffer;
104 const T_ECN_EDT_HDR *t_esv;
105 } a_rcv_pkt;
106
107 a_rcv_pkt.buffer = buffer;
108 if ( a_rcv_pkt.t_esv->ecn_hdr.ehd1 != ECN_EDH1_ECHONET_LITE /* ECHONET Lite規格 */
109 || a_rcv_pkt.t_esv->ecn_hdr.ehd2 != ECN_EDH2_FORMAT_1 /* 電文形式1 */) {
110 ECN_DBG_PUT_2("[LCL ECHO SRV] illegal type (0x%02X,0x%02X)", a_rcv_pkt.t_esv->ecn_hdr.ehd1, a_rcv_pkt.t_esv->ecn_hdr.ehd2);
111 return E_PAR;
112 }
113
114#ifdef ECN_DBG_PUT_ENA
115 _ecn_dbg_bindmp(buffer, fa_len);
116#endif
117
118 a_ret = _ecn_fbs_cre(mrb, fa_len, &a_fbs_id);
119 if (a_ret != E_OK) {
120 ECN_DBG_PUT_2("[LCL ECHO SRV] _ecn_fbs_cre() result = %d:%s", a_ret, itron_strerror(a_ret));
121 return a_ret;
122 }
123 a_ret = _ecn_fbs_add_data_ex(mrb, a_fbs_id, buffer, fa_len);
124 if (a_ret) {
125 ECN_DBG_PUT_2("[LCL ECHO SRV] _ecn_fbs_add_data_ex() result = %d:%s", a_ret, itron_strerror(a_ret));
126 goto lb_except;
127 }
128 a_fbs_id.ptr->hdr.type = ECN_MSG_ECHONET;
129 a_fbs_id.ptr->hdr.target.id = ENOD_LOCAL_ID;
130 a_fbs_id.ptr->hdr.sender.id = ENOD_NOT_MATCH_ID;
131
132 /* 通信レイヤーアドレスからリモートECHONETノードへ変換 */
133 a_enod_id = lcl_get_id(svc, (T_EDATA *)a_fbs_id.ptr, dst);
134 if (!lcl_is_valid_addrid(svc, a_enod_id)) {
135 ECN_DBG_PUT_1("[LCL ECHO SRV] lcl src(%s) echonet-node not found.",
136 ip2str(NULL, &dst->lcladdr));
137 } else {
138 /* 送信å…
139ƒECHONETノードを記録 */
140 a_fbs_id.ptr->hdr.sender.id = a_enod_id;
141 }
142 a_fbs_id.ptr->hdr.reply.id = a_fbs_id.ptr->hdr.sender.id;
143
144 /* echonet_taskに送る */
145 a_ret = ecn_fbs_enqueue(&svc->svc_mbxid, a_fbs_id.ptr);
146 if (a_ret != E_OK) {
147 ECN_DBG_PUT_2("[LCL ECHO SRV] snd_mbx(svc->svc_mbxid) result = %d:%s", a_ret, itron_strerror(a_ret));
148 goto lb_except;
149 }
150 return a_ret;
151lb_except:
152 _ecn_fbs_del(mrb, a_fbs_id);
153 return a_ret;
154}
155
156/*
157* ECHONET Lite 通信レイヤータスク タイマー値取得
158*/
159TMO echonet_lcltask_get_timer(ecnl_svc_task_t *svc)
160{
161 TMO a_timer;
162
163 a_timer = ECHONET_LCL_TASK_GET_TIMER;
164
165 return a_timer;
166}
167
168
169/*
170* ECHONET Lite 通信レイヤータスク 時間経過処理
171*/
172void echonet_lcltask_progress(ecnl_svc_task_t *svc, TMO a_timer)
173{
174 ECHONET_LCL_TASK_PROGRESS(a_timer);
175}
176
177/*
178* ECHONET Lite 通信レイヤータスク メッセージ受信処理
179*/
180void echonet_lcltask_recv_msg(ecnl_svc_task_t *svc, T_ECN_FST_BLK *p_msg)
181{
182 ECN_FBS_ID a_fbs_id;
183 ECN_FBS_SSIZE_T a_snd_len;
184
185 a_fbs_id.ptr = p_msg;
186
187 /* 送信データ長を取得 */
188 a_snd_len = _ecn_fbs_get_datalen(a_fbs_id);
189
190 ECN_DBG_PUT_1("trcv_dtq() mbx recv (%d byte)", a_snd_len);
191
192 switch (a_fbs_id.ptr->hdr.type) {
193 /* 内
194部使用メッセージ */
195 case ECN_MSG_INTERNAL:
196 _ecn_int_msg(svc, a_fbs_id, a_snd_len);
197 break;
198
199 /* ECHONET用メッセージ */
200 case ECN_MSG_ECHONET:
201 _ecn_esv_msg(svc, a_fbs_id);
202 break;
203
204 default:
205 ECN_DBG_PUT_1("echonet_task() a_fbs_id.ptr->k.hdr.k.t_edt.type:0x%02X undefined.", a_fbs_id.ptr->hdr.type);
206 }
207
208 /* 領域解放 */
209 _ecn_fbs_del(svc->mrb, a_fbs_id);
210}
211
212/*
213* ECHONET Lite 通信レイヤータスク タイムアウト処理
214*/
215void echonet_lcltask_timeout(ecnl_svc_task_t *svc)
216{
217 ECHONET_LCL_TASK_TIMEOUT;
218}
219
220/* 応答電文用fbs設定(sender/targetの設定) */
221static ER _ecn_lcl_cre_req_fbs(ecnl_svc_task_t *svc, T_ECN_FBS_QUEUE *sender, uint8_t cmd, ECN_FBS_ID *pk_req)
222{
223 mrb_state *mrb = svc->mrb;
224 ER ret;
225 ECN_FBS_ID req;
226
227 ret = _ecn_fbs_cre(mrb, 1, &req);
228 if (ret != E_OK) {
229 ECN_DBG_PUT_2("_ecn_lcl_cre_req_fbs() : _ecn_fbs_cre() result = %d:%s", ret, itron_strerror(ret));
230 return ret;
231 }
232
233 ret = _ecn_fbs_add_data(mrb, req, &cmd, sizeof(cmd));
234 if (ret != E_OK) {
235 _ecn_fbs_del(mrb, req);
236 ECN_DBG_PUT_2("_ecn_lcl_cre_req_fbs() : _ecn_fbs_add_data() result = %d:%s", ret, itron_strerror(ret));
237 return ret;
238 }
239
240 req.ptr->hdr.type = ECN_MSG_INTERNAL;
241 req.ptr->hdr.sender.mbxid = sender;
242 req.ptr->hdr.target.mbxid = &svc->lcl_mbxid;
243 req.ptr->hdr.reply.mbxid = sender;
244
245 *pk_req = req;
246
247 return E_OK;
248}
249
250/* 応答電文用fbs設定(sender/targetの設定) */
251static ER _ecn_lcl_cre_res_fbs(ecnl_svc_task_t *svc, ECN_FBS_ID req, uint8_t cmd, ECN_FBS_ID *pk_res)
252{
253 mrb_state *mrb = svc->mrb;
254 ER ret;
255 ECN_FBS_ID res;
256
257 ret = _ecn_fbs_cre(mrb, 1, &res);
258 if (ret != E_OK) {
259 ECN_DBG_PUT_2("_ecn_lcl_cre_res_fbs() : _ecn_fbs_cre() result = %d:%s", ret, itron_strerror(ret));
260 return ret;
261 }
262
263 ret = _ecn_fbs_add_data(mrb, res, &cmd, sizeof(cmd));
264 if (ret != E_OK) {
265 _ecn_fbs_del(mrb, res);
266 ECN_DBG_PUT_2("_ecn_lcl_cre_res_fbs() : _ecn_fbs_add_data() result = %d:%s", ret, itron_strerror(ret));
267 return ret;
268 }
269
270 res.ptr->hdr.type = ECN_MSG_INTERNAL;
271 res.ptr->hdr.sender.mbxid = &svc->lcl_mbxid;
272 res.ptr->hdr.target.mbxid = req.ptr->hdr.reply.mbxid;
273 res.ptr->hdr.reply.mbxid = &svc->lcl_mbxid;
274
275 *pk_res = res;
276
277 return E_OK;
278}
279
280/*
281 * 内
282部メッセージ受信処理
283 */
284void _ecn_int_msg(ecnl_svc_task_t *svc, ECN_FBS_ID fbs_id, ECN_FBS_SSIZE_T a_snd_len)
285{
286 mrb_state *mrb = svc->mrb;
287 ER result = E_OK, a_ret;
288 ecn_lcl_msg_get_lcladdr_req_t msg;
289 ecn_lcl_msg_get_lcladdr_error_t err;
290 ECN_FBS_SSIZE_T len;
291 ECN_FBS_ID buf;
292 uint8_t cmd;
293 mrb_value addr;
294
295 a_ret = _ecn_fbs_get_data(mrb, fbs_id, &cmd, 1, &len);
296 if (a_ret != E_OK) {
297 ECN_DBG_PUT_2("[LCL TSK] _ecn_fbs_get_data() result = %d:%s", a_ret, itron_strerror(a_ret));
298 return;
299 }
300
301 switch(cmd){
302 // 通信レイヤーアドレスを返信
303 case ECN_LCL_MSG_GET_LCLADDR_REQ:
304 if (a_snd_len < sizeof(msg)) {
305 result = E_PAR;
306 break;
307 }
308
309 a_snd_len = 0;
310 a_ret = _ecn_fbs_get_data(mrb, fbs_id, &msg, sizeof(msg), &a_snd_len);
311 if (a_ret != E_OK) {
312 ECN_DBG_PUT_2("[LCL TSK] _ecn_fbs_get_data() result = %d:%s", a_ret, itron_strerror(a_ret));
313 }
314
315 if (!lcl_is_valid_addrid(svc, msg.enodid)) {
316 result = E_PAR;
317 break;
318 }
319
320 a_ret = _ecn_lcl_cre_res_fbs(svc, fbs_id, ECN_LCL_MSG_GET_LCLADDR_RES, &buf);
321 if (a_ret != E_OK) {
322 return;
323 }
324
325 a_ret = _ecn_fbs_add_data_ex(mrb, buf, &msg.requestid, offsetof(ecn_lcl_msg_get_lcladdr_res_t, enodadrb));
326 if (a_ret != E_OK) {
327 _ecn_fbs_del(mrb, buf);
328 ECN_DBG_PUT_2("_ecn_int_msg() : _ecn_fbs_add_data_ex() result = %d:%s", a_ret, itron_strerror(a_ret));
329 return;
330 }
331
332 addr = lcl_get_remote_addr(svc, msg.enodid);
333 a_ret = _ecn_fbs_add_data_ex(mrb, buf, &addr, sizeof(addr));
334 if (a_ret != E_OK) {
335 _ecn_fbs_del(mrb, buf);
336 ECN_DBG_PUT_2("_ecn_int_msg() : _ecn_fbs_add_data_ex() result = %d:%s", a_ret, itron_strerror(a_ret));
337 return;
338 }
339
340 a_ret = ecn_fbs_enqueue(buf.ptr->hdr.target.mbxid, buf.ptr);
341 if (a_ret != E_OK) {
342 _ecn_fbs_del(mrb, buf);
343 ECN_DBG_PUT_2("_ecn_int_msg() : psnd_dtq() result = %d:%s", a_ret, itron_strerror(a_ret));
344 return;
345 }
346 return;
347 }
348
349 a_ret = _ecn_lcl_cre_res_fbs(svc, fbs_id, ECN_LCL_MSG_GET_LCLADDR_ERROR, &buf);
350 if (a_ret != E_OK) {
351 return;
352 }
353
354 err.requestid = msg.requestid;
355 err.error = result;
356 a_ret = _ecn_fbs_add_data_ex(mrb, buf, &err, sizeof(err));
357 if (a_ret != E_OK) {
358 _ecn_fbs_del(mrb, buf);
359 ECN_DBG_PUT_2("_ecn_int_msg() : _ecn_fbs_add_data_ex() result = %d:%s", a_ret, itron_strerror(a_ret));
360 return;
361 }
362
363 a_ret = ecn_fbs_enqueue(buf.ptr->hdr.target.mbxid, buf.ptr);
364 if (a_ret != E_OK) {
365 _ecn_fbs_del(mrb, buf);
366 ECN_DBG_PUT_2("_ecn_int_msg() : psnd_dtq() result = %d:%s", a_ret, itron_strerror(a_ret));
367 return;
368 }
369}
370
371/*
372 * ECHONET 電文受信処理
373 */
374void _ecn_esv_msg(ecnl_svc_task_t *svc, ECN_FBS_ID fbs_id)
375{
376 mrb_state *mrb = svc->mrb;
377 size_t a_len = _ecn_fbs_get_datalen(fbs_id);
378 mrb_value a_msg;
379 mrb_value a_dst;
380 ER a_ret;
381 ECN_FBS_SSIZE_T a_snd_len;
382
383 /* 送信å…
384ˆé€šä¿¡ãƒ¬ã‚¤ãƒ¤ãƒ¼ã‚¢ãƒ‰ãƒ¬ã‚¹ */
385 a_dst = lcl_get_addr(svc, fbs_id.ptr->hdr.target.id);
386 if (mrb_type(a_dst) != MRB_TT_FALSE/*nil*/) {
387 ECN_DBG_PUT_4("[LCL TSK] echonet-node 0x%02X-0x%02X-0x%02X → lcl dest(%s)",
388 ((T_EDATA *)fbs_id.ptr)->hdr.edata.deoj.eojx1,
389 ((T_EDATA *)fbs_id.ptr)->hdr.edata.deoj.eojx2,
390 ((T_EDATA *)fbs_id.ptr)->hdr.edata.deoj.eojx3,
391 ip2str(NULL, &a_dst.lcladdr));
392
393 a_msg = mrb_str_buf_new(mrb, a_len);
394
395 /* fbsから出力領域にデータを抽出 */
396 a_snd_len = 0;
397 a_ret = _ecn_fbs_get_data(mrb, fbs_id, RSTRING_PTR(a_msg), a_len, &a_snd_len);
398 if (a_ret != E_OK) {
399 ECN_DBG_PUT_2("[UDP TSK] _ecn_fbs_get_data() result = %d:%s", a_ret, itron_strerror(a_ret));
400 }
401 else if (lcl_is_local_addr(svc, a_dst)) {
402 RSTR_SET_LEN(RSTRING(a_msg), a_snd_len);
403
404 /* 送信å…
405ˆãŒ127.0.0.1 → mbxに転送 */
406 ECN_DBG_PUT_1("redirect svc->lcl_mbxid → svc->svc_mbxid (esv:0x%02X)",
407 ((T_EDATA *)fbs_id.ptr)->hdr.edata.esv);
408
409 a_ret = _ecn_lcl2mbx(svc, (const uint8_t *)RSTRING_PTR(a_msg), RSTRING_LEN(a_msg), a_dst);
410 if (a_ret != E_OK) {
411 ECN_DBG_PUT_2("_ecn_esv_msg() : _ecn_lcl2mbx() result = %d:%s", a_ret, itron_strerror(a_ret));
412 }
413 }
414 else {
415 RSTR_SET_LEN(RSTRING(a_msg), a_snd_len);
416
417 ECN_DBG_PUT_2("[LCL TSK] lcl_snd_dat() to:%s %ubyte(s)",
418 ip2str(NULL, &a_dst.lcladdr), a_snd_len);
419#ifdef ECN_DBG_PUT_ENA
420 _ecn_dbg_bindmp(RSTRING_PTR(a_msg), a_snd_len);
421#endif
422 /* 通信レイヤーへ送信 */
423 a_ret = lcl_snd_msg(svc, a_dst, a_msg);
424 if (a_ret < 0) {
425 ECN_DBG_PUT_1("[LCL TSK] send, error: %s", itron_strerror(a_ret));
426 }
427 }
428
429 /* データが長すぎて1パケットに収まらなかった場合 */
430 if (_ecn_fbs_exist_data(fbs_id)) {
431 ECN_DBG_PUT_1("[LCL TSK] send, data so long: %dbyte(s)", _ecn_fbs_get_datalen(fbs_id));
432 }
433 } else {
434 ECN_DBG_PUT_3("[LCL TSK] echonet-node 0x%02X-0x%02X-0x%02X not found.",
435 ((T_EDATA *)fbs_id.ptr)->hdr.edata.deoj.eojx1,
436 ((T_EDATA *)fbs_id.ptr)->hdr.edata.deoj.eojx2,
437 ((T_EDATA *)fbs_id.ptr)->hdr.edata.deoj.eojx3);
438 }
439}
440
441/*
442 * ノンブロッキングコールのコールバック関数
443 */
444ER echonet_lcl_input_msg(ecnl_svc_task_t *svc, mrb_value ep, mrb_value data)
445{
446 ECHONET_LCL_SEND_TO_MBX;
447
448 _ecn_lcl2mbx(svc, (const uint8_t *)RSTRING_PTR(data), RSTRING_LEN(data), ep);
449
450 return E_OK;
451}
452
453/*
454 * リモートECHONETノードの適合確認
455 */
456bool_t ecn_is_match(ecnl_svc_task_t *svc, const EOBJCB *enodcb, T_EDATA *edata, mrb_value ep)
457{
458 mrb_state *mrb = svc->mrb;
459 ER ret;
460 T_ENUM_EPC enm;
461 uint8_t epc;
462 uint8_t pdc;
463 uint8_t p_edt[256];
464 int i, j, k;
465 int count;
466 const EOBJINIB *p_eobj;
467 bool_t match;
468
469 if (!edata)
470 return false;
471
472 /* ノードスタート時インスタンスリスト通知以外は除外 */
473 if ( edata->hdr.edata.esv != ESV_INF
474 || edata->hdr.edata.deoj.eojx1 != EOJ_X1_PROFILE
475 || edata->hdr.edata.deoj.eojx2 != EOJ_X2_NODE_PROFILE
476 || edata->hdr.edata.deoj.eojx3 != 0x01
477 || edata->hdr.edata.seoj.eojx1 != EOJ_X1_PROFILE
478 || edata->hdr.edata.seoj.eojx2 != EOJ_X2_NODE_PROFILE
479 || ( edata->hdr.edata.seoj.eojx3 != 0x01
480 && edata->hdr.edata.seoj.eojx3 != 0x02)) {
481 return false;
482 }
483
484 ret = ecn_itr_ini(&enm, edata);
485 if (ret) {
486 ECN_DBG_PUT_2("ecn_is_match(): ecn_itr_ini() result = %d:%s", ret, itron_strerror(ret));
487 return false;
488 }
489 while ((ret = ecn_itr_nxt(mrb, &enm, &epc, &pdc, p_edt)) == E_OK) {
490 if (enm.is_eof) {
491 break;
492 }
493 ECN_DBG_PUT_2("ecn_is_match(): ecn_itr_nxt() result: epc=0x%02X, pdc=%d", epc, pdc);
494 /* インスタンスリスト通知または自ノードインスタンスリストS以外は除外 */
495 if ((epc != 0xD5) && (epc != 0xD6)) {
496 continue;
497 }
498
499 /* 2バイト目以降にeojが列挙されている */
500 count = (pdc - 1) / sizeof(T_ECN_EOJ);
501
502 /* ノード内
503の機器オブジェクトを検索 */
504 for (k = 0; k < enodcb->eobjcnt; k++) {
505 p_eobj = enodcb->eobjs[k];
506
507 /* インスタンスリストを確認 */
508 match = false;
509 for (i = 0, j = 1; i < count; i++, j += sizeof(T_ECN_EOJ)) {
510 if (p_eobj->eojx1 != p_edt[j])
511 continue;
512 if (p_eobj->eojx2 != p_edt[j + 1])
513 continue;
514 if (p_eobj->eojx3 != p_edt[j + 2])
515 continue;
516
517 match = true;
518 break;
519 }
520
521 if (!match)
522 return false;
523 }
524
525 /* すべて揃っていたら適合(インスタンスリストの方が多くてもいいこととする) */
526 return true;
527 }
528
529 return false;
530}
531
532/*
533 * 通信レイヤーアドレスからリモートECHONETノードへ変換
534 */
535ECN_ENOD_ID lcl_get_id(ecnl_svc_task_t *svc, T_EDATA *edata, const mrb_value ep)
536{
537 ECN_ENOD_ID id;
538
539 if (lcl_is_local_addr(svc, ep))
540 return ENOD_LOCAL_ID;
541 if (lcl_is_multicast_addr(svc, ep))
542 return ENOD_MULTICAST_ID;
543
544 /* 通信レイヤーアドレスの同じものを検索 */
545 if ((id = lcl_get_remote_id(svc, ep)) != ENOD_NOT_MATCH_ID) {
546 ECN_CAP_PUT_2("lcl_get_id(): ip-found remote(%d) = %s",
547 id - ENOD_REMOTE_ID, ip2str(NULL, &lcladdr));
548 return id;
549 }
550
551 /* 対応するリモートノードがあれば通信レイヤーアドレスを設定 */
552 if ((id = lcl_set_remote_addr(svc, edata, ep)) != ENOD_NOT_MATCH_ID) {
553 ECN_CAP_PUT_2("lcl_get_id(): enod-found remote(%d) = %s",
554 id - ENOD_REMOTE_ID, ip2str(NULL, &lcladdr));
555 return id;
556 }
557
558 /* 空き領域を探して自動登録 */
559 if ((id = lcl_add_remote_addr(svc, edata, ep)) != ENOD_NOT_MATCH_ID) {
560 ECN_CAP_PUT_2("lcl_get_id(): empty-found remote(%d) = %s",
561 id - ENOD_REMOTE_ID, ip2str(NULL, &lcladdr));
562 return id;
563 }
564
565 return ENOD_NOT_MATCH_ID;
566}
567
568/*
569 * リモートECHONETノードから通信レイヤーアドレスへ変換
570 */
571mrb_value lcl_get_addr(ecnl_svc_task_t *svc, ECN_ENOD_ID fa_enodid)
572{
573 if (fa_enodid == ENOD_MULTICAST_ID) {
574 /* targetがENOD_MULTICAST_IDの場合、マルチキャストを行う */
575 return lcl_get_multicast_addr(svc);
576 }
577
578 if (fa_enodid < ENOD_REMOTE_ID) {
579 /* targetが未定義・LOCAL・APIの場合、ローカルé…
580é€ã‚’行う */
581 return lcl_get_local_addr(svc);
582 }
583
584 return lcl_get_remote_addr(svc, fa_enodid);
585}
586
587ER ecn_lcl_get_lcladdr(ecnl_svc_task_t *svc, T_ECN_FBS_QUEUE *sender, int requestid, ECN_ENOD_ID enodid, ECN_FBS_ID *pk_req)
588{
589 mrb_state *mrb = svc->mrb;
590 ER a_ret;
591 ECN_FBS_ID req;
592 mrb_value addr;
593
594 a_ret = _ecn_lcl_cre_req_fbs(svc, sender, ECN_LCL_MSG_GET_LCLADDR_REQ, &req);
595 if (a_ret != E_OK) {
596 return a_ret;
597 }
598
599 a_ret = _ecn_fbs_add_data_ex(mrb, req, &requestid, sizeof(((ecn_lcl_msg_get_lcladdr_res_t *)0)->requestid));
600 if (a_ret != E_OK) {
601 _ecn_fbs_del(mrb, req);
602 ECN_DBG_PUT_2("ecn_lcl_get_lcladdr() : _ecn_fbs_add_data_ex() result = %d:%s", a_ret, itron_strerror(a_ret));
603 return a_ret;
604 }
605
606 a_ret = _ecn_fbs_add_data_ex(mrb, req, &enodid, sizeof(((ecn_lcl_msg_get_lcladdr_res_t *)0)->enodid));
607 if (a_ret != E_OK) {
608 _ecn_fbs_del(mrb, req);
609 ECN_DBG_PUT_2("ecn_lcl_get_lcladdr() : _ecn_fbs_add_data_ex() result = %d:%s", a_ret, itron_strerror(a_ret));
610 return a_ret;
611 }
612
613 addr = lcl_get_remote_addr(svc, enodid);
614 a_ret = _ecn_fbs_add_data_ex(mrb, req, &addr, sizeof(addr));
615 if (a_ret != E_OK) {
616 _ecn_fbs_del(mrb, req);
617 ECN_DBG_PUT_2("ecn_lcl_get_lcladdr() : _ecn_fbs_add_data_ex() result = %d:%s", a_ret, itron_strerror(a_ret));
618 return a_ret;
619 }
620
621 *pk_req = req;
622
623 return E_OK;
624}
Note: See TracBrowser for help on using the repository browser.