source: uKadecot/trunk/uip/task/uip_task.c@ 125

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

ECHONET Lite規格に準拠していない動作を修正。
WebSocketの接続先URLを/webapi.ashxから/webapiに変更。
DHCPのリトライ処理が行われていなかったのを修正。
DHCPの有効/無効設定を追加し、固定IPアドレスを設定できるよう変更。

  • 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: 11.9 KB
Line 
1/*
2 * Copyright (c) 2001, Adam Dunkels.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Adam Dunkels.
16 * 4. The name of the author may not be used to endorse or promote
17 * products derived from this software without specific prior
18 * written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
21 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
24 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
26 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 * This file is part of the uIP TCP/IP stack.
33 *
34 * $Id: uip_task.c 125 2015-07-23 06:21:02Z coas-nagasima $
35 *
36 */
37
38#include <string.h>
39#include <kernel.h>
40#include "uip.h"
41#include "uip_arp.h"
42#include "timer.h"
43#include "uip_task.h"
44#include "uip_nic_config.h"
45#include "kernel_cfg.h"
46#include "uip_adpt.h"
47#include "uip_app_config.h"
48#include "sil.h"
49
50#ifndef NULL
51#define NULL (void *)0
52#endif /* NULL */
53
54struct uip_task_t {
55 ID tskid;
56 struct pt pt;
57 struct uip_timer periodic_timer, arp_timer;
58 clock_time_t timer;
59 u8_t uip_buf[UIP_BUFSIZE + 2];
60};
61
62struct uip_task_t uiptsk = {
63 UIP_TASK
64};
65
66u8_t *uip_buf = uiptsk.uip_buf;
67
68typedef struct _uip_out_buf_t
69{
70 union {
71 struct uip_conn *tcp;
72 struct uip_udp_conn *udp;
73 } cepid;
74 uip_ipaddr_t ripaddr;
75 u16_t rport;
76 int len;
77 u8_t data[UIP_BUFSIZE + 2];
78} UIP_OUT_BUF_T;
79
80#define UIP_BUF_COUNT 6
81UIP_OUT_BUF_T uip_out_buf[UIP_BUF_COUNT];
82int uip_out_wpos = 0;
83int uip_out_rpos = 0;
84u8_t my_ip[4] = { IPV4_ADDR_LOCAL };
85u8_t my_netmask[4] = { IPV4_ADDR_LOCAL_MASK };
86u8_t my_default_router[4] = { IPV4_ADDR_DEFAULT_GW };
87int ws_out_req;
88int ws_out_res;
89#ifdef __DHCPC_H__
90struct dhcpc_state *dhcpc;
91extern bool_t dhcp_enable;
92#endif
93
94/*---------------------------------------------------------------------------*/
95static
96PT_THREAD(uip_task_pt(struct uip_task_t *uiptsk))
97{
98 T_IF_SOFTC *ic = IF_ETHER_NIC_GET_SOFTC();
99 int ret;
100
101 PT_BEGIN(&uiptsk->pt);
102
103 /* NIC を初期化する。*/
104 IF_ETHER_NIC_PROBE(ic);
105 IF_ETHER_NIC_INIT(ic);
106
107 uip_sethostaddr(my_ip);
108 uip_setnetmask(my_netmask);
109 uip_setdraddr(my_default_router);
110
111 timer_set(&uiptsk->periodic_timer, CLOCK_SECOND / 2);
112 timer_set(&uiptsk->arp_timer, CLOCK_SECOND * 10);
113
114 uip_init();
115#ifdef __DHCPC_H__
116 if(dhcp_enable){
117 dhcpc = dhcpc_init(uip_ethaddr.addr, sizeof(uip_ethaddr.addr));
118 }
119#endif
120 uip_task_init((intptr_t)uiptsk);
121
122 for (;;) {
123 sil_wrb_mem((uint8_t *)0x0008C02A, sil_reb_mem((uint8_t *)0x0008C02A) & ~0x03);
124
125 PT_WAIT_UNTIL(&uiptsk->pt, (ret = ic->link_pre != ic->link_now ? 1 :
126 (ic->rxb_read != ic->rxb_write ? 2 :
127 (uip_out_buf[uip_out_rpos].len > 0 ? 3 :
128 (ws_out_req != ws_out_res ? 4 :
129 (timer_expired(&uiptsk->periodic_timer) ? 5 : 0))))) != 0);
130
131 if(ret == 1){
132 sil_wrb_mem((uint8_t *)0x0008C02A, sil_reb_mem((uint8_t *)0x0008C02A) | 0x01);
133 if(IF_ETHER_NIC_LINK(ic)){
134 bool_t cng = ic->link_pre != ic->link_now;
135 ic->link_pre = ic->link_now;
136 if(cng && ic->link_pre){
137#ifdef __DHCPC_H__
138 if(dhcp_enable){
139 sil_wrb_mem((uint8_t *)0x0008C02A, sil_reb_mem((uint8_t *)0x0008C02A) | 0x04);
140 uip_buf = uiptsk->uip_buf;
141 uip_len = 0;
142 dhcpc_request(dhcpc);
143 /* If the above function invocation resulted in data that
144 should be sent out on the network, the global variable
145 uip_len is set to a value > 0. */
146 if (uip_len > 0) {
147 uip_arp_out();
148 IF_ETHER_NIC_START(ic, uip_buf, uip_len);
149 }
150 }
151 else{
152 DHCP4_CLI_SET_ADDR_CALLBACK();
153 }
154#else
155 DHCP4_CLI_SET_ADDR_CALLBACK();
156#endif
157 }
158 }
159 PT_YIELD(&uiptsk->pt);
160 continue;
161 }
162 else if (ret == 2) {
163 sil_wrb_mem((uint8_t *)0x0008C02A, sil_reb_mem((uint8_t *)0x0008C02A) | 0x02);
164 ic->rxb_read++;
165 uip_buf = uiptsk->uip_buf;
166 uip_len = IF_ETHER_NIC_READ(ic, (void **)&uip_buf);
167 if ((uip_len > 0) && (uip_buf != NULL)){
168 if (((struct uip_eth_hdr *)uip_buf)->type == htons(UIP_ETHTYPE_IP)) {
169 uip_arp_ipin();
170 uip_input();
171 /* If the above function invocation resulted in data that
172 should be sent out on the network, the global variable
173 uip_len is set to a value > 0. */
174 if (uip_len > 0) {
175 uip_arp_out();
176 IF_ETHER_NIC_START(ic, uip_buf, uip_len);
177 PT_YIELD(&uiptsk->pt);
178 continue;
179 }
180 }
181 else if (((struct uip_eth_hdr *)uip_buf)->type == htons(UIP_ETHTYPE_ARP)) {
182 uip_arp_arpin();
183 /* If the above function invocation resulted in data that
184 should be sent out on the network, the global variable
185 uip_len is set to a value > 0. */
186 if (uip_len > 0) {
187 IF_ETHER_NIC_START(ic, uip_buf, uip_len);
188 PT_YIELD(&uiptsk->pt);
189 continue;
190 }
191 }
192 }
193 }
194#if UIP_UDP
195 else if (ret == 3) {
196 UIP_OUT_BUF_T *buf = &uip_out_buf[uip_out_rpos];
197 struct uip_udp_conn *cepid = buf->cepid.udp;
198
199 sil_wrb_mem((uint8_t *)0x0008C02A, sil_reb_mem((uint8_t *)0x0008C02A) | 0x02);
200
201 uip_ipaddr_copy(cepid->ripaddr, buf->ripaddr);
202 cepid->rport = buf->rport;
203 uip_buf = buf->data;
204 uip_udp_send(buf->len);
205
206 buf->len = 0;
207 uip_out_rpos++;
208 if (uip_out_rpos >= UIP_BUF_COUNT)
209 uip_out_rpos = 0;
210
211 uip_udp_conn = cepid;
212 uip_process(UIP_UDP_SEND_CONN);
213 uip_ipaddr(cepid->ripaddr, 0, 0, 0, 0);
214 cepid->rport = 0;
215 uip_arp_out();
216 IF_ETHER_NIC_START(ic, uip_buf, uip_len);
217 PT_YIELD(&uiptsk->pt);
218 continue;
219 }
220#endif /* UIP_UDP */
221 else if (ret == 4) {
222 sil_wrb_mem((uint8_t *)0x0008C02A, sil_reb_mem((uint8_t *)0x0008C02A) | 0x02);
223 ws_out_res++;
224 for (ic->udp_pos = 0; ic->udp_pos < UIP_CONNS; ic->udp_pos++) {
225 uip_buf = uiptsk->uip_buf;
226 uip_len = 0;
227 uip_poll_conn(&uip_conns[ic->udp_pos]);
228 /* If the above function invocation resulted in data that
229 should be sent out on the network, the global variable
230 uip_len is set to a value > 0. */
231 if (uip_len > 0) {
232 uip_arp_out();
233 IF_ETHER_NIC_START(ic, uip_buf, uip_len);
234 PT_YIELD(&uiptsk->pt);
235 }
236 }
237 }
238 else if (ret == 5) {
239 timer_reset(&uiptsk->periodic_timer);
240 for (ic->udp_pos = 0; ic->udp_pos < UIP_CONNS; ic->udp_pos++) {
241 uip_buf = uiptsk->uip_buf;
242 uip_len = 0;
243 uip_periodic(ic->udp_pos);
244 /* If the above function invocation resulted in data that
245 should be sent out on the network, the global variable
246 uip_len is set to a value > 0. */
247 if (uip_len > 0) {
248 uip_arp_out();
249 IF_ETHER_NIC_START(ic, uip_buf, uip_len);
250 PT_YIELD(&uiptsk->pt);
251 }
252 }
253#if UIP_UDP
254 for (ic->udp_pos = 0; ic->udp_pos < UIP_UDP_CONNS; ic->udp_pos++) {
255 uip_buf = uiptsk->uip_buf;
256 uip_len = 0;
257 uip_udp_periodic(ic->udp_pos);
258 /* If the above function invocation resulted in data that
259 should be sent out on the network, the global variable
260 uip_len is set to a value > 0. */
261 if (uip_len > 0) {
262 uip_arp_out();
263 IF_ETHER_NIC_START(ic, uip_buf, uip_len);
264 PT_YIELD(&uiptsk->pt);
265 }
266 }
267#endif /* UIP_UDP */
268
269 /* Call the ARP timer function every 10 seconds. */
270 if (timer_expired(&uiptsk->arp_timer)) {
271 timer_reset(&uiptsk->arp_timer);
272 uip_buf = uiptsk->uip_buf;
273 uip_len = 0;
274 uip_arp_timer();
275 }
276 }
277 }
278
279 PT_END(&uiptsk->pt);
280}
281
282/*
283 * uIP プロトスレッド起動タスク
284 */
285void uip_task(intptr_t exinf)
286{
287 struct uip_task_t *uiptsk = (struct uip_task_t *)exinf;
288
289 uip_task_pt(uiptsk);
290}
291
292/*
293 * uIP タスク起動用周期ハンドラー
294 */
295void uip_cychdr(intptr_t exinf)
296{
297 struct uip_task_t *uiptsk = (struct uip_task_t *)exinf;
298 uiptsk->timer++;
299#ifndef UIP_ACT_TSK_ONLY_ON_SEND
300 if(timer_expired(&uiptsk->periodic_timer))
301 (void)iact_tsk(uiptsk->tskid);
302#endif
303}
304
305struct uip_conn *
306tcp_acre_cep(const T_TCP_CCEP *pk_ccep)
307{
308 struct uip_conn *cepid;
309
310 cepid = uip_connect((uip_ipaddr_t *)&pk_ccep->ripaddr, htons(pk_ccep->rport));
311 if (cepid != NULL) {
312 //cepid->appstate.tcp_callback = pk_ccep->callback;
313 }
314
315 return cepid;
316}
317
318int
319tcp_snd_dat(struct uip_conn *cepid, T_IPV4EP *p_dstaddr, void *data, int len)
320{
321 UIP_OUT_BUF_T *buf = &uip_out_buf[uip_out_wpos];
322
323 if (buf->len == 0) {
324 buf->cepid.tcp = cepid;
325 uip_ipaddr_copy(buf->ripaddr, p_dstaddr->ipaddr);
326 buf->rport = htons(p_dstaddr->portno);
327 memcpy(&buf->data[UIP_IPTCPH_LEN + UIP_LLH_LEN], data, len);
328 uip_out_buf[uip_out_wpos].len = len;
329 uip_out_wpos++;
330 if (uip_out_wpos >= UIP_BUF_COUNT)
331 uip_out_wpos = 0;
332#ifndef UIP_ACT_TSK_ONLY_ON_SEND
333 act_tsk(UIP_TASK);
334#endif
335 return len;
336 }
337
338 return 0;
339}
340
341int
342tcp_rcv_dat(struct uip_conn *cepid, T_IPV4EP *p_srcaddr, void *data, int len)
343{
344 int rlen;
345
346 if (!uip_newdata())
347 return 0;
348
349 rlen = uip_datalen();
350 if (rlen > len)
351 rlen = len;
352
353 uip_ipaddr_copy(p_srcaddr->ipaddr, ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])->srcipaddr);
354 p_srcaddr->portno = ntohs(((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])->srcport);
355 memcpy(data, uip_appdata, rlen);
356
357 return rlen;
358}
359
360void uip_appcall(void)
361{
362 uip_tcp_appstate_t *s = &uip_conn->appstate;
363 //s->tcp_callback(uip_conn, 0, &s->parblk);
364}
365#if UIP_UDP
366/*---------------------------------------------------------------------------*/
367struct uip_udp_conn *
368udp_acre_cep(const T_UDP_CCEP *pk_ccep)
369{
370 struct uip_udp_conn *cepid;
371
372 cepid = uip_udp_new((uip_ipaddr_t *)&pk_ccep->ripaddr, htons(pk_ccep->rport));
373 if (cepid != NULL) {
374 cepid->appstate.udp_callback = pk_ccep->callback;
375 uip_udp_bind(cepid, htons(pk_ccep->lport));
376 }
377
378 return cepid;
379}
380
381int
382udp_snd_dat(struct uip_udp_conn *cepid, T_IPV4EP *p_dstaddr, void *data, int len)
383{
384 UIP_OUT_BUF_T *buf = &uip_out_buf[uip_out_wpos];
385
386 if (buf->len == 0) {
387 buf->cepid.udp = cepid;
388 uip_ipaddr_copy(buf->ripaddr, p_dstaddr->ipaddr);
389 buf->rport = htons(p_dstaddr->portno);
390 memcpy(&buf->data[UIP_IPUDPH_LEN + UIP_LLH_LEN], data, len);
391 uip_out_buf[uip_out_wpos].len = len;
392 uip_out_wpos++;
393 if (uip_out_wpos >= UIP_BUF_COUNT)
394 uip_out_wpos = 0;
395#ifndef UIP_ACT_TSK_ONLY_ON_SEND
396 act_tsk(UIP_TASK);
397#endif
398 return len;
399 }
400
401 return 0;
402}
403
404int
405udp_rcv_dat(struct uip_udp_conn *cepid, T_IPV4EP *p_srcaddr, void *data, int len)
406{
407 int rlen;
408
409 if (!uip_newdata())
410 return 0;
411
412 rlen = uip_datalen();
413 if (rlen > len)
414 rlen = len;
415
416 uip_ipaddr_copy(p_srcaddr->ipaddr, ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])->srcipaddr);
417 p_srcaddr->portno = ntohs(((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])->srcport);
418 memcpy(data, uip_appdata, rlen);
419
420 return rlen;
421}
422
423void uip_udp_appcall(void)
424{
425 uip_udp_appstate_t *s = &uip_udp_conn->appstate;
426 s->udp_callback(uip_udp_conn, 0, &s->parblk);
427}
428#endif
429/*---------------------------------------------------------------------------*/
430void
431uip_log(char *m)
432{
433 printf("uIP log message: %s\n", m);
434}
435#ifdef __DHCPC_H__
436void
437dhcpc_configured(const struct dhcpc_state *s)
438{
439 sil_wrb_mem((uint8_t *)0x0008C02A, sil_reb_mem((uint8_t *)0x0008C02A) & ~0x04);
440 uip_sethostaddr(s->ipaddr);
441 uip_setnetmask(s->netmask);
442 uip_setdraddr(s->default_router);
443 // resolv_conf(s->dnsaddr);
444 DHCP4_CLI_SET_ADDR_CALLBACK();
445}
446#endif /* __DHCPC_H__ */
447/*---------------------------------------------------------------------------*/
448clock_time_t clock_time(void)
449{
450 return uiptsk.timer;
451}
Note: See TracBrowser for help on using the repository browser.