source: uKadecot/trunk/ecnl_ssp/echonet_uip_task.c@ 101

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

TOPPERS/uKadecotのソースコードを追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/plain
File size: 20.6 KB
Line 
1/*
2 * TOPPERS ECHONET Lite Communication Middleware
3 *
4 * Copyright (C) 2014 Cores Co., Ltd. Japan
5 *
6 * ã‹L’˜ìŒ ŽÒ‚́CˆÈ‰º‚Ì(1)`(4)‚ÌðŒ‚ð–ž‚½‚·ê‡‚ÉŒÀ‚èC–{ƒ\ƒtƒgƒEƒF
7 * ƒAi–{ƒ\ƒtƒgƒEƒFƒA‚ð‰ü•Ï‚µ‚½‚à‚Ì‚ðŠÜ‚ށDˆÈ‰º“¯‚¶j‚ðŽg—pE•¡»E‰ü
8 * •ÏEÄ”z•ziˆÈ‰ºC—˜—p‚ƌĂԁj‚·‚邱‚Ƃ𖳏ž‚Å‹–‘ø‚·‚éD
9 * (1) –{ƒ\ƒtƒgƒEƒFƒA‚ðƒ\[ƒXƒR[ƒh‚ÌŒ`‚Å—˜—p‚·‚éê‡‚ɂ́Cã‹L‚Ì’˜ì
10 * Œ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L‚Ì–³•ÛØ‹K’肪C‚»‚Ì‚Ü‚Ü‚ÌŒ`‚Ń\[
11 * ƒXƒR[ƒh’†‚ÉŠÜ‚Ü‚ê‚Ä‚¢‚邱‚ƁD
12 * (2) –{ƒ\ƒtƒgƒEƒFƒA‚ðCƒ‰ƒCƒuƒ‰ƒŠŒ`Ž®‚ȂǁC‘¼‚̃\ƒtƒgƒEƒFƒAŠJ”­‚ÉŽg
13 * —p‚Å‚«‚éŒ`‚ōĔz•z‚·‚éê‡‚ɂ́CÄ”z•z‚É”º‚¤ƒhƒLƒ…
14ƒƒ“ƒgi—˜—p
15 * ŽÒƒ}ƒjƒ…
16ƒAƒ‹‚Ȃǁj‚ɁCã‹L‚Ì’˜ìŒ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L
17 * ‚Ì–³•ÛØ‹K’è‚ðŒfÚ‚·‚邱‚ƁD
18 * (3) –{ƒ\ƒtƒgƒEƒFƒA‚ðC‹@Ší‚É‘g‚ݍž‚ނȂǁC‘¼‚̃\ƒtƒgƒEƒFƒAŠJ”­‚ÉŽg
19 * —p‚Å‚«‚È‚¢Œ`‚ōĔz•z‚·‚éê‡‚ɂ́CŽŸ‚Ì‚¢‚¸‚ê‚©‚ÌðŒ‚ð–ž‚½‚·‚±
20 * ‚ƁD
21 * (a) Ä”z•z‚É”º‚¤ƒhƒLƒ…
22ƒƒ“ƒgi—˜—pŽÒƒ}ƒjƒ…
23ƒAƒ‹‚Ȃǁj‚ɁCã‹L‚Ì’˜
24 * ìŒ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L‚Ì–³•ÛØ‹K’è‚ðŒfÚ‚·‚邱‚ƁD
25 * (b) Ä”z•z‚ÌŒ`‘Ô‚ðC•Ê‚É’è‚ß‚é•û–@‚É‚æ‚Á‚āCTOPPERSƒvƒƒWƒFƒNƒg‚É
26 * •ñ‚·‚邱‚ƁD
27 * (4) –{ƒ\ƒtƒgƒEƒFƒA‚Ì—˜—p‚É‚æ‚è’¼Ú“I‚Ü‚½‚͊ԐړI‚ɐ¶‚¶‚é‚¢‚©‚Ȃ鑹
28 * ŠQ‚©‚ç‚àCã‹L’˜ìŒ ŽÒ‚¨‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚ð–Ɛӂ·‚邱‚ƁD
29 * ‚Ü‚½C–{ƒ\ƒtƒgƒEƒFƒA‚̃†[ƒU‚Ü‚½‚̓Gƒ“ƒhƒ†[ƒU‚©‚ç‚Ì‚¢‚©‚Ȃ闝
30 * —R‚ÉŠî‚­¿‹‚©‚ç‚àCã‹L’˜ìŒ ŽÒ‚¨‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚ð
31 * –Ɛӂ·‚邱‚ƁD
32 *
33 * –{ƒ\ƒtƒgƒEƒFƒA‚́C–³•ÛØ‚Å’ñ‹Ÿ‚³‚ê‚Ä‚¢‚é‚à‚Ì‚Å‚ ‚éDã‹L’˜ìŒ ŽÒ‚¨
34 * ‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚́C–{ƒ\ƒtƒgƒEƒFƒA‚ÉŠÖ‚µ‚āC“Á’è‚ÌŽg—p–Ú“I
35 * ‚ɑ΂·‚é“K‡«‚àŠÜ‚߂āC‚¢‚©‚È‚é•ÛØ‚às‚í‚È‚¢D‚Ü‚½C–{ƒ\ƒtƒgƒEƒF
36 * ƒA‚Ì—˜—p‚É‚æ‚è’¼Ú“I‚Ü‚½‚͊ԐړI‚ɐ¶‚¶‚½‚¢‚©‚Ȃ鑹ŠQ‚ÉŠÖ‚µ‚Ä‚àC‚»
37 * ‚̐ӔC‚𕉂í‚È‚¢D
38 *
39 * @(#) $Id: echonet_uip_task.c 101 2015-06-02 15:37:23Z coas-nagasima $
40 */
41
42/*
43 * ECHONET Lite UDP’ʐMˆ—ƒ^ƒXƒN
44 */
45#ifdef SUPPORT_UIP
46
47#include <kernel.h>
48#include <string.h>
49#include <stdio.h>
50#include <stdlib.h>
51#include <t_syslog.h>
52#include <sil.h>
53#include <uip.h>
54#include "uip_adpt.h"
55
56#include "syssvc/serial.h"
57#include "syssvc/syslog.h"
58#include "echonet.h"
59#include "echonet_task.h"
60#include "echonet_lcl_task.h"
61#include "echonet_dbg.h"
62
63#ifndef ECHONET_UDP_TASK_GET_TIMER
64#define ECHONET_UDP_TASK_GET_TIMER TMO_FEVR
65#endif /* ECHONET_UDP_TASK_GET_TIMER */
66
67#ifndef ECHONET_UDP_TASK_PROGRESS
68#define ECHONET_UDP_TASK_PROGRESS(timer)
69#endif /* ECHONET_UDP_TASK_PROGRESS */
70
71#ifndef ECHONET_UDP_TASK_TIMEOUT
72#define ECHONET_UDP_TASK_TIMEOUT
73#endif /* ECHONET_UDP_TASK_TIMEOUT */
74
75#ifndef ECHONET_UDP_SEND_TO_MBX
76#define ECHONET_UDP_SEND_TO_MBX
77#endif /* ECHONET_UDP_SEND_TO_MBX */
78
79#ifndef ECHONET_NODE_MATCH
80#define ECHONET_NODE_MATCH(enodcb, edata, ipaddr, portno) is_match(enodcb, edata, ipaddr, portno)
81#endif /* ECHONET_NODE_MATCH */
82
83static T_IN4_ADDR localhost;
84static T_IN4_ADDR multicast;
85static T_IN4_ADDR zeroaddr;
86struct uip_udp_conn *UDP_CEPID;
87
88static ECN_ENOD_ID udp_get_id(T_EDATA *edata, const T_IN4_ADDR ipaddr, uint16_t portno);
89static int udp_get_ip(T_IPV4EP *fp_ipep, ECN_ENOD_ID fa_enodid);
90void _ecn_int_msg(ECN_FBS_ID fbs_id, ECN_FBS_SSIZE_T a_snd_len);
91void _ecn_esv_msg(ECN_FBS_ID fbs_id);
92
93static struct pt pt;
94static struct uip_timer timer;
95
96/*
97 * ŽóM‚µ‚½UDPƒf[ƒ^‚ðMAILBOX‚É‘—‚é
98 */
99ER _ecn_udp2mbx(const uint8_t *buffer, size_t fa_len, const T_IPV4EP *dst);
100ER _ecn_udp2mbx(const uint8_t *buffer, size_t fa_len, const T_IPV4EP *dst)
101{
102 ECN_FBS_ID a_fbs_id = { 0 };
103 ER a_ret = E_OK;
104 ECN_ENOD_ID a_enod_id;
105 union
106 {
107 const uint8_t *buffer;
108 const T_ECN_EDT_HDR *t_esv;
109 } a_rcv_pkt;
110
111 a_rcv_pkt.buffer = buffer;
112 if ( a_rcv_pkt.t_esv->ecn_hdr.ehd1 != ECN_EDH1_ECHONET_LITE /* ECHONET Lite‹KŠi */
113 || a_rcv_pkt.t_esv->ecn_hdr.ehd2 != ECN_EDH2_FORMAT_1 /* “d•¶Œ`Ž®1 */) {
114 ECN_DBG_PUT "[UDP ECHO SRV] illegal type (0x%02X,0x%02X)", a_rcv_pkt.t_esv->ecn_hdr.ehd1, a_rcv_pkt.t_esv->ecn_hdr.ehd2 ECN_DBG_END;
115 return E_PAR;
116 }
117
118#ifdef ECN_DBG_PUT_ENA
119 _ecn_dbg_bindmp(buffer, fa_len);
120#endif
121
122 a_ret = _ecn_fbs_cre(fa_len, &a_fbs_id);
123 if (a_ret != E_OK) {
124 ECN_DBG_PUT "[UDP ECHO SRV] _ecn_fbs_cre() result = %d:%s", a_ret, itron_strerror(a_ret) ECN_DBG_END;
125 return a_ret;
126 }
127 a_ret = _ecn_fbs_add_data_ex(a_fbs_id, buffer, fa_len);
128 if (a_ret) {
129 ECN_DBG_PUT "[UDP ECHO SRV] _ecn_fbs_add_data_ex() result = %d:%s", a_ret, itron_strerror(a_ret) ECN_DBG_END;
130 goto lb_except;
131 }
132 a_fbs_id.ptr->hdr.type = ECN_MSG_ECHONET;
133 a_fbs_id.ptr->hdr.target = ENOD_LOCAL_ID;
134 a_fbs_id.ptr->hdr.sender = ENOD_NOT_MATCH_ID;
135
136 /* IPƒAƒhƒŒƒX‚©‚烊ƒ‚[ƒgECHONETƒm[ƒh‚Ö•ÏŠ· */
137 a_enod_id = udp_get_id((T_EDATA *)a_fbs_id.ptr, dst->ipaddr, dst->portno);
138 if (a_enod_id < 0 || tnum_enodadr <= a_enod_id) {
139 ECN_DBG_PUT "[UDP ECHO SRV] udp src(%s) echonet-node not found.",
140 ip2str(NULL, dst->ipaddr) ECN_DBG_END;
141 } else {
142 /* ‘—MŒ³ECHONETƒm[ƒh‚ð‹L˜^ */
143 a_fbs_id.ptr->hdr.sender = a_enod_id;
144 }
145 a_fbs_id.ptr->hdr.reply = a_fbs_id.ptr->hdr.sender;
146
147 /* echonet_task‚É‘—‚é */
148 a_ret = psnd_dtq(ecn_svc_mailboxid, (intptr_t)a_fbs_id.ptr);
149 if (a_ret != E_OK) {
150 ECN_DBG_PUT "[UDP ECHO SRV] psnd_dtq(ecn_svc_mailboxid) result = %d:%s", a_ret, itron_strerror(a_ret) ECN_DBG_END;
151 goto lb_except;
152 }
153 return a_ret;
154lb_except:
155 _ecn_fbs_del(a_fbs_id);
156 return a_ret;
157}
158
159/*
160 * ECHONET UDP’ʐMˆ—ƒ^ƒXƒN
161 */
162static
163PT_THREAD(echonet_udp_task_pt(void))
164{
165 /* UDPo—͗̈æiŽb’èj */
166 static uint_t buffer[(UIP_BUFSIZE) / sizeof(uint_t) + 1];
167
168 T_IN4_ADDR a_src;
169 ER a_ret, a_ret2;
170 ECN_FBS_SSIZE_T a_snd_len;
171 union
172 {
173 intptr_t p_msg;
174 ECN_FBS_ID fbs_id;
175 } a_mdt;
176 static SYSTIM a_prev, a_now;
177 TMO a_timer;
178 T_UDP_CCEP ccep;
179
180 PT_BEGIN(&pt);
181
182 uip_ipaddr(localhost, 127, 0, 0, 1);
183 uip_ipaddr(multicast, 224, 0, 23, 0);
184 uip_ipaddr(zeroaddr, 0, 0, 0, 0);
185 uip_ipaddr(ccep.ripaddr, 0, 0, 0, 0);
186 ccep.rport = 0;
187 ccep.lport = 3610;
188 ccep.callback = callback_nblk_udp;
189
190 uip_gethostaddr(a_src);
191 ECN_DBG_PUT "[UDP TSK:%d] started, IP Address: %s ether_max_len: %u",
192 ecn_udp_taskid,
193 ip2str(NULL, a_src),
194 UIP_BUFSIZE ECN_DBG_END;
195 uip_ipaddr_copy(enodadrb_table[ENOD_LOCAL_ID].ipaddr, a_src);
196
197 UDP_CEPID = udp_acre_cep(&ccep);
198 if (UDP_CEPID == NULL) {
199 ECN_DBG_PUT "udp_acre_cep()" ECN_DBG_END;
200 PT_EXIT(&pt);
201 }
202
203 /* ŽüŠúƒnƒ“ƒhƒ‰‚Ì‹N“® */
204 a_ret = sta_cyc(ecn_udp_cychdrid);
205 if (a_ret != E_OK) {
206 ECN_DBG_PUT "sta_cyc() result = %d:%s", a_ret, itron_strerror(a_ret) ECN_DBG_END;
207 PT_EXIT(&pt);
208 }
209
210 a_ret = act_tsk(ecn_svc_taskid);
211 if (a_ret != E_OK) {
212 ECN_DBG_PUT "act_tsk() result = %d:%s", a_ret, itron_strerror(a_ret) ECN_DBG_END;
213 PT_EXIT(&pt);
214 }
215
216 a_ret = get_tim(&a_now);
217 if (a_ret != E_OK) {
218 ECN_DBG_PUT "get_tim() result = %d:%s", a_ret, itron_strerror(a_ret) ECN_DBG_END;
219 PT_EXIT(&pt);
220 }
221
222 /* ƒƒbƒZ[ƒWƒ‹[ƒv */
223 for (;;) {
224 a_prev = a_now;
225
226 a_timer = ECHONET_UDP_TASK_GET_TIMER;
227 timer_set(&timer, a_timer);
228
229 PT_WAIT_UNTIL(&pt, (((a_ret = prcv_dtq(ecn_udp_mailboxid, &a_mdt.p_msg)) == E_OK)
230 || ((a_ret = timer_expired(&timer) ? E_TMOUT : E_WBLK) == E_TMOUT)));
231 if ((a_ret != E_OK) && (a_ret != E_TMOUT)) {
232 ECN_DBG_PUT "trcv_dtq() result = %d:%s", a_ret, itron_strerror(a_ret) ECN_DBG_END;
233 PT_EXIT(&pt);
234 }
235
236 a_ret2 = get_tim(&a_now);
237 if (a_ret2 != E_OK) {
238 ECN_DBG_PUT "get_tim() result = %d:%s", a_ret2, itron_strerror(a_ret2) ECN_DBG_END;
239 PT_EXIT(&pt);
240 }
241
242 a_timer = a_now - a_prev;
243 ECHONET_UDP_TASK_PROGRESS(a_timer);
244
245 if (a_ret == E_OK) {
246 /* ‘—Mƒf[ƒ^’·‚ðŽæ“¾ */
247 a_snd_len = _ecn_fbs_get_datalen(a_mdt.fbs_id);
248
249 ECN_DBG_PUT "[UDP TSK] trcv_dtq() mbx recv (%d byte)", a_snd_len ECN_DBG_END;
250
251 if (0 < a_snd_len) {
252 switch(a_mdt.fbs_id.ptr->hdr.type){
253 case ECN_MSG_INTERNAL:
254 _ecn_int_msg(a_mdt.fbs_id, a_snd_len);
255 break;
256 case ECN_MSG_ECHONET:
257 _ecn_esv_msg(a_mdt.fbs_id);
258 break;
259 }
260 }
261
262 _ecn_fbs_del(a_mdt.fbs_id);
263 }
264
265 ECHONET_UDP_TASK_TIMEOUT;
266 }
267
268 PT_END(&pt);
269}
270
271/*
272 * ECHONET UDP’ʐMˆ—ƒvƒƒgƒXƒŒƒbƒh‹N“®ƒ^ƒXƒN
273 */
274void echonet_udp_task(intptr_t exinf)
275{
276 echonet_udp_task_pt();
277}
278
279/*
280 * ECHONET UDP’ʐMˆ—ƒ^ƒXƒN‹N“®—pŽüŠúƒnƒ“ƒhƒ‰[
281 */
282void echonet_udp_cychdr(intptr_t exinf)
283{
284 (void)iact_tsk((ID)exinf);
285}
286
287/* ‰ž“š“d•¶—pfbsÝ’è(sender/target‚̐ݒè) */
288static ER _ecn_udp_cre_req_fbs(ID sender, uint8_t cmd, ECN_FBS_ID *pk_req)
289{
290 ER ret;
291 ECN_FBS_ID req;
292
293 ret = _ecn_fbs_cre(1, &req);
294 if (ret != E_OK) {
295 ECN_DBG_PUT "_ecn_udp_cre_req_fbs() : _ecn_fbs_cre() result = %d:%s", ret, itron_strerror(ret) ECN_DBG_END;
296 return ret;
297 }
298
299 ret = _ecn_fbs_add_data(req, &cmd, sizeof(cmd));
300 if (ret != E_OK) {
301 _ecn_fbs_del(req);
302 ECN_DBG_PUT "_ecn_udp_cre_req_fbs() : _ecn_fbs_add_data() result = %d:%s", ret, itron_strerror(ret) ECN_DBG_END;
303 return ret;
304 }
305
306 req.ptr->hdr.type = ECN_MSG_INTERNAL;
307 req.ptr->hdr.sender_mbxid = sender;
308 req.ptr->hdr.target_mbxid = ecn_udp_mailboxid;
309 req.ptr->hdr.reply_mbxid = sender;
310
311 *pk_req = req;
312
313 return E_OK;
314}
315
316/* ‰ž“š“d•¶—pfbsÝ’è(sender/target‚̐ݒè) */
317static ER _ecn_udp_cre_res_fbs(ECN_FBS_ID req, uint8_t cmd, ECN_FBS_ID *pk_res)
318{
319 ER ret;
320 ECN_FBS_ID res;
321
322 ret = _ecn_fbs_cre(1, &res);
323 if (ret != E_OK) {
324 ECN_DBG_PUT "_ecn_udp_cre_res_fbs() : _ecn_fbs_cre() result = %d:%s", ret, itron_strerror(ret) ECN_DBG_END;
325 return ret;
326 }
327
328 ret = _ecn_fbs_add_data(res, &cmd, sizeof(cmd));
329 if (ret != E_OK) {
330 _ecn_fbs_del(res);
331 ECN_DBG_PUT "_ecn_udp_cre_res_fbs() : _ecn_fbs_add_data() result = %d:%s", ret, itron_strerror(ret) ECN_DBG_END;
332 return ret;
333 }
334
335 res.ptr->hdr.type = ECN_MSG_INTERNAL;
336 res.ptr->hdr.sender_mbxid = ecn_udp_mailboxid;
337 res.ptr->hdr.target_mbxid = req.ptr->hdr.reply_mbxid;
338 res.ptr->hdr.reply_mbxid = ecn_udp_mailboxid;
339
340 *pk_res = res;
341
342 return E_OK;
343}
344
345/*
346 * “à•”ƒƒbƒZ[ƒWŽóMˆ—
347 */
348void _ecn_int_msg(ECN_FBS_ID fbs_id, ECN_FBS_SSIZE_T a_snd_len)
349{
350 ER result = E_OK, a_ret;
351 ecn_udp_msg_get_ipaddr_req_t msg;
352 ecn_udp_msg_get_ipaddr_error_t err;
353 ECN_FBS_SSIZE_T len;
354 ECN_FBS_ID buf;
355 uint8_t cmd;
356
357 a_ret = _ecn_fbs_get_data(fbs_id, &cmd, 1, &len);
358 if (a_ret != E_OK) {
359 ECN_DBG_PUT "[UDP TSK] _ecn_fbs_get_data() result = %d:%s", a_ret, itron_strerror(a_ret) ECN_DBG_END;
360 return;
361 }
362
363 switch(cmd){
364 // IPƒAƒhƒŒƒX‚ð•ÔM
365 case ECN_UDP_MSG_GET_IPADDR_REQ:
366 if (a_snd_len < sizeof(msg)) {
367 result = E_PAR;
368 break;
369 }
370
371 a_snd_len = 0;
372 a_ret = _ecn_fbs_get_data(fbs_id, &msg, sizeof(msg), &a_snd_len);
373 if (a_ret != E_OK) {
374 ECN_DBG_PUT "[UDP TSK] _ecn_fbs_get_data() result = %d:%s", a_ret, itron_strerror(a_ret) ECN_DBG_END;
375 }
376
377 if ((msg.enodid < 0) && (msg.enodid >= tnum_enodadr)) {
378 result = E_PAR;
379 break;
380 }
381
382 a_ret = _ecn_udp_cre_res_fbs(fbs_id, ECN_UDP_MSG_GET_IPADDR_RES, &buf);
383 if (a_ret != E_OK) {
384 return;
385 }
386
387 a_ret = _ecn_fbs_add_data_ex(buf, &msg.requestid, offsetof(ecn_udp_msg_get_ipaddr_res_t, enodadrb));
388 if (a_ret != E_OK) {
389 _ecn_fbs_del(buf);
390 ECN_DBG_PUT "_ecn_int_msg() : _ecn_fbs_add_data_ex() result = %d:%s", a_ret, itron_strerror(a_ret) ECN_DBG_END;
391 return;
392 }
393
394 a_ret = _ecn_fbs_add_data_ex(buf, &enodadrb_table[msg.enodid], sizeof(enodadrb_table[msg.enodid]));
395 if (a_ret != E_OK) {
396 _ecn_fbs_del(buf);
397 ECN_DBG_PUT "_ecn_int_msg() : _ecn_fbs_add_data_ex() result = %d:%s", a_ret, itron_strerror(a_ret) ECN_DBG_END;
398 return;
399 }
400
401 a_ret = psnd_dtq(buf.ptr->hdr.target_mbxid, (intptr_t)buf.ptr);
402 if (a_ret != E_OK) {
403 _ecn_fbs_del(buf);
404 ECN_DBG_PUT "_ecn_int_msg() : psnd_dtq() result = %d:%s", a_ret, itron_strerror(a_ret) ECN_DBG_END;
405 return;
406 }
407 return;
408 }
409
410 a_ret = _ecn_udp_cre_res_fbs(fbs_id, ECN_UDP_MSG_GET_IPADDR_ERROR, &buf);
411 if (a_ret != E_OK) {
412 return;
413 }
414
415 err.requestid = msg.requestid;
416 err.error = result;
417 a_ret = _ecn_fbs_add_data_ex(buf, &err, sizeof(err));
418 if (a_ret != E_OK) {
419 _ecn_fbs_del(buf);
420 ECN_DBG_PUT "_ecn_int_msg() : _ecn_fbs_add_data_ex() result = %d:%s", a_ret, itron_strerror(a_ret) ECN_DBG_END;
421 return;
422 }
423
424 a_ret = psnd_dtq(buf.ptr->hdr.target_mbxid, (intptr_t)buf.ptr);
425 if (a_ret != E_OK) {
426 _ecn_fbs_del(buf);
427 ECN_DBG_PUT "_ecn_int_msg() : psnd_dtq() result = %d:%s", a_ret, itron_strerror(a_ret) ECN_DBG_END;
428 return;
429 }
430}
431
432/*
433 * ECHONET “d•¶ŽóMˆ—
434 */
435void _ecn_esv_msg(ECN_FBS_ID fbs_id)
436{
437 /* UDPo—͗̈æiŽb’èj */
438 static uint_t buffer[(UIP_BUFSIZE) / sizeof(uint_t) + 1];
439 T_IPV4EP a_dst;
440 ER a_ret;
441 ECN_FBS_SSIZE_T a_snd_len;
442 static SYSTIM a_prev, a_now;
443
444 uip_ipaddr(a_dst.ipaddr, 0,0,0,0);
445 a_dst.portno = 0;
446 /* ‘—MæIPƒAƒhƒŒƒX */
447 a_ret = udp_get_ip(&a_dst, fbs_id.ptr->hdr.target);
448 if (!a_ret) {
449 ECN_DBG_PUT "[UDP TSK] echonet-node 0x%02X-0x%02X-0x%02X ¨ udp dest(%s)",
450 ((T_EDATA *)fbs_id.ptr)->hdr.edata.deoj.eojx1,
451 ((T_EDATA *)fbs_id.ptr)->hdr.edata.deoj.eojx2,
452 ((T_EDATA *)fbs_id.ptr)->hdr.edata.deoj.eojx3,
453 ip2str(NULL, a_dst.ipaddr) ECN_DBG_END;
454
455 /* fbs‚©‚ço—͗̈æ‚Ƀf[ƒ^‚𒊏o */
456 a_snd_len = 0;
457 a_ret = _ecn_fbs_get_data(fbs_id, buffer, sizeof(buffer), &a_snd_len);
458 if (a_ret != E_OK) {
459 ECN_DBG_PUT "[UDP TSK] _ecn_fbs_get_data() result = %d:%s", a_ret, itron_strerror(a_ret) ECN_DBG_END;
460 }
461 else if(uip_ipaddr_cmp(a_dst.ipaddr, localhost)) {
462 /* ‘—Mæ‚ª127.0.0.1 ¨ mbx‚É“]‘— */
463 ECN_DBG_PUT "redirect ecn_udp_mailboxid ¨ ecn_svc_mailboxid (esv:0x%02X)",
464 ((T_EDATA *)fbs_id.ptr)->hdr.edata.esv ECN_DBG_END;
465
466 a_ret = _ecn_udp2mbx((const uint8_t *)buffer, a_snd_len, &a_dst);
467 if (a_ret != E_OK) {
468 syslog(LOG_WARNING, "_ecn_esv_msg() : _ecn_udp2mbx() result = %d:%s", a_ret, itron_strerror(a_ret));
469 }
470 }
471 else {
472 ECN_DBG_PUT "[UDP TSK] udp_snd_dat() to:%s %ubyte(s)",
473 ip2str(NULL, a_dst.ipaddr), a_snd_len ECN_DBG_END;
474#ifdef ECN_DBG_PUT_ENA
475 _ecn_dbg_bindmp((const uint8_t *)buffer, a_snd_len);
476#endif
477 /* UDP‘—M */
478 a_ret = udp_snd_dat(UDP_CEPID, &a_dst, buffer, a_snd_len);
479 if (a_ret < 0) {
480 ECN_DBG_PUT "[UDP TSK] send, error: %s", itron_strerror(a_ret) ECN_DBG_END;
481 }
482 }
483
484 /* ƒf[ƒ^‚ª’·‚·‚¬‚Ä1ƒpƒPƒbƒg‚ÉŽû‚Ü‚ç‚È‚©‚Á‚½ê‡ */
485 if (_ecn_fbs_exist_data(fbs_id)) {
486 ECN_DBG_PUT "[UDP TSK] send, data so long: %dbyte(s)", _ecn_fbs_get_datalen(fbs_id) ECN_DBG_END;
487 }
488 } else {
489 ECN_DBG_PUT "[UDP TSK] echonet-node 0x%02X-0x%02X-0x%02X not found.",
490 ((T_EDATA *)fbs_id.ptr)->hdr.edata.deoj.eojx1,
491 ((T_EDATA *)fbs_id.ptr)->hdr.edata.deoj.eojx2,
492 ((T_EDATA *)fbs_id.ptr)->hdr.edata.deoj.eojx3 ECN_DBG_END;
493 }
494}
495
496static struct ecnl_state s;
497
498/*
499 * ƒmƒ“ƒuƒƒbƒLƒ“ƒOƒR[ƒ‹‚̃R[ƒ‹ƒoƒbƒNŠÖ”
500 */
501static
502PT_THREAD(callback_nblk_udp_pt(void))
503{
504 /* void *p_parblk = uip_buf; */
505 static uint8_t buffer[(UIP_BUFSIZE) / sizeof(uint_t) + 1];
506 T_IPV4EP dst;
507 int a_len;
508
509 PT_BEGIN(&s.pt);
510
511 /* ECN_CAP_PUT "[UDP ECHO SRV] callback_nblk_udp() recv: %u", *(int *)p_parblk ECN_CAP_END; */
512 memset(buffer, 0, sizeof(buffer));
513
514 PT_WAIT_UNTIL(&s.pt, ((a_len = udp_rcv_dat(UDP_CEPID, &dst, buffer, sizeof(buffer) - 1)) != 0));
515 if(a_len < 0) {
516 syslog(LOG_WARNING, "[UDP ECHO SRV] recv, error: %s", itron_strerror(a_len));
517 PT_EXIT(&s.pt);
518 }
519#ifdef _MSC_VER
520 /* (ŠJ”­—p) ECHONET—pƒpƒPƒbƒgˆÈŠO‚Í“Ç‚ÝŽÌ‚Ä‚é */
521 if (buffer[0] != 0x10 || buffer[1] != 0x81) {
522 PT_EXIT(&s.pt);
523 }
524#endif
525 ECN_CAP_PUT "[UDP ECHO SRV] recv, addr: %s:%d, len: %d, msg: '%s'",
526 ip2str(NULL, dst.ipaddr), dst.portno, a_len, buffer ECN_CAP_END;
527 if ((int)sizeof(buffer) <= a_len)
528 a_len = (int)sizeof(buffer) - 1;
529 if (0 < a_len) {
530 ECHONET_UDP_SEND_TO_MBX;
531
532 _ecn_udp2mbx(buffer, a_len, &dst);
533 }
534
535 PT_END(&s.pt);
536}
537
538ER callback_nblk_udp(struct uip_udp_conn *uip_udp_conn, int fncd, void *p_parblk)
539{
540 callback_nblk_udp_pt();
541
542 return E_OK;
543}
544
545void callback_nblk_tcp(void)
546{
547}
548
549/*
550 * ƒŠƒ‚[ƒgECHONETƒm[ƒh‚Ì“K‡Šm”F
551 */
552bool_t is_match(const EOBJCB *enodcb, T_EDATA *edata, const void *_ipaddr, uint16_t portno)
553{
554 /*T_IN4_ADDR *ipaddr = (T_IN4_ADDR *)_ipaddr;*/
555 ER ret;
556 T_ENUM_EPC enm;
557 uint8_t epc;
558 uint8_t pdc;
559 uint8_t p_edt[256];
560 int i, j, k;
561 int count;
562 const EOBJINIB *p_eobj;
563 bool_t match;
564
565 if (!edata)
566 return false;
567
568 /* ƒm[ƒhƒXƒ^[ƒgŽžƒCƒ“ƒXƒ^ƒ“ƒXƒŠƒXƒg’Ê’mˆÈŠO‚͏œŠO */
569 if ( edata->hdr.edata.esv != ESV_INF
570 || edata->hdr.edata.deoj.eojx1 != EOJ_X1_PROFILE
571 || edata->hdr.edata.deoj.eojx2 != EOJ_X2_NODE_PROFILE
572 || edata->hdr.edata.deoj.eojx3 != 0x01
573 || edata->hdr.edata.seoj.eojx1 != EOJ_X1_PROFILE
574 || edata->hdr.edata.seoj.eojx2 != EOJ_X2_NODE_PROFILE
575 || ( edata->hdr.edata.seoj.eojx3 != 0x01
576 && edata->hdr.edata.seoj.eojx3 != 0x02)) {
577 return false;
578 }
579
580 ret = ecn_itr_ini(&enm, edata);
581 if (ret) {
582 syslog(LOG_WARNING, "is_match(): ecn_itr_ini() result = %d:%s", ret, itron_strerror(ret));
583 return false;
584 }
585 while ((ret = ecn_itr_nxt(&enm, &epc, &pdc, p_edt)) == E_OK) {
586 if (enm.is_eof) {
587 break;
588 }
589 ECN_DBG_PUT "is_match(): ecn_itr_nxt() result: epc=0x%02X, pdc=%d", epc, pdc ECN_DBG_END;
590 /* ƒCƒ“ƒXƒ^ƒ“ƒXƒŠƒXƒg’Ê’m‚Ü‚½‚ÍŽ©ƒm[ƒhƒCƒ“ƒXƒ^ƒ“ƒXƒŠƒXƒg‚rˆÈŠO‚͏œŠO */
591 if ((epc != 0xD5) && (epc != 0xD6)) {
592 continue;
593 }
594
595 /* ‚QƒoƒCƒg–ڈȍ~‚Éeoj‚ª—ñ‹“‚³‚ê‚Ä‚¢‚é */
596 count = (pdc - 1) / sizeof(T_ECN_EOJ);
597
598 /* ƒm[ƒh“à‚Ì‹@ŠíƒIƒuƒWƒFƒNƒg‚ðŒŸõ */
599 for (k = 0; k < enodcb->eobjcnt; k++) {
600 p_eobj = enodcb->eobjs[k];
601
602 /* ƒCƒ“ƒXƒ^ƒ“ƒXƒŠƒXƒg‚ðŠm”F */
603 match = false;
604 for (i = 0, j = 1; i < count; i++, j += sizeof(T_ECN_EOJ)) {
605 if (p_eobj->eojx1 != p_edt[j])
606 continue;
607 if (p_eobj->eojx2 != p_edt[j + 1])
608 continue;
609 if (p_eobj->eojx3 != p_edt[j + 2])
610 continue;
611
612 match = true;
613 break;
614 }
615
616 if (!match)
617 return false;
618 }
619
620 /* ‚·‚ׂđµ‚Á‚Ä‚¢‚½‚ç“K‡iƒCƒ“ƒXƒ^ƒ“ƒXƒŠƒXƒg‚Ì•û‚ª‘½‚­‚Ä‚à‚¢‚¢‚±‚Æ‚Æ‚·‚éj */
621 return true;
622 }
623
624 return false;
625}
626
627/*
628 * IPƒAƒhƒŒƒX‚©‚烊ƒ‚[ƒgECHONETƒm[ƒh‚Ö•ÏŠ·
629 */
630ECN_ENOD_ID udp_get_id(T_EDATA *edata, const T_IN4_ADDR ipaddr, uint16_t portno)
631{
632 T_ENOD_ADDR *ea;
633 int i;
634
635 if (uip_ipaddr_cmp(ipaddr, localhost))
636 return ENOD_LOCAL_ID;
637 if (uip_ipaddr_cmp(ipaddr, multicast))
638 return ENOD_MULTICAST_ID;
639
640 /* IPƒAƒhƒŒƒX‚Ì“¯‚¶‚à‚Ì‚ðŒŸõ */
641 for (i = 0, ea = enodadrb_table; i < tnum_enodadr; i++, ea++) {
642 if (!ea->inuse)
643 continue;
644 if (!uip_ipaddr_cmp(ea->ipaddr, ipaddr))
645 continue;
646
647 ECN_CAP_PUT "udp_get_id(): ip-found remote(%d) = %s",
648 i - ENOD_REMOTE_ID, ip2str(NULL, ipaddr) ECN_CAP_END;
649 return (ECN_ENOD_ID)i;
650 }
651
652 /* ‘Ήž‚·‚郊ƒ‚[ƒgƒm[ƒh‚ðŒŸõ */
653 for (i = ENOD_REMOTE_ID, ea = &enodadrb_table[ENOD_REMOTE_ID]; i < tnum_enodadr; i++, ea++) {
654 if (!ea->inuse)
655 continue;
656 if ((i - ENOD_REMOTE_ID + 1) >= tnum_enodid)
657 break;
658 if (uip_ipaddr_cmp(ea->ipaddr, zeroaddr))
659 continue;
660 if (!ECHONET_NODE_MATCH(&eobjcb_table[i - ENOD_REMOTE_ID + 1], edata, ipaddr, portno))
661 continue;
662
663 /* ‘Ήž‚·‚郊ƒ‚[ƒgƒm[ƒh‚ª‚ ‚ê‚ÎIPƒAƒhƒŒƒX‚ðÝ’è */
664 uip_ipaddr_copy(ea->ipaddr, ipaddr);
665
666 ECN_CAP_PUT "udp_get_id(): enod-found remote(%d) = %s",
667 i - ENOD_REMOTE_ID, ip2str(NULL, ipaddr) ECN_CAP_END;
668 return (ECN_ENOD_ID)i;
669 }
670
671 /* ‹ó‚«—̈æ‚ð’T‚µ‚ÄŽ©“®“o˜^ */
672 for (i = ENOD_REMOTE_ID, ea = &enodadrb_table[ENOD_REMOTE_ID]; i < tnum_enodadr; i++, ea++) {
673 if (ea->inuse)
674 continue;
675
676 ea->inuse = true;
677 uip_ipaddr_copy(ea->ipaddr, ipaddr);
678
679 ECN_CAP_PUT "udp_get_id(): empty-found remote(%d) = %s",
680 i - ENOD_REMOTE_ID, ip2str(NULL, ipaddr) ECN_CAP_END;
681 return (ECN_ENOD_ID)i;
682 }
683
684 return ENOD_NOT_MATCH_ID;
685}
686
687/*
688 * ƒŠƒ‚[ƒgECHONETƒm[ƒh‚©‚çIPƒAƒhƒŒƒX‚Ö•ÏŠ·
689 */
690int udp_get_ip(T_IPV4EP *fp_ipep, ECN_ENOD_ID fa_enodid)
691{
692 T_ENOD_ADDR *ea;
693
694 if (!fp_ipep)
695 return -1; /* NG */
696
697 fp_ipep->portno = 3610;
698
699 if (fa_enodid == ENOD_MULTICAST_ID) {
700 /* target‚ªENOD_MULTICAST_ID‚̏ꍇAƒ}ƒ‹ƒ`ƒLƒƒƒXƒg‚ðs‚¤ */
701 uip_ipaddr_copy(fp_ipep->ipaddr, multicast);
702 return 0; /* ok */
703 }
704
705 if (fa_enodid < ENOD_REMOTE_ID) {
706 /* target‚ª–¢’è‹`ELOCALEAPI‚̏ꍇAƒ[ƒJƒ‹”z‘—‚ðs‚¤ */
707 uip_ipaddr_copy(fp_ipep->ipaddr, localhost);
708 return 0; /* ok */
709 }
710
711 if (fa_enodid >= tnum_enodadr)
712 return -1; /* NG */
713
714 ea = &enodadrb_table[fa_enodid];
715 if (!ea->inuse)
716 return -1; /* NG */
717
718 if (uip_ipaddr_cmp(ea->ipaddr, zeroaddr))
719 return -1; /* NG */
720
721 uip_ipaddr_copy(fp_ipep->ipaddr, ea->ipaddr);
722 return 0; /* ok */
723}
724
725ER ecn_udp_get_ipaddr(ID sender, int requestid, ECN_ENOD_ID enodid, ECN_FBS_ID *pk_req)
726{
727 ER a_ret;
728 ECN_FBS_ID req;
729
730 a_ret = _ecn_udp_cre_req_fbs(sender, ECN_UDP_MSG_GET_IPADDR_REQ, &req);
731 if (a_ret != E_OK) {
732 return a_ret;
733 }
734
735 a_ret = _ecn_fbs_add_data_ex(req, &requestid, sizeof(((ecn_udp_msg_get_ipaddr_res_t *)0)->requestid));
736 if (a_ret != E_OK) {
737 _ecn_fbs_del(req);
738 ECN_DBG_PUT "ecn_udp_get_ipaddr() : _ecn_fbs_add_data_ex() result = %d:%s", a_ret, itron_strerror(a_ret) ECN_DBG_END;
739 return a_ret;
740 }
741
742 a_ret = _ecn_fbs_add_data_ex(req, &enodid, sizeof(((ecn_udp_msg_get_ipaddr_res_t *)0)->enodid));
743 if (a_ret != E_OK) {
744 _ecn_fbs_del(req);
745 ECN_DBG_PUT "ecn_udp_get_ipaddr() : _ecn_fbs_add_data_ex() result = %d:%s", a_ret, itron_strerror(a_ret) ECN_DBG_END;
746 return a_ret;
747 }
748
749 a_ret = _ecn_fbs_add_data_ex(req, &enodadrb_table[enodid], sizeof(((ecn_udp_msg_get_ipaddr_res_t *)0)->enodadrb));
750 if (a_ret != E_OK) {
751 _ecn_fbs_del(req);
752 ECN_DBG_PUT "ecn_udp_get_ipaddr() : _ecn_fbs_add_data_ex() result = %d:%s", a_ret, itron_strerror(a_ret) ECN_DBG_END;
753 return a_ret;
754 }
755
756 *pk_req = req;
757
758 return E_OK;
759}
760
761char *ipaddr2str(char *buf, int bubsz, uint8_t *ipaddr)
762{
763 return ip2str(buf, *(T_IN4_ADDR *)ipaddr);
764}
765
766#endif
Note: See TracBrowser for help on using the repository browser.