Small Testprogram to have WebAccess via Webserver to a 433Mhz tranmitter to control remotly some devices from remote, with TFTP, NTP and RMF. This could be a base to develop applications.

Dependencies:   ChaNFSSD TFTPServer RMFWeb

Dependents:   RMFWeb

Committer:
ED7418
Date:
Mon Jun 16 07:40:08 2014 +0000
Revision:
1:809b59c7a800
Parent:
0:51f1ef89ec7b
mbed-lib and other libs are a based on a project, published in a Elektor-book "ARM-microkontroller Part II".

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ED7418 0:51f1ef89ec7b 1 /**
ED7418 0:51f1ef89ec7b 2 * @file
ED7418 0:51f1ef89ec7b 3 * Stack-internal timers implementation.
ED7418 0:51f1ef89ec7b 4 * This file includes timer callbacks for stack-internal timers as well as
ED7418 0:51f1ef89ec7b 5 * functions to set up or stop timers and check for expired timers.
ED7418 0:51f1ef89ec7b 6 *
ED7418 0:51f1ef89ec7b 7 */
ED7418 0:51f1ef89ec7b 8
ED7418 0:51f1ef89ec7b 9 /*
ED7418 0:51f1ef89ec7b 10 * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
ED7418 0:51f1ef89ec7b 11 * All rights reserved.
ED7418 0:51f1ef89ec7b 12 *
ED7418 0:51f1ef89ec7b 13 * Redistribution and use in source and binary forms, with or without modification,
ED7418 0:51f1ef89ec7b 14 * are permitted provided that the following conditions are met:
ED7418 0:51f1ef89ec7b 15 *
ED7418 0:51f1ef89ec7b 16 * 1. Redistributions of source code must retain the above copyright notice,
ED7418 0:51f1ef89ec7b 17 * this list of conditions and the following disclaimer.
ED7418 0:51f1ef89ec7b 18 * 2. Redistributions in binary form must reproduce the above copyright notice,
ED7418 0:51f1ef89ec7b 19 * this list of conditions and the following disclaimer in the documentation
ED7418 0:51f1ef89ec7b 20 * and/or other materials provided with the distribution.
ED7418 0:51f1ef89ec7b 21 * 3. The name of the author may not be used to endorse or promote products
ED7418 0:51f1ef89ec7b 22 * derived from this software without specific prior written permission.
ED7418 0:51f1ef89ec7b 23 *
ED7418 0:51f1ef89ec7b 24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
ED7418 0:51f1ef89ec7b 25 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
ED7418 0:51f1ef89ec7b 26 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
ED7418 0:51f1ef89ec7b 27 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
ED7418 0:51f1ef89ec7b 28 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
ED7418 0:51f1ef89ec7b 29 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
ED7418 0:51f1ef89ec7b 30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
ED7418 0:51f1ef89ec7b 31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
ED7418 0:51f1ef89ec7b 32 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
ED7418 0:51f1ef89ec7b 33 * OF SUCH DAMAGE.
ED7418 0:51f1ef89ec7b 34 *
ED7418 0:51f1ef89ec7b 35 * This file is part of the lwIP TCP/IP stack.
ED7418 0:51f1ef89ec7b 36 *
ED7418 0:51f1ef89ec7b 37 * Author: Adam Dunkels <adam@sics.se>
ED7418 0:51f1ef89ec7b 38 * Simon Goldschmidt
ED7418 0:51f1ef89ec7b 39 *
ED7418 0:51f1ef89ec7b 40 */
ED7418 0:51f1ef89ec7b 41
ED7418 0:51f1ef89ec7b 42 #include "lwip/opt.h"
ED7418 0:51f1ef89ec7b 43
ED7418 0:51f1ef89ec7b 44 #include "lwip/timers.h"
ED7418 0:51f1ef89ec7b 45
ED7418 0:51f1ef89ec7b 46 #if LWIP_TIMERS
ED7418 0:51f1ef89ec7b 47
ED7418 0:51f1ef89ec7b 48 #include "lwip/def.h"
ED7418 0:51f1ef89ec7b 49 #include "lwip/memp.h"
ED7418 0:51f1ef89ec7b 50 #include "lwip/tcpip.h"
ED7418 0:51f1ef89ec7b 51
ED7418 0:51f1ef89ec7b 52 #include "lwip/tcp_impl.h"
ED7418 0:51f1ef89ec7b 53 #include "lwip/ip_frag.h"
ED7418 0:51f1ef89ec7b 54 #include "netif/etharp.h"
ED7418 0:51f1ef89ec7b 55 #include "lwip/dhcp.h"
ED7418 0:51f1ef89ec7b 56 #include "lwip/autoip.h"
ED7418 0:51f1ef89ec7b 57 #include "lwip/igmp.h"
ED7418 0:51f1ef89ec7b 58 #include "lwip/dns.h"
ED7418 0:51f1ef89ec7b 59
ED7418 0:51f1ef89ec7b 60
ED7418 0:51f1ef89ec7b 61 /** The one and only timeout list */
ED7418 0:51f1ef89ec7b 62 static struct sys_timeo *next_timeout;
ED7418 0:51f1ef89ec7b 63 #if NO_SYS
ED7418 0:51f1ef89ec7b 64 static u32_t timeouts_last_time;
ED7418 0:51f1ef89ec7b 65 #endif /* NO_SYS */
ED7418 0:51f1ef89ec7b 66
ED7418 0:51f1ef89ec7b 67 #if LWIP_TCP
ED7418 0:51f1ef89ec7b 68 /** global variable that shows if the tcp timer is currently scheduled or not */
ED7418 0:51f1ef89ec7b 69 static int tcpip_tcp_timer_active;
ED7418 0:51f1ef89ec7b 70
ED7418 0:51f1ef89ec7b 71 /**
ED7418 0:51f1ef89ec7b 72 * Timer callback function that calls tcp_tmr() and reschedules itself.
ED7418 0:51f1ef89ec7b 73 *
ED7418 0:51f1ef89ec7b 74 * @param arg unused argument
ED7418 0:51f1ef89ec7b 75 */
ED7418 0:51f1ef89ec7b 76 static void
ED7418 0:51f1ef89ec7b 77 tcpip_tcp_timer(void *arg)
ED7418 0:51f1ef89ec7b 78 {
ED7418 0:51f1ef89ec7b 79 LWIP_UNUSED_ARG(arg);
ED7418 0:51f1ef89ec7b 80
ED7418 0:51f1ef89ec7b 81 /* call TCP timer handler */
ED7418 0:51f1ef89ec7b 82 tcp_tmr();
ED7418 0:51f1ef89ec7b 83 /* timer still needed? */
ED7418 0:51f1ef89ec7b 84 if (tcp_active_pcbs || tcp_tw_pcbs) {
ED7418 0:51f1ef89ec7b 85 /* restart timer */
ED7418 0:51f1ef89ec7b 86 sys_timeout(TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL);
ED7418 0:51f1ef89ec7b 87 } else {
ED7418 0:51f1ef89ec7b 88 /* disable timer */
ED7418 0:51f1ef89ec7b 89 tcpip_tcp_timer_active = 0;
ED7418 0:51f1ef89ec7b 90 }
ED7418 0:51f1ef89ec7b 91 }
ED7418 0:51f1ef89ec7b 92
ED7418 0:51f1ef89ec7b 93 /**
ED7418 0:51f1ef89ec7b 94 * Called from TCP_REG when registering a new PCB:
ED7418 0:51f1ef89ec7b 95 * the reason is to have the TCP timer only running when
ED7418 0:51f1ef89ec7b 96 * there are active (or time-wait) PCBs.
ED7418 0:51f1ef89ec7b 97 */
ED7418 0:51f1ef89ec7b 98 void
ED7418 0:51f1ef89ec7b 99 tcp_timer_needed(void)
ED7418 0:51f1ef89ec7b 100 {
ED7418 0:51f1ef89ec7b 101 /* timer is off but needed again? */
ED7418 0:51f1ef89ec7b 102 if (!tcpip_tcp_timer_active && (tcp_active_pcbs || tcp_tw_pcbs)) {
ED7418 0:51f1ef89ec7b 103 /* enable and start timer */
ED7418 0:51f1ef89ec7b 104 tcpip_tcp_timer_active = 1;
ED7418 0:51f1ef89ec7b 105 sys_timeout(TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL);
ED7418 0:51f1ef89ec7b 106 }
ED7418 0:51f1ef89ec7b 107 }
ED7418 0:51f1ef89ec7b 108 #endif /* LWIP_TCP */
ED7418 0:51f1ef89ec7b 109
ED7418 0:51f1ef89ec7b 110 #if IP_REASSEMBLY
ED7418 0:51f1ef89ec7b 111 /**
ED7418 0:51f1ef89ec7b 112 * Timer callback function that calls ip_reass_tmr() and reschedules itself.
ED7418 0:51f1ef89ec7b 113 *
ED7418 0:51f1ef89ec7b 114 * @param arg unused argument
ED7418 0:51f1ef89ec7b 115 */
ED7418 0:51f1ef89ec7b 116 static void
ED7418 0:51f1ef89ec7b 117 ip_reass_timer(void *arg)
ED7418 0:51f1ef89ec7b 118 {
ED7418 0:51f1ef89ec7b 119 LWIP_UNUSED_ARG(arg);
ED7418 0:51f1ef89ec7b 120 LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: ip_reass_tmr()\n"));
ED7418 0:51f1ef89ec7b 121 ip_reass_tmr();
ED7418 0:51f1ef89ec7b 122 sys_timeout(IP_TMR_INTERVAL, ip_reass_timer, NULL);
ED7418 0:51f1ef89ec7b 123 }
ED7418 0:51f1ef89ec7b 124 #endif /* IP_REASSEMBLY */
ED7418 0:51f1ef89ec7b 125
ED7418 0:51f1ef89ec7b 126 #if LWIP_ARP
ED7418 0:51f1ef89ec7b 127 /**
ED7418 0:51f1ef89ec7b 128 * Timer callback function that calls etharp_tmr() and reschedules itself.
ED7418 0:51f1ef89ec7b 129 *
ED7418 0:51f1ef89ec7b 130 * @param arg unused argument
ED7418 0:51f1ef89ec7b 131 */
ED7418 0:51f1ef89ec7b 132 static void
ED7418 0:51f1ef89ec7b 133 arp_timer(void *arg)
ED7418 0:51f1ef89ec7b 134 {
ED7418 0:51f1ef89ec7b 135 LWIP_UNUSED_ARG(arg);
ED7418 0:51f1ef89ec7b 136 LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: etharp_tmr()\n"));
ED7418 0:51f1ef89ec7b 137 etharp_tmr();
ED7418 0:51f1ef89ec7b 138 sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);
ED7418 0:51f1ef89ec7b 139 }
ED7418 0:51f1ef89ec7b 140 #endif /* LWIP_ARP */
ED7418 0:51f1ef89ec7b 141
ED7418 0:51f1ef89ec7b 142 #if LWIP_DHCP
ED7418 0:51f1ef89ec7b 143 /**
ED7418 0:51f1ef89ec7b 144 * Timer callback function that calls dhcp_coarse_tmr() and reschedules itself.
ED7418 0:51f1ef89ec7b 145 *
ED7418 0:51f1ef89ec7b 146 * @param arg unused argument
ED7418 0:51f1ef89ec7b 147 */
ED7418 0:51f1ef89ec7b 148 static void
ED7418 0:51f1ef89ec7b 149 dhcp_timer_coarse(void *arg)
ED7418 0:51f1ef89ec7b 150 {
ED7418 0:51f1ef89ec7b 151 LWIP_UNUSED_ARG(arg);
ED7418 0:51f1ef89ec7b 152 LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: dhcp_coarse_tmr()\n"));
ED7418 0:51f1ef89ec7b 153 dhcp_coarse_tmr();
ED7418 0:51f1ef89ec7b 154 sys_timeout(DHCP_COARSE_TIMER_MSECS, dhcp_timer_coarse, NULL);
ED7418 0:51f1ef89ec7b 155 }
ED7418 0:51f1ef89ec7b 156
ED7418 0:51f1ef89ec7b 157 /**
ED7418 0:51f1ef89ec7b 158 * Timer callback function that calls dhcp_fine_tmr() and reschedules itself.
ED7418 0:51f1ef89ec7b 159 *
ED7418 0:51f1ef89ec7b 160 * @param arg unused argument
ED7418 0:51f1ef89ec7b 161 */
ED7418 0:51f1ef89ec7b 162 static void
ED7418 0:51f1ef89ec7b 163 dhcp_timer_fine(void *arg)
ED7418 0:51f1ef89ec7b 164 {
ED7418 0:51f1ef89ec7b 165 LWIP_UNUSED_ARG(arg);
ED7418 0:51f1ef89ec7b 166 LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: dhcp_fine_tmr()\n"));
ED7418 0:51f1ef89ec7b 167 dhcp_fine_tmr();
ED7418 0:51f1ef89ec7b 168 sys_timeout(DHCP_FINE_TIMER_MSECS, dhcp_timer_fine, NULL);
ED7418 0:51f1ef89ec7b 169 }
ED7418 0:51f1ef89ec7b 170 #endif /* LWIP_DHCP */
ED7418 0:51f1ef89ec7b 171
ED7418 0:51f1ef89ec7b 172 #if LWIP_AUTOIP
ED7418 0:51f1ef89ec7b 173 /**
ED7418 0:51f1ef89ec7b 174 * Timer callback function that calls autoip_tmr() and reschedules itself.
ED7418 0:51f1ef89ec7b 175 *
ED7418 0:51f1ef89ec7b 176 * @param arg unused argument
ED7418 0:51f1ef89ec7b 177 */
ED7418 0:51f1ef89ec7b 178 static void
ED7418 0:51f1ef89ec7b 179 autoip_timer(void *arg)
ED7418 0:51f1ef89ec7b 180 {
ED7418 0:51f1ef89ec7b 181 LWIP_UNUSED_ARG(arg);
ED7418 0:51f1ef89ec7b 182 LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: autoip_tmr()\n"));
ED7418 0:51f1ef89ec7b 183 autoip_tmr();
ED7418 0:51f1ef89ec7b 184 sys_timeout(AUTOIP_TMR_INTERVAL, autoip_timer, NULL);
ED7418 0:51f1ef89ec7b 185 }
ED7418 0:51f1ef89ec7b 186 #endif /* LWIP_AUTOIP */
ED7418 0:51f1ef89ec7b 187
ED7418 0:51f1ef89ec7b 188 #if LWIP_IGMP
ED7418 0:51f1ef89ec7b 189 /**
ED7418 0:51f1ef89ec7b 190 * Timer callback function that calls igmp_tmr() and reschedules itself.
ED7418 0:51f1ef89ec7b 191 *
ED7418 0:51f1ef89ec7b 192 * @param arg unused argument
ED7418 0:51f1ef89ec7b 193 */
ED7418 0:51f1ef89ec7b 194 static void
ED7418 0:51f1ef89ec7b 195 igmp_timer(void *arg)
ED7418 0:51f1ef89ec7b 196 {
ED7418 0:51f1ef89ec7b 197 LWIP_UNUSED_ARG(arg);
ED7418 0:51f1ef89ec7b 198 LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: igmp_tmr()\n"));
ED7418 0:51f1ef89ec7b 199 igmp_tmr();
ED7418 0:51f1ef89ec7b 200 sys_timeout(IGMP_TMR_INTERVAL, igmp_timer, NULL);
ED7418 0:51f1ef89ec7b 201 }
ED7418 0:51f1ef89ec7b 202 #endif /* LWIP_IGMP */
ED7418 0:51f1ef89ec7b 203
ED7418 0:51f1ef89ec7b 204 #if LWIP_DNS
ED7418 0:51f1ef89ec7b 205 /**
ED7418 0:51f1ef89ec7b 206 * Timer callback function that calls dns_tmr() and reschedules itself.
ED7418 0:51f1ef89ec7b 207 *
ED7418 0:51f1ef89ec7b 208 * @param arg unused argument
ED7418 0:51f1ef89ec7b 209 */
ED7418 0:51f1ef89ec7b 210 static void
ED7418 0:51f1ef89ec7b 211 dns_timer(void *arg)
ED7418 0:51f1ef89ec7b 212 {
ED7418 0:51f1ef89ec7b 213 LWIP_UNUSED_ARG(arg);
ED7418 0:51f1ef89ec7b 214 LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: dns_tmr()\n"));
ED7418 0:51f1ef89ec7b 215 dns_tmr();
ED7418 0:51f1ef89ec7b 216 sys_timeout(DNS_TMR_INTERVAL, dns_timer, NULL);
ED7418 0:51f1ef89ec7b 217 }
ED7418 0:51f1ef89ec7b 218 #endif /* LWIP_DNS */
ED7418 0:51f1ef89ec7b 219
ED7418 0:51f1ef89ec7b 220 /** Initialize this module */
ED7418 0:51f1ef89ec7b 221 void sys_timeouts_init(void)
ED7418 0:51f1ef89ec7b 222 {
ED7418 0:51f1ef89ec7b 223 next_timeout = NULL;
ED7418 0:51f1ef89ec7b 224 #if IP_REASSEMBLY
ED7418 0:51f1ef89ec7b 225 sys_timeout(IP_TMR_INTERVAL, ip_reass_timer, NULL);
ED7418 0:51f1ef89ec7b 226 #endif /* IP_REASSEMBLY */
ED7418 0:51f1ef89ec7b 227 #if LWIP_ARP
ED7418 0:51f1ef89ec7b 228 sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);
ED7418 0:51f1ef89ec7b 229 #endif /* LWIP_ARP */
ED7418 0:51f1ef89ec7b 230 #if LWIP_DHCP
ED7418 0:51f1ef89ec7b 231 sys_timeout(DHCP_COARSE_TIMER_MSECS, dhcp_timer_coarse, NULL);
ED7418 0:51f1ef89ec7b 232 sys_timeout(DHCP_FINE_TIMER_MSECS, dhcp_timer_fine, NULL);
ED7418 0:51f1ef89ec7b 233 #endif /* LWIP_DHCP */
ED7418 0:51f1ef89ec7b 234 #if LWIP_AUTOIP
ED7418 0:51f1ef89ec7b 235 sys_timeout(AUTOIP_TMR_INTERVAL, autoip_timer, NULL);
ED7418 0:51f1ef89ec7b 236 #endif /* LWIP_AUTOIP */
ED7418 0:51f1ef89ec7b 237 #if LWIP_IGMP
ED7418 0:51f1ef89ec7b 238 sys_timeout(IGMP_TMR_INTERVAL, igmp_timer, NULL);
ED7418 0:51f1ef89ec7b 239 #endif /* LWIP_IGMP */
ED7418 0:51f1ef89ec7b 240 #if LWIP_DNS
ED7418 0:51f1ef89ec7b 241 sys_timeout(DNS_TMR_INTERVAL, dns_timer, NULL);
ED7418 0:51f1ef89ec7b 242 #endif /* LWIP_DNS */
ED7418 0:51f1ef89ec7b 243
ED7418 0:51f1ef89ec7b 244 #if NO_SYS
ED7418 0:51f1ef89ec7b 245 /* Initialise timestamp for sys_check_timeouts */
ED7418 0:51f1ef89ec7b 246 timeouts_last_time = sys_now();
ED7418 0:51f1ef89ec7b 247 #endif
ED7418 0:51f1ef89ec7b 248 }
ED7418 0:51f1ef89ec7b 249
ED7418 0:51f1ef89ec7b 250 /**
ED7418 0:51f1ef89ec7b 251 * Create a one-shot timer (aka timeout). Timeouts are processed in the
ED7418 0:51f1ef89ec7b 252 * following cases:
ED7418 0:51f1ef89ec7b 253 * - while waiting for a message using sys_timeouts_mbox_fetch()
ED7418 0:51f1ef89ec7b 254 * - by calling sys_check_timeouts() (NO_SYS==1 only)
ED7418 0:51f1ef89ec7b 255 *
ED7418 0:51f1ef89ec7b 256 * @param msecs time in milliseconds after that the timer should expire
ED7418 0:51f1ef89ec7b 257 * @param handler callback function to call when msecs have elapsed
ED7418 0:51f1ef89ec7b 258 * @param arg argument to pass to the callback function
ED7418 0:51f1ef89ec7b 259 */
ED7418 0:51f1ef89ec7b 260 #if LWIP_DEBUG_TIMERNAMES
ED7418 0:51f1ef89ec7b 261 void
ED7418 0:51f1ef89ec7b 262 sys_timeout_debug(u32_t msecs, sys_timeout_handler handler, void *arg, const char* handler_name)
ED7418 0:51f1ef89ec7b 263 #else /* LWIP_DEBUG_TIMERNAMES */
ED7418 0:51f1ef89ec7b 264 void
ED7418 0:51f1ef89ec7b 265 sys_timeout(u32_t msecs, sys_timeout_handler handler, void *arg)
ED7418 0:51f1ef89ec7b 266 #endif /* LWIP_DEBUG_TIMERNAMES */
ED7418 0:51f1ef89ec7b 267 {
ED7418 0:51f1ef89ec7b 268 struct sys_timeo *timeout, *t;
ED7418 0:51f1ef89ec7b 269
ED7418 0:51f1ef89ec7b 270 timeout = (struct sys_timeo *)memp_malloc(MEMP_SYS_TIMEOUT);
ED7418 0:51f1ef89ec7b 271 if (timeout == NULL) {
ED7418 0:51f1ef89ec7b 272 LWIP_ASSERT("sys_timeout: timeout != NULL, pool MEMP_SYS_TIMEOUT is empty", timeout != NULL);
ED7418 0:51f1ef89ec7b 273 return;
ED7418 0:51f1ef89ec7b 274 }
ED7418 0:51f1ef89ec7b 275 timeout->next = NULL;
ED7418 0:51f1ef89ec7b 276 timeout->h = handler;
ED7418 0:51f1ef89ec7b 277 timeout->arg = arg;
ED7418 0:51f1ef89ec7b 278 timeout->time = msecs;
ED7418 0:51f1ef89ec7b 279 #if LWIP_DEBUG_TIMERNAMES
ED7418 0:51f1ef89ec7b 280 timeout->handler_name = handler_name;
ED7418 0:51f1ef89ec7b 281 LWIP_DEBUGF(TIMERS_DEBUG, ("sys_timeout: %p msecs=%"U32_F" handler=%s arg=%p\n",
ED7418 0:51f1ef89ec7b 282 (void *)timeout, msecs, handler_name, (void *)arg));
ED7418 0:51f1ef89ec7b 283 #endif /* LWIP_DEBUG_TIMERNAMES */
ED7418 0:51f1ef89ec7b 284
ED7418 0:51f1ef89ec7b 285 if (next_timeout == NULL) {
ED7418 0:51f1ef89ec7b 286 next_timeout = timeout;
ED7418 0:51f1ef89ec7b 287 return;
ED7418 0:51f1ef89ec7b 288 }
ED7418 0:51f1ef89ec7b 289
ED7418 0:51f1ef89ec7b 290 if (next_timeout->time > msecs) {
ED7418 0:51f1ef89ec7b 291 next_timeout->time -= msecs;
ED7418 0:51f1ef89ec7b 292 timeout->next = next_timeout;
ED7418 0:51f1ef89ec7b 293 next_timeout = timeout;
ED7418 0:51f1ef89ec7b 294 } else {
ED7418 0:51f1ef89ec7b 295 for(t = next_timeout; t != NULL; t = t->next) {
ED7418 0:51f1ef89ec7b 296 timeout->time -= t->time;
ED7418 0:51f1ef89ec7b 297 if (t->next == NULL || t->next->time > timeout->time) {
ED7418 0:51f1ef89ec7b 298 if (t->next != NULL) {
ED7418 0:51f1ef89ec7b 299 t->next->time -= timeout->time;
ED7418 0:51f1ef89ec7b 300 }
ED7418 0:51f1ef89ec7b 301 timeout->next = t->next;
ED7418 0:51f1ef89ec7b 302 t->next = timeout;
ED7418 0:51f1ef89ec7b 303 break;
ED7418 0:51f1ef89ec7b 304 }
ED7418 0:51f1ef89ec7b 305 }
ED7418 0:51f1ef89ec7b 306 }
ED7418 0:51f1ef89ec7b 307 }
ED7418 0:51f1ef89ec7b 308
ED7418 0:51f1ef89ec7b 309 /**
ED7418 0:51f1ef89ec7b 310 * Go through timeout list (for this task only) and remove the first matching
ED7418 0:51f1ef89ec7b 311 * entry, even though the timeout has not triggered yet.
ED7418 0:51f1ef89ec7b 312 *
ED7418 0:51f1ef89ec7b 313 * @note This function only works as expected if there is only one timeout
ED7418 0:51f1ef89ec7b 314 * calling 'handler' in the list of timeouts.
ED7418 0:51f1ef89ec7b 315 *
ED7418 0:51f1ef89ec7b 316 * @param handler callback function that would be called by the timeout
ED7418 0:51f1ef89ec7b 317 * @param arg callback argument that would be passed to handler
ED7418 0:51f1ef89ec7b 318 */
ED7418 0:51f1ef89ec7b 319 void
ED7418 0:51f1ef89ec7b 320 sys_untimeout(sys_timeout_handler handler, void *arg)
ED7418 0:51f1ef89ec7b 321 {
ED7418 0:51f1ef89ec7b 322 struct sys_timeo *prev_t, *t;
ED7418 0:51f1ef89ec7b 323
ED7418 0:51f1ef89ec7b 324 if (next_timeout == NULL) {
ED7418 0:51f1ef89ec7b 325 return;
ED7418 0:51f1ef89ec7b 326 }
ED7418 0:51f1ef89ec7b 327
ED7418 0:51f1ef89ec7b 328 for (t = next_timeout, prev_t = NULL; t != NULL; prev_t = t, t = t->next) {
ED7418 0:51f1ef89ec7b 329 if ((t->h == handler) && (t->arg == arg)) {
ED7418 0:51f1ef89ec7b 330 /* We have a match */
ED7418 0:51f1ef89ec7b 331 /* Unlink from previous in list */
ED7418 0:51f1ef89ec7b 332 if (prev_t == NULL) {
ED7418 0:51f1ef89ec7b 333 next_timeout = t->next;
ED7418 0:51f1ef89ec7b 334 } else {
ED7418 0:51f1ef89ec7b 335 prev_t->next = t->next;
ED7418 0:51f1ef89ec7b 336 }
ED7418 0:51f1ef89ec7b 337 /* If not the last one, add time of this one back to next */
ED7418 0:51f1ef89ec7b 338 if (t->next != NULL) {
ED7418 0:51f1ef89ec7b 339 t->next->time += t->time;
ED7418 0:51f1ef89ec7b 340 }
ED7418 0:51f1ef89ec7b 341 memp_free(MEMP_SYS_TIMEOUT, t);
ED7418 0:51f1ef89ec7b 342 return;
ED7418 0:51f1ef89ec7b 343 }
ED7418 0:51f1ef89ec7b 344 }
ED7418 0:51f1ef89ec7b 345 return;
ED7418 0:51f1ef89ec7b 346 }
ED7418 0:51f1ef89ec7b 347
ED7418 0:51f1ef89ec7b 348 #if NO_SYS
ED7418 0:51f1ef89ec7b 349
ED7418 0:51f1ef89ec7b 350 /** Handle timeouts for NO_SYS==1 (i.e. without using
ED7418 0:51f1ef89ec7b 351 * tcpip_thread/sys_timeouts_mbox_fetch(). Uses sys_now() to call timeout
ED7418 0:51f1ef89ec7b 352 * handler functions when timeouts expire.
ED7418 0:51f1ef89ec7b 353 *
ED7418 0:51f1ef89ec7b 354 * Must be called periodically from your main loop.
ED7418 0:51f1ef89ec7b 355 */
ED7418 0:51f1ef89ec7b 356 void
ED7418 0:51f1ef89ec7b 357 sys_check_timeouts(void)
ED7418 0:51f1ef89ec7b 358 {
ED7418 0:51f1ef89ec7b 359 struct sys_timeo *tmptimeout;
ED7418 0:51f1ef89ec7b 360 u32_t diff;
ED7418 0:51f1ef89ec7b 361 sys_timeout_handler handler;
ED7418 0:51f1ef89ec7b 362 void *arg;
ED7418 0:51f1ef89ec7b 363 int had_one;
ED7418 0:51f1ef89ec7b 364 u32_t now;
ED7418 0:51f1ef89ec7b 365
ED7418 0:51f1ef89ec7b 366 now = sys_now();
ED7418 0:51f1ef89ec7b 367 if (next_timeout) {
ED7418 0:51f1ef89ec7b 368 /* this cares for wraparounds */
ED7418 0:51f1ef89ec7b 369 diff = LWIP_U32_DIFF(now, timeouts_last_time);
ED7418 0:51f1ef89ec7b 370 do
ED7418 0:51f1ef89ec7b 371 {
ED7418 0:51f1ef89ec7b 372 had_one = 0;
ED7418 0:51f1ef89ec7b 373 tmptimeout = next_timeout;
ED7418 0:51f1ef89ec7b 374 if (tmptimeout->time <= diff) {
ED7418 0:51f1ef89ec7b 375 /* timeout has expired */
ED7418 0:51f1ef89ec7b 376 had_one = 1;
ED7418 0:51f1ef89ec7b 377 timeouts_last_time = now;
ED7418 0:51f1ef89ec7b 378 diff -= tmptimeout->time;
ED7418 0:51f1ef89ec7b 379 next_timeout = tmptimeout->next;
ED7418 0:51f1ef89ec7b 380 handler = tmptimeout->h;
ED7418 0:51f1ef89ec7b 381 arg = tmptimeout->arg;
ED7418 0:51f1ef89ec7b 382 #if LWIP_DEBUG_TIMERNAMES
ED7418 0:51f1ef89ec7b 383 if (handler != NULL) {
ED7418 0:51f1ef89ec7b 384 LWIP_DEBUGF(TIMERS_DEBUG, ("sct calling h=%s arg=%p\n",
ED7418 0:51f1ef89ec7b 385 tmptimeout->handler_name, arg));
ED7418 0:51f1ef89ec7b 386 }
ED7418 0:51f1ef89ec7b 387 #endif /* LWIP_DEBUG_TIMERNAMES */
ED7418 0:51f1ef89ec7b 388 memp_free(MEMP_SYS_TIMEOUT, tmptimeout);
ED7418 0:51f1ef89ec7b 389 if (handler != NULL) {
ED7418 0:51f1ef89ec7b 390 handler(arg);
ED7418 0:51f1ef89ec7b 391 }
ED7418 0:51f1ef89ec7b 392 }
ED7418 0:51f1ef89ec7b 393 /* repeat until all expired timers have been called */
ED7418 0:51f1ef89ec7b 394 }while(had_one);
ED7418 0:51f1ef89ec7b 395 }
ED7418 0:51f1ef89ec7b 396 }
ED7418 0:51f1ef89ec7b 397
ED7418 0:51f1ef89ec7b 398 /** Set back the timestamp of the last call to sys_check_timeouts()
ED7418 0:51f1ef89ec7b 399 * This is necessary if sys_check_timeouts() hasn't been called for a long
ED7418 0:51f1ef89ec7b 400 * time (e.g. while saving energy) to prevent all timer functions of that
ED7418 0:51f1ef89ec7b 401 * period being called.
ED7418 0:51f1ef89ec7b 402 */
ED7418 0:51f1ef89ec7b 403 void
ED7418 0:51f1ef89ec7b 404 sys_restart_timeouts(void)
ED7418 0:51f1ef89ec7b 405 {
ED7418 0:51f1ef89ec7b 406 timeouts_last_time = sys_now();
ED7418 0:51f1ef89ec7b 407 }
ED7418 0:51f1ef89ec7b 408
ED7418 0:51f1ef89ec7b 409 #else /* NO_SYS */
ED7418 0:51f1ef89ec7b 410
ED7418 0:51f1ef89ec7b 411 /**
ED7418 0:51f1ef89ec7b 412 * Wait (forever) for a message to arrive in an mbox.
ED7418 0:51f1ef89ec7b 413 * While waiting, timeouts are processed.
ED7418 0:51f1ef89ec7b 414 *
ED7418 0:51f1ef89ec7b 415 * @param mbox the mbox to fetch the message from
ED7418 0:51f1ef89ec7b 416 * @param msg the place to store the message
ED7418 0:51f1ef89ec7b 417 */
ED7418 0:51f1ef89ec7b 418 void
ED7418 0:51f1ef89ec7b 419 sys_timeouts_mbox_fetch(sys_mbox_t *mbox, void **msg)
ED7418 0:51f1ef89ec7b 420 {
ED7418 0:51f1ef89ec7b 421 u32_t time_needed;
ED7418 0:51f1ef89ec7b 422 struct sys_timeo *tmptimeout;
ED7418 0:51f1ef89ec7b 423 sys_timeout_handler handler;
ED7418 0:51f1ef89ec7b 424 void *arg;
ED7418 0:51f1ef89ec7b 425
ED7418 0:51f1ef89ec7b 426 again:
ED7418 0:51f1ef89ec7b 427 if (!next_timeout) {
ED7418 0:51f1ef89ec7b 428 time_needed = sys_arch_mbox_fetch(mbox, msg, 0);
ED7418 0:51f1ef89ec7b 429 } else {
ED7418 0:51f1ef89ec7b 430 if (next_timeout->time > 0) {
ED7418 0:51f1ef89ec7b 431 time_needed = sys_arch_mbox_fetch(mbox, msg, next_timeout->time);
ED7418 0:51f1ef89ec7b 432 } else {
ED7418 0:51f1ef89ec7b 433 time_needed = SYS_ARCH_TIMEOUT;
ED7418 0:51f1ef89ec7b 434 }
ED7418 0:51f1ef89ec7b 435
ED7418 0:51f1ef89ec7b 436 if (time_needed == SYS_ARCH_TIMEOUT) {
ED7418 0:51f1ef89ec7b 437 /* If time == SYS_ARCH_TIMEOUT, a timeout occured before a message
ED7418 0:51f1ef89ec7b 438 could be fetched. We should now call the timeout handler and
ED7418 0:51f1ef89ec7b 439 deallocate the memory allocated for the timeout. */
ED7418 0:51f1ef89ec7b 440 tmptimeout = next_timeout;
ED7418 0:51f1ef89ec7b 441 next_timeout = tmptimeout->next;
ED7418 0:51f1ef89ec7b 442 handler = tmptimeout->h;
ED7418 0:51f1ef89ec7b 443 arg = tmptimeout->arg;
ED7418 0:51f1ef89ec7b 444 #if LWIP_DEBUG_TIMERNAMES
ED7418 0:51f1ef89ec7b 445 if (handler != NULL) {
ED7418 0:51f1ef89ec7b 446 LWIP_DEBUGF(TIMERS_DEBUG, ("stmf calling h=%s arg=%p\n",
ED7418 0:51f1ef89ec7b 447 tmptimeout->handler_name, arg));
ED7418 0:51f1ef89ec7b 448 }
ED7418 0:51f1ef89ec7b 449 #endif /* LWIP_DEBUG_TIMERNAMES */
ED7418 0:51f1ef89ec7b 450 memp_free(MEMP_SYS_TIMEOUT, tmptimeout);
ED7418 0:51f1ef89ec7b 451 if (handler != NULL) {
ED7418 0:51f1ef89ec7b 452 /* For LWIP_TCPIP_CORE_LOCKING, lock the core before calling the
ED7418 0:51f1ef89ec7b 453 timeout handler function. */
ED7418 0:51f1ef89ec7b 454 LOCK_TCPIP_CORE();
ED7418 0:51f1ef89ec7b 455 handler(arg);
ED7418 0:51f1ef89ec7b 456 UNLOCK_TCPIP_CORE();
ED7418 0:51f1ef89ec7b 457 }
ED7418 0:51f1ef89ec7b 458 LWIP_TCPIP_THREAD_ALIVE();
ED7418 0:51f1ef89ec7b 459
ED7418 0:51f1ef89ec7b 460 /* We try again to fetch a message from the mbox. */
ED7418 0:51f1ef89ec7b 461 goto again;
ED7418 0:51f1ef89ec7b 462 } else {
ED7418 0:51f1ef89ec7b 463 /* If time != SYS_ARCH_TIMEOUT, a message was received before the timeout
ED7418 0:51f1ef89ec7b 464 occured. The time variable is set to the number of
ED7418 0:51f1ef89ec7b 465 milliseconds we waited for the message. */
ED7418 0:51f1ef89ec7b 466 if (time_needed < next_timeout->time) {
ED7418 0:51f1ef89ec7b 467 next_timeout->time -= time_needed;
ED7418 0:51f1ef89ec7b 468 } else {
ED7418 0:51f1ef89ec7b 469 next_timeout->time = 0;
ED7418 0:51f1ef89ec7b 470 }
ED7418 0:51f1ef89ec7b 471 }
ED7418 0:51f1ef89ec7b 472 }
ED7418 0:51f1ef89ec7b 473 }
ED7418 0:51f1ef89ec7b 474
ED7418 0:51f1ef89ec7b 475 #endif /* NO_SYS */
ED7418 0:51f1ef89ec7b 476
ED7418 0:51f1ef89ec7b 477 #else /* LWIP_TIMERS */
ED7418 0:51f1ef89ec7b 478 /* Satisfy the TCP code which calls this function */
ED7418 0:51f1ef89ec7b 479 void
ED7418 0:51f1ef89ec7b 480 tcp_timer_needed(void)
ED7418 0:51f1ef89ec7b 481 {
ED7418 0:51f1ef89ec7b 482 }
ED7418 0:51f1ef89ec7b 483 #endif /* LWIP_TIMERS */