source: uKadecot/trunk/uip/task/uip_task.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: 11.8 KB
RevLine 
[101]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 108 2015-06-11 09:15:46Z 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;
84const u8_t my_ip[4] = { IPV4_ADDR_LOCAL };
85const u8_t my_netmask[4] = { IPV4_ADDR_LOCAL_MASK };
86const u8_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;
91#endif
92
93/*---------------------------------------------------------------------------*/
94static
95PT_THREAD(uip_task_pt(struct uip_task_t *uiptsk))
96{
97 T_IF_SOFTC *ic = IF_ETHER_NIC_GET_SOFTC();
98 int ret;
99
100 PT_BEGIN(&uiptsk->pt);
101
102 /* NIC を初期化する。*/
103 IF_ETHER_NIC_PROBE(ic);
104 IF_ETHER_NIC_INIT(ic);
105
106 uip_sethostaddr(my_ip);
107 uip_setnetmask(my_netmask);
108 uip_setdraddr(my_default_router);
109
110 timer_set(&uiptsk->periodic_timer, CLOCK_SECOND / 2);
111 timer_set(&uiptsk->arp_timer, CLOCK_SECOND * 10);
112
113 uip_init();
114#ifdef __DHCPC_H__
115 dhcpc = dhcpc_init(uip_ethaddr.addr, sizeof(uip_ethaddr.addr));
116#endif
117 uip_task_init((intptr_t)uiptsk);
118
119 for (;;) {
120 sil_wrb_mem((uint8_t *)0x0008C02A, sil_reb_mem((uint8_t *)0x0008C02A) & ~0x03);
121
122 PT_WAIT_UNTIL(&uiptsk->pt, (ret = ic->link_pre != ic->link_now ? 1 :
123 (ic->rxb_read != ic->rxb_write ? 2 :
124 (uip_out_buf[uip_out_rpos].len > 0 ? 3 :
125 (ws_out_req != ws_out_res ? 4 :
126 (timer_expired(&uiptsk->periodic_timer) ? 5 : 0))))) != 0);
127
128 if(ret == 1){
129 sil_wrb_mem((uint8_t *)0x0008C02A, sil_reb_mem((uint8_t *)0x0008C02A) | 0x01);
130 if(IF_ETHER_NIC_LINK(ic)){
131 bool_t cng = ic->link_pre != ic->link_now;
132 ic->link_pre = ic->link_now;
133 if(cng && ic->link_pre){
134 sil_wrb_mem((uint8_t *)0x0008C02A, sil_reb_mem((uint8_t *)0x0008C02A) | 0x04);
135#ifdef __DHCPC_H__
136 uip_buf = uiptsk->uip_buf;
137 uip_len = 0;
138 dhcpc_request(dhcpc);
139 /* If the above function invocation resulted in data that
140 should be sent out on the network, the global variable
141 uip_len is set to a value > 0. */
142 if (uip_len > 0) {
143 uip_arp_out();
144 IF_ETHER_NIC_START(ic, uip_buf, uip_len);
145 }
146#else
147 DHCP4_CLI_SET_ADDR_CALLBACK();
148#endif
149 }
150 }
151 PT_YIELD(&uiptsk->pt);
152 continue;
153 }
154 else if (ret == 2) {
155 sil_wrb_mem((uint8_t *)0x0008C02A, sil_reb_mem((uint8_t *)0x0008C02A) | 0x02);
156 ic->rxb_read++;
157 uip_buf = uiptsk->uip_buf;
158 uip_len = IF_ETHER_NIC_READ(ic, (void **)&uip_buf);
159 if ((uip_len > 0) && (uip_buf != NULL)){
160 if (((struct uip_eth_hdr *)uip_buf)->type == htons(UIP_ETHTYPE_IP)) {
161 uip_arp_ipin();
162 uip_input();
163 /* If the above function invocation resulted in data that
164 should be sent out on the network, the global variable
165 uip_len is set to a value > 0. */
166 if (uip_len > 0) {
167 uip_arp_out();
168 IF_ETHER_NIC_START(ic, uip_buf, uip_len);
169 PT_YIELD(&uiptsk->pt);
170 continue;
171 }
172 }
173 else if (((struct uip_eth_hdr *)uip_buf)->type == htons(UIP_ETHTYPE_ARP)) {
174 uip_arp_arpin();
175 /* If the above function invocation resulted in data that
176 should be sent out on the network, the global variable
177 uip_len is set to a value > 0. */
178 if (uip_len > 0) {
179 IF_ETHER_NIC_START(ic, uip_buf, uip_len);
180 PT_YIELD(&uiptsk->pt);
181 continue;
182 }
183 }
184 }
185 }
186#if UIP_UDP
187 else if (ret == 3) {
188 UIP_OUT_BUF_T *buf = &uip_out_buf[uip_out_rpos];
189 struct uip_udp_conn *cepid = buf->cepid.udp;
190
191 sil_wrb_mem((uint8_t *)0x0008C02A, sil_reb_mem((uint8_t *)0x0008C02A) | 0x02);
192
193 uip_ipaddr_copy(cepid->ripaddr, buf->ripaddr);
194 cepid->rport = buf->rport;
195 uip_buf = buf->data;
196 uip_udp_send(buf->len);
197
198 buf->len = 0;
199 uip_out_rpos++;
200 if (uip_out_rpos >= UIP_BUF_COUNT)
201 uip_out_rpos = 0;
202
203 uip_udp_conn = cepid;
204 uip_process(UIP_UDP_SEND_CONN);
205 uip_ipaddr(cepid->ripaddr, 0, 0, 0, 0);
206 cepid->rport = 0;
207 uip_arp_out();
208 IF_ETHER_NIC_START(ic, uip_buf, uip_len);
209 PT_YIELD(&uiptsk->pt);
210 continue;
211 }
212#endif /* UIP_UDP */
213 else if (ret == 4) {
214 sil_wrb_mem((uint8_t *)0x0008C02A, sil_reb_mem((uint8_t *)0x0008C02A) | 0x02);
215 ws_out_res++;
216 for (ic->udp_pos = 0; ic->udp_pos < UIP_CONNS; ic->udp_pos++) {
217 uip_buf = uiptsk->uip_buf;
218 uip_len = 0;
219 uip_poll_conn(&uip_conns[ic->udp_pos]);
220 /* If the above function invocation resulted in data that
221 should be sent out on the network, the global variable
222 uip_len is set to a value > 0. */
223 if (uip_len > 0) {
224 uip_arp_out();
225 IF_ETHER_NIC_START(ic, uip_buf, uip_len);
226 PT_YIELD(&uiptsk->pt);
227 }
228 }
229 }
230 else if (ret == 5) {
231 timer_reset(&uiptsk->periodic_timer);
232 for (ic->udp_pos = 0; ic->udp_pos < UIP_CONNS; ic->udp_pos++) {
233 uip_buf = uiptsk->uip_buf;
234 uip_len = 0;
235 uip_periodic(ic->udp_pos);
236 /* If the above function invocation resulted in data that
237 should be sent out on the network, the global variable
238 uip_len is set to a value > 0. */
239 if (uip_len > 0) {
240 uip_arp_out();
241 IF_ETHER_NIC_START(ic, uip_buf, uip_len);
242 PT_YIELD(&uiptsk->pt);
243 }
244 }
245#if UIP_UDP
246 for (ic->udp_pos = 0; ic->udp_pos < UIP_UDP_CONNS; ic->udp_pos++) {
247 uip_buf = uiptsk->uip_buf;
248 uip_len = 0;
249 uip_udp_periodic(ic->udp_pos);
250 /* If the above function invocation resulted in data that
251 should be sent out on the network, the global variable
252 uip_len is set to a value > 0. */
253 if (uip_len > 0) {
254 uip_arp_out();
255 IF_ETHER_NIC_START(ic, uip_buf, uip_len);
256 PT_YIELD(&uiptsk->pt);
257 }
258 }
259#endif /* UIP_UDP */
260
261 /* Call the ARP timer function every 10 seconds. */
262 if (timer_expired(&uiptsk->arp_timer)) {
263 timer_reset(&uiptsk->arp_timer);
264 uip_buf = uiptsk->uip_buf;
265 uip_len = 0;
266 uip_arp_timer();
267 }
268 }
269 }
270
271 PT_END(&uiptsk->pt);
272}
273
274/*
275 * uIP プロトスレッド起動タスク
276 */
277void uip_task(intptr_t exinf)
278{
279 struct uip_task_t *uiptsk = (struct uip_task_t *)exinf;
280
281 uip_task_pt(uiptsk);
282}
283
284/*
285 * uIP タスク起動用周期ハンドラー
286 */
287void uip_cychdr(intptr_t exinf)
288{
289 struct uip_task_t *uiptsk = (struct uip_task_t *)exinf;
290 uiptsk->timer++;
291#ifndef UIP_ACT_TSK_ONLY_ON_SEND
292 if(timer_expired(&uiptsk->periodic_timer))
293 (void)iact_tsk(uiptsk->tskid);
294#endif
295}
296
297struct uip_conn *
298tcp_acre_cep(const T_TCP_CCEP *pk_ccep)
299{
300 struct uip_conn *cepid;
301
302 cepid = uip_connect((uip_ipaddr_t *)&pk_ccep->ripaddr, htons(pk_ccep->rport));
303 if (cepid != NULL) {
304 //cepid->appstate.tcp_callback = pk_ccep->callback;
305 }
306
307 return cepid;
308}
309
310int
311tcp_snd_dat(struct uip_conn *cepid, T_IPV4EP *p_dstaddr, void *data, int len)
312{
313 UIP_OUT_BUF_T *buf = &uip_out_buf[uip_out_wpos];
314
315 if (buf->len == 0) {
316 buf->cepid.tcp = cepid;
317 uip_ipaddr_copy(buf->ripaddr, p_dstaddr->ipaddr);
318 buf->rport = htons(p_dstaddr->portno);
319 memcpy(&buf->data[UIP_IPTCPH_LEN + UIP_LLH_LEN], data, len);
320 uip_out_buf[uip_out_wpos].len = len;
321 uip_out_wpos++;
322 if (uip_out_wpos >= UIP_BUF_COUNT)
323 uip_out_wpos = 0;
324#ifndef UIP_ACT_TSK_ONLY_ON_SEND
325 act_tsk(UIP_TASK);
326#endif
327 return len;
328 }
329
330 return 0;
331}
332
333int
334tcp_rcv_dat(struct uip_conn *cepid, T_IPV4EP *p_srcaddr, void *data, int len)
335{
336 int rlen;
337
338 if (!uip_newdata())
339 return 0;
340
341 rlen = uip_datalen();
342 if (rlen > len)
343 rlen = len;
344
345 uip_ipaddr_copy(p_srcaddr->ipaddr, ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])->srcipaddr);
346 p_srcaddr->portno = ntohs(((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])->srcport);
347 memcpy(data, uip_appdata, rlen);
348
349 return rlen;
350}
351
352void uip_appcall(void)
353{
354 uip_tcp_appstate_t *s = &uip_conn->appstate;
355 //s->tcp_callback(uip_conn, 0, &s->parblk);
356}
357#if UIP_UDP
358/*---------------------------------------------------------------------------*/
359struct uip_udp_conn *
360udp_acre_cep(const T_UDP_CCEP *pk_ccep)
361{
362 struct uip_udp_conn *cepid;
363
364 cepid = uip_udp_new((uip_ipaddr_t *)&pk_ccep->ripaddr, htons(pk_ccep->rport));
365 if (cepid != NULL) {
366 cepid->appstate.udp_callback = pk_ccep->callback;
367 uip_udp_bind(cepid, htons(pk_ccep->lport));
368 }
369
370 return cepid;
371}
372
373int
374udp_snd_dat(struct uip_udp_conn *cepid, T_IPV4EP *p_dstaddr, void *data, int len)
375{
376 UIP_OUT_BUF_T *buf = &uip_out_buf[uip_out_wpos];
377
378 if (buf->len == 0) {
379 buf->cepid.udp = cepid;
380 uip_ipaddr_copy(buf->ripaddr, p_dstaddr->ipaddr);
381 buf->rport = htons(p_dstaddr->portno);
382 memcpy(&buf->data[UIP_IPUDPH_LEN + UIP_LLH_LEN], data, len);
383 uip_out_buf[uip_out_wpos].len = len;
384 uip_out_wpos++;
385 if (uip_out_wpos >= UIP_BUF_COUNT)
386 uip_out_wpos = 0;
387#ifndef UIP_ACT_TSK_ONLY_ON_SEND
388 act_tsk(UIP_TASK);
389#endif
390 return len;
391 }
392
393 return 0;
394}
395
396int
397udp_rcv_dat(struct uip_udp_conn *cepid, T_IPV4EP *p_srcaddr, void *data, int len)
398{
399 int rlen;
400
401 if (!uip_newdata())
402 return 0;
403
404 rlen = uip_datalen();
405 if (rlen > len)
406 rlen = len;
407
408 uip_ipaddr_copy(p_srcaddr->ipaddr, ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])->srcipaddr);
409 p_srcaddr->portno = ntohs(((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])->srcport);
410 memcpy(data, uip_appdata, rlen);
411
412 return rlen;
413}
414
415void uip_udp_appcall(void)
416{
417 uip_udp_appstate_t *s = &uip_udp_conn->appstate;
418 s->udp_callback(uip_udp_conn, 0, &s->parblk);
419}
420#endif
421/*---------------------------------------------------------------------------*/
422void
423uip_log(char *m)
424{
425 printf("uIP log message: %s\n", m);
426}
427#ifdef __DHCPC_H__
428void
429dhcpc_configured(const struct dhcpc_state *s)
430{
431 sil_wrb_mem((uint8_t *)0x0008C02A, sil_reb_mem((uint8_t *)0x0008C02A) & ~0x04);
432 uip_sethostaddr(s->ipaddr);
433 uip_setnetmask(s->netmask);
434 uip_setdraddr(s->default_router);
435 // resolv_conf(s->dnsaddr);
436 DHCP4_CLI_SET_ADDR_CALLBACK();
437}
438#endif /* __DHCPC_H__ */
439/*---------------------------------------------------------------------------*/
440clock_time_t clock_time(void)
441{
442 return uiptsk.timer;
443}
Note: See TracBrowser for help on using the repository browser.