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

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

インクルードのパス指定をContikiに合わせ変更。
整数型の型名をContikiに合わせ変更。

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